719 lines
26 KiB
Plaintext
719 lines
26 KiB
Plaintext
|
(*
|
||
|
* Copyright 2014, NICTA
|
||
|
*
|
||
|
* This software may be distributed and modified according to the terms of
|
||
|
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||
|
* See "LICENSE_GPLv2.txt" for details.
|
||
|
*
|
||
|
* @TAG(NICTA_GPL)
|
||
|
*)
|
||
|
|
||
|
theory Syscall_S
|
||
|
imports Separation
|
||
|
begin
|
||
|
|
||
|
lemma syscall_bisim:
|
||
|
assumes bs:
|
||
|
"bisim (fr \<oplus> r_flt_rel) P P' m_flt m_flt'"
|
||
|
"\<And>flt flt'. fr flt flt' \<Longrightarrow>
|
||
|
bisim r (P_flt flt) (P'_flt flt') (h_flt flt) (h_flt' flt')"
|
||
|
"\<And>rv rv'. r_flt_rel rv rv' \<Longrightarrow>
|
||
|
bisim (ser \<oplus> r_err_rel rv rv')
|
||
|
(P_no_flt rv) (P'_no_flt rv')
|
||
|
(m_err rv) (m_err' rv')"
|
||
|
"\<And>rv rv' err err'. \<lbrakk>r_flt_rel rv rv'; ser err err'\<rbrakk>
|
||
|
\<Longrightarrow> bisim r (P_err rv err)
|
||
|
(P'_err rv' err') (h_err err) (h_err' err')"
|
||
|
"\<And>rvf rvf' rve rve'. \<lbrakk>r_flt_rel rvf rvf'; r_err_rel rvf rvf' rve rve'\<rbrakk>
|
||
|
\<Longrightarrow> bisim (f \<oplus> r)
|
||
|
(P_no_err rvf rve) (P'_no_err rvf' rve')
|
||
|
(m_fin rve) (m_fin' rve')"
|
||
|
assumes wp: "\<And>rv. \<lbrace>Q_no_flt rv\<rbrace> m_err rv \<lbrace>P_no_err rv\<rbrace>, \<lbrace>P_err rv\<rbrace>"
|
||
|
"\<And>rv'. \<lbrace>Q'_no_flt rv'\<rbrace> m_err' rv' \<lbrace>P'_no_err rv'\<rbrace>,\<lbrace>P'_err rv'\<rbrace>"
|
||
|
"\<lbrace>Q\<rbrace> m_flt \<lbrace>\<lambda>rv. P_no_flt rv and Q_no_flt rv\<rbrace>, \<lbrace>P_flt\<rbrace>"
|
||
|
"\<lbrace>Q'\<rbrace> m_flt' \<lbrace>\<lambda>rv. P'_no_flt rv and Q'_no_flt rv\<rbrace>, \<lbrace>P'_flt\<rbrace>"
|
||
|
|
||
|
shows "bisim (f \<oplus> r) (P and Q) (P' and Q')
|
||
|
(syscall m_flt h_flt m_err h_err m_fin)
|
||
|
(syscall m_flt' h_flt' m_err' h_err' m_fin')"
|
||
|
apply (simp add: syscall_def liftE_bindE)
|
||
|
apply (rule bisim_split_bind_sum_case)
|
||
|
apply (rule bs)
|
||
|
apply simp
|
||
|
apply (rule bs)
|
||
|
apply simp
|
||
|
apply (simp add: liftE_bindE)
|
||
|
apply (rule bisim_split_bind_sum_case)
|
||
|
apply (erule bs)
|
||
|
apply simp
|
||
|
apply (erule bs)
|
||
|
apply simp
|
||
|
apply (erule(1) bs)
|
||
|
apply (rule wp)+
|
||
|
done
|
||
|
|
||
|
lemma dc_refl: "dc r r" by simp
|
||
|
|
||
|
|
||
|
lemma bisim_catch_faults_r:
|
||
|
assumes bs: "\<And>x. bisim_underlying sr r P (P' x) a (m x)"
|
||
|
and flt: "\<lbrace>S\<rbrace> b \<lbrace>\<lambda>_ _. False\<rbrace>, \<lbrace>P'\<rbrace>"
|
||
|
and pure: "\<And>s. \<lbrace>S' and op = s\<rbrace> b \<lbrace>\<lambda>_. op = s\<rbrace>"
|
||
|
and db: "not_empty Pd b"
|
||
|
shows "bisim_underlying sr r P (S and S' and Pd) a (b <catch> m)"
|
||
|
unfolding catch_def
|
||
|
apply (rule bisim_symb_exec_r [OF _ flt [unfolded validE_def] pure db] )
|
||
|
apply (case_tac x)
|
||
|
apply simp
|
||
|
apply (rule bs)
|
||
|
apply simp
|
||
|
apply (rule bisim_underlyingI, simp_all)[1]
|
||
|
done
|
||
|
|
||
|
lemma bisim_validE_R:
|
||
|
assumes ac: "bisim_underlying (op =) (dc \<oplus> op =) P P' a a'"
|
||
|
and rl: "\<lbrace>Q\<rbrace> a \<lbrace>S\<rbrace>, -"
|
||
|
shows "\<lbrace>P and P' and Q\<rbrace> a' \<lbrace>S\<rbrace>, -"
|
||
|
using ac rl
|
||
|
unfolding bisim_underlying_def valid_def validE_def validE_R_def
|
||
|
by (fastforce simp: split_def split: sum.splits)
|
||
|
|
||
|
lemma bisim_validE_R2:
|
||
|
assumes ac: "bisim_underlying (op =) (op =) P P' a a'"
|
||
|
and rl: "\<lbrace>Q\<rbrace> a' \<lbrace>S\<rbrace>, -"
|
||
|
shows "\<lbrace>P and P' and Q\<rbrace> a \<lbrace>S\<rbrace>, -"
|
||
|
using ac rl
|
||
|
unfolding bisim_underlying_def valid_def validE_def validE_R_def
|
||
|
by (fastforce simp: split_def split: sum.splits)
|
||
|
|
||
|
|
||
|
lemma bisim_rab:
|
||
|
"bisim (dc \<oplus> op =) \<top> (\<lambda>s. separate_cnode_cap (caps_of_state s) cap \<and> valid_cap cap s)
|
||
|
(doE
|
||
|
_ \<leftarrow> whenE (length cref < word_bits) (throwError undefined);
|
||
|
case cap of
|
||
|
CNodeCap p bits guard \<Rightarrow> if guard \<le> cref then
|
||
|
returnOk ((p, take bits (drop (length guard) cref)), drop (bits + length guard) cref)
|
||
|
else
|
||
|
(throwError undefined)
|
||
|
| _ \<Rightarrow> throwError undefined
|
||
|
odE)
|
||
|
(resolve_address_bits (cap, cref))"
|
||
|
unfolding resolve_address_bits_def
|
||
|
apply (cases "length cref < word_bits")
|
||
|
apply (auto intro!: bisim_underlyingI
|
||
|
elim!: separate_cnode_capE
|
||
|
simp: whenE_def in_monad Bex_def in_bindE word_bits_def in_get_cap_cte_wp_at cte_wp_at_caps_of_state
|
||
|
simp del: add_is_0 split: split_if_asm)[1]
|
||
|
apply simp
|
||
|
apply (rule bisim_underlyingI)
|
||
|
apply (clarsimp )
|
||
|
apply (erule separate_cnode_capE)
|
||
|
apply (fastforce simp: word_bits_def in_monad )
|
||
|
apply (case_tac "\<not> guard \<le> cref")
|
||
|
apply (clarsimp simp: in_monad Bex_def)
|
||
|
apply (drule (2) valid_sep_cap_not_cnode [where cref = cref])
|
||
|
apply simp
|
||
|
apply (fastforce simp: in_monad Bex_def in_bindE word_bits_def in_get_cap_cte_wp_at cte_wp_at_caps_of_state whenE_def
|
||
|
simp del: add_is_0 split: split_if_asm)
|
||
|
apply clarsimp
|
||
|
apply (erule separate_cnode_capE)
|
||
|
apply (fastforce simp: word_bits_def in_monad)
|
||
|
apply (drule (2) valid_sep_cap_not_cnode [where cref = cref])
|
||
|
apply simp
|
||
|
apply (fastforce simp: in_monad Bex_def in_bindE word_bits_def in_get_cap_cte_wp_at cte_wp_at_caps_of_state whenE_def
|
||
|
simp del: add_is_0 split: split_if_asm)
|
||
|
done
|
||
|
|
||
|
|
||
|
lemma lsft_sep:
|
||
|
"\<lbrace>separate_state and valid_objs\<rbrace> lookup_slot_for_thread tcb cptr \<lbrace>\<lambda>rv s. \<forall>cap. caps_of_state s (fst rv) = Some cap \<longrightarrow> separate_cap cap\<rbrace>, -"
|
||
|
unfolding lookup_slot_for_thread_def
|
||
|
apply wp
|
||
|
apply (rule bisim_validE_R)
|
||
|
apply (rule bisim_rab)
|
||
|
apply (wpc | wp whenE_throwError_wp)+
|
||
|
apply (fastforce elim: separate_cnode_capE dest: separate_state_get_tcbD objs_valid_tcb_ctable)
|
||
|
done
|
||
|
|
||
|
lemma get_cap_wp':
|
||
|
"\<lbrace>\<lambda>s. \<forall>cap. caps_of_state s p = Some cap \<longrightarrow> Q cap s\<rbrace> get_cap p \<lbrace>Q\<rbrace>"
|
||
|
apply (wp get_cap_wp)
|
||
|
apply (simp add: cte_wp_at_caps_of_state)
|
||
|
done
|
||
|
|
||
|
lemma lc_sep [wp]:
|
||
|
"\<lbrace>separate_state and valid_objs \<rbrace> lookup_cap tcb cptr \<lbrace>\<lambda>cap _. separate_cap cap\<rbrace>, -"
|
||
|
unfolding lookup_cap_def
|
||
|
apply (simp add: split_def)
|
||
|
apply (rule hoare_pre)
|
||
|
apply (wp get_cap_wp' lsft_sep)
|
||
|
apply simp
|
||
|
done
|
||
|
|
||
|
|
||
|
lemma not_empty_thread_get [wp]:
|
||
|
"not_empty (tcb_at p) (thread_get f p)"
|
||
|
unfolding thread_get_def
|
||
|
apply (rule not_empty_guard_imp)
|
||
|
apply (simp add: gets_the_def bind_assoc)
|
||
|
apply (wp )
|
||
|
apply (simp add: tcb_at_def)
|
||
|
done
|
||
|
|
||
|
lemma not_empty_throwError [wp]:
|
||
|
"not_empty \<top> (throwError e)"
|
||
|
unfolding not_empty_def throwError_def by (fastforce simp: return_def)
|
||
|
|
||
|
lemma not_empty_cap_fault_on_failure [wp]:
|
||
|
assumes d: "not_empty P m"
|
||
|
shows "not_empty P (cap_fault_on_failure a b m)"
|
||
|
unfolding cap_fault_on_failure_def
|
||
|
apply (simp add: handleE_def handleE'_def)
|
||
|
apply (rule not_empty_guard_imp)
|
||
|
apply (wp d | wpc | simp)+
|
||
|
done
|
||
|
|
||
|
lemma not_empty_splitE [wp_split]:
|
||
|
assumes da: "not_empty Pa a"
|
||
|
and db: "\<And>x. not_empty (Pb x) (b x)"
|
||
|
and v: "\<lbrace>Pb'\<rbrace> a \<lbrace>Pb\<rbrace>, -"
|
||
|
shows "not_empty (Pa and Pb') (a >>=E b)"
|
||
|
using v
|
||
|
apply (clarsimp simp: bindE_def validE_R_def validE_def)
|
||
|
apply (rule not_empty_split [OF da])
|
||
|
apply (rule not_empty_lift [OF db])
|
||
|
apply (erule hoare_post_imp [rotated])
|
||
|
apply (clarsimp split: sum.splits)
|
||
|
done
|
||
|
|
||
|
lemma not_empty_whenE_throwError [wp]:
|
||
|
"not_empty \<top> (whenE P (throwError e))"
|
||
|
by (simp add: whenE_def throwError_def return_def not_empty_def returnOk_def)
|
||
|
|
||
|
lemma not_empty_returnOk [wp]:
|
||
|
"not_empty \<top> (returnOk v)"
|
||
|
by (simp add: return_def not_empty_def returnOk_def)
|
||
|
|
||
|
lemma not_empty_if [wp_split]:
|
||
|
"\<lbrakk> not_empty Pt m; not_empty Pf m' \<rbrakk> \<Longrightarrow> not_empty (\<lambda>s. (b \<longrightarrow> Pt s) \<and> ( \<not> b \<longrightarrow> Pf s)) (if b then m else m')"
|
||
|
by (clarsimp split: split_if)
|
||
|
|
||
|
lemma not_empty_lsft:
|
||
|
shows "not_empty (tcb_at t and valid_objs and separate_state) (lookup_slot_for_thread t cptr)"
|
||
|
unfolding lookup_slot_for_thread_def
|
||
|
apply (simp add: gets_the_def bind_assoc)
|
||
|
apply (rule not_empty_guard_imp)
|
||
|
apply (wp bisim_not_empty [OF bisim_rab] | wpc)+
|
||
|
apply (fastforce simp: tcb_at_def elim: separate_cnode_capE dest: separate_state_get_tcbD objs_valid_tcb_ctable)
|
||
|
done
|
||
|
|
||
|
lemma not_empty_get_cap [wp]:
|
||
|
"not_empty (cte_at p) (get_cap p)"
|
||
|
unfolding not_empty_def
|
||
|
by (clarsimp simp: cte_at_def)
|
||
|
|
||
|
lemma not_empty_lc:
|
||
|
shows "not_empty (tcb_at t and valid_objs and separate_state) (lookup_cap t cptr)"
|
||
|
unfolding lookup_cap_def
|
||
|
apply (simp add: split_def)
|
||
|
apply (rule not_empty_guard_imp)
|
||
|
apply (wp not_empty_lsft)
|
||
|
apply simp
|
||
|
done
|
||
|
|
||
|
lemma not_empty_get [wp]:
|
||
|
"not_empty \<top> get"
|
||
|
unfolding not_empty_def get_def by simp
|
||
|
|
||
|
lemma not_empty_put [wp]:
|
||
|
"not_empty \<top> (put s)"
|
||
|
unfolding not_empty_def put_def by simp
|
||
|
|
||
|
lemma not_empty_set_object [wp]:
|
||
|
"not_empty \<top> (set_object p v)"
|
||
|
unfolding set_object_def
|
||
|
apply simp
|
||
|
apply (rule not_empty_guard_imp)
|
||
|
apply wp
|
||
|
apply simp
|
||
|
done
|
||
|
|
||
|
lemma not_empty_assert_opt [wp]:
|
||
|
"not_empty (\<lambda>_. v \<noteq> None) (assert_opt v)"
|
||
|
unfolding not_empty_def assert_opt_def
|
||
|
by (clarsimp simp: return_def)
|
||
|
|
||
|
lemma not_empty_thread_set [wp]:
|
||
|
"not_empty (tcb_at p) (thread_set f p)"
|
||
|
unfolding thread_set_def
|
||
|
apply (simp add: gets_the_def bind_assoc)
|
||
|
apply (rule not_empty_guard_imp)
|
||
|
apply wp
|
||
|
apply (simp add: tcb_at_def)
|
||
|
done
|
||
|
|
||
|
lemma not_empty_False:
|
||
|
"not_empty (\<lambda>_. False) m"
|
||
|
unfolding not_empty_def by simp
|
||
|
|
||
|
lemma not_empty_gen_asm:
|
||
|
assumes ne: "P \<Longrightarrow> not_empty R m"
|
||
|
shows "not_empty (R and (\<lambda>_. P)) m"
|
||
|
using ne unfolding not_empty_def by auto
|
||
|
|
||
|
lemmas bisim_refl' = bisim_refl [where P = \<top> and P' = \<top> and R = "op =", OF refl]
|
||
|
|
||
|
lemma send_fault_ipc_bisim:
|
||
|
"bisim op = \<top> (tcb_at tcb and valid_objs and separate_state)
|
||
|
(set_thread_state tcb Inactive) (send_fault_ipc tcb flt' <catch> handle_double_fault tcb flt')"
|
||
|
unfolding send_fault_ipc_def
|
||
|
apply (rule bisim_guard_imp)
|
||
|
apply (rule bisim_catch_faults_r [where S = "separate_state and valid_objs"])
|
||
|
apply (clarsimp simp: handle_double_fault_def)
|
||
|
apply (rule bisim_refl')
|
||
|
apply (simp add: Let_def)
|
||
|
apply (rule hoare_vcg_seqE)
|
||
|
apply (rule hoare_vcg_seqE)
|
||
|
apply wpc
|
||
|
apply wp
|
||
|
apply simp
|
||
|
apply (rule hoare_post_imp_R [OF lc_sep])
|
||
|
apply (clarsimp simp: separate_cap_def)
|
||
|
apply (wp | simp add: Let_def)+
|
||
|
apply (rule_tac P = "separate_cap handler_cap" in hoare_gen_asmE')
|
||
|
apply (erule separate_capE, simp_all)[1]
|
||
|
apply (wp | simp)+
|
||
|
apply clarsimp
|
||
|
apply assumption
|
||
|
-- "det_ont"
|
||
|
apply (simp add: Let_def cong: cap.case_cong)
|
||
|
apply (wp not_empty_lc)
|
||
|
apply (rule_tac P = "separate_cap xa" in not_empty_gen_asm)
|
||
|
apply (erule separate_capE, simp_all)[1]
|
||
|
apply wp
|
||
|
apply simp
|
||
|
done
|
||
|
|
||
|
lemma handle_fault_bisim:
|
||
|
"bisim op = \<top> (separate_state and tcb_at tcb and valid_objs) (handle_fault tcb flt) (Ipc_A.handle_fault tcb flt')"
|
||
|
unfolding handle_fault_def Ipc_A.handle_fault_def
|
||
|
apply (rule bisim_guard_imp)
|
||
|
apply (rule bisim_symb_exec_r [where Pe = \<top>])
|
||
|
apply simp
|
||
|
apply (rule send_fault_ipc_bisim)
|
||
|
apply wp
|
||
|
apply simp
|
||
|
apply (simp add: gets_the_def)
|
||
|
apply wp
|
||
|
apply (simp add: tcb_at_def)
|
||
|
done
|
||
|
|
||
|
lemmas bisim_throwError_dc = bisim_throwError [where f = dc, OF dc_refl]
|
||
|
|
||
|
lemma bisim_returnOk:
|
||
|
"R a b \<Longrightarrow> bisim (f \<oplus> R) \<top> \<top> (returnOk a) (returnOk b)"
|
||
|
apply (simp add: returnOk_def)
|
||
|
apply (rule bisim_return)
|
||
|
apply simp
|
||
|
done
|
||
|
|
||
|
lemma bisim_liftME_same:
|
||
|
assumes bs: "bisim (f \<oplus> op =) P P' m m'"
|
||
|
shows "bisim (f \<oplus> op =) P P' (liftME g m) (liftME g m')"
|
||
|
unfolding liftME_def
|
||
|
apply (rule bisim_guard_imp)
|
||
|
apply (rule bisim_splitE [OF bs])
|
||
|
apply simp
|
||
|
apply (rule bisim_returnOk)
|
||
|
apply simp
|
||
|
apply wp
|
||
|
apply simp+
|
||
|
done
|
||
|
|
||
|
lemma bisim_split_if:
|
||
|
"\<lbrakk> P \<Longrightarrow> bisim R Pt Pt' a a'; \<not> P \<Longrightarrow> bisim R Pf Pf' b b' \<rbrakk> \<Longrightarrow>
|
||
|
bisim R (\<lambda>s. (P \<longrightarrow> Pt s) \<and> (\<not> P \<longrightarrow> Pf s)) (\<lambda>s. (P \<longrightarrow> Pt' s) \<and> (\<not> P \<longrightarrow> Pf' s))
|
||
|
(if P then a else b) (if P then a' else b')"
|
||
|
by simp
|
||
|
|
||
|
lemma bisim_reflE:
|
||
|
"bisim (op = \<oplus> op =) \<top> \<top> a a"
|
||
|
apply (rule bisim_underlyingI)
|
||
|
apply (case_tac r, fastforce+)[1]
|
||
|
apply (case_tac r', fastforce+)[1]
|
||
|
done
|
||
|
|
||
|
lemma bisim_reflE_dc:
|
||
|
"bisim (dc \<oplus> op =) \<top> \<top> a a"
|
||
|
apply (rule bisim_underlyingI)
|
||
|
apply (case_tac r, fastforce+)[1]
|
||
|
apply (case_tac r', fastforce+)[1]
|
||
|
done
|
||
|
|
||
|
lemma decode_invocation_bisim:
|
||
|
"bisim (op = \<oplus> op =) \<top> (K (separate_cap cap))
|
||
|
(decode_invocation a b c d cap f) (Decode_A.decode_invocation a b c d cap f)"
|
||
|
unfolding decode_invocation_def Decode_A.decode_invocation_def
|
||
|
apply (rule bisim_guard_imp)
|
||
|
apply (rule bisim_separate_cap_cases [where cap = cap])
|
||
|
apply (simp split del: split_if)
|
||
|
apply (rule bisim_throwError, simp)
|
||
|
apply (simp split del: split_if)
|
||
|
apply (rule bisim_reflE)
|
||
|
apply (fastforce intro!: bisim_throwError bisim_returnOk simp: AllowRecv_def AllowSend_def)
|
||
|
apply simp
|
||
|
done
|
||
|
|
||
|
abbreviation
|
||
|
"separate_inv c \<equiv> \<exists>ptr badge rights. c = InvokeAsyncEndpoint ptr badge rights"
|
||
|
|
||
|
lemma perform_invocation_bisim:
|
||
|
"bisim (dc \<oplus> op =) \<top> (\<top> and K (separate_inv c))
|
||
|
(perform_invocation a b c) (Syscall_A.perform_invocation a b c)"
|
||
|
apply (rule bisim_gen_asm_r)
|
||
|
apply clarsimp
|
||
|
apply (rule bisim_reflE_dc)
|
||
|
done
|
||
|
|
||
|
lemmas bisim_split_reflE_eq = bisim_split_reflE [where R = "op =" and f = "op =", OF _ _ _ refl refl]
|
||
|
lemmas bisim_split_reflE_dc = bisim_split_reflE [where R = "op =" and f = "dc", OF _ _ _ dc_refl refl]
|
||
|
|
||
|
lemma decode_separate_inv:
|
||
|
"\<lbrace>\<top> and K ((\<forall>c \<in> set f. separate_cap (fst c)) \<and> (separate_cap cap))\<rbrace> Decode_A.decode_invocation a b c d cap f \<lbrace>\<lambda>rv s. separate_inv rv\<rbrace>, -"
|
||
|
unfolding Decode_A.decode_invocation_def
|
||
|
apply (rule hoare_gen_asmE)
|
||
|
apply clarify
|
||
|
apply (erule separate_capE, simp_all split del: split_if)
|
||
|
apply (rule hoare_pre, (wp | simp add: comp_def)+)[1]
|
||
|
apply (rule hoare_pre)
|
||
|
apply (wp | simp)+
|
||
|
done
|
||
|
|
||
|
lemma lcas_sep [wp]:
|
||
|
"\<lbrace>separate_state and valid_objs\<rbrace> lookup_cap_and_slot t v \<lbrace>\<lambda>rv s. separate_cap (fst rv)\<rbrace>, -"
|
||
|
apply (simp add: lookup_cap_and_slot_def split_def bind_assoc)
|
||
|
apply (rule hoare_pre)
|
||
|
apply (wp lsft_sep get_cap_wp'|simp)+
|
||
|
done
|
||
|
|
||
|
lemma lec_separate_caps:
|
||
|
"\<lbrace>separate_state and valid_objs\<rbrace> lookup_extra_caps t buffer ra \<lbrace>\<lambda>rv s. (\<forall>c\<in>set rv. separate_cap (fst c))\<rbrace>, -"
|
||
|
unfolding lookup_extra_caps_def
|
||
|
apply (wp mapME_set | simp)+
|
||
|
done
|
||
|
|
||
|
lemma handle_invocation_bisim:
|
||
|
"bisim (dc \<oplus> op =) \<top> (separate_state and valid_objs and cur_tcb) (handle_invocation c b) (Syscall_A.handle_invocation c b)"
|
||
|
unfolding handle_invocation_def Syscall_A.handle_invocation_def
|
||
|
apply (simp add: split_def)
|
||
|
apply (rule bisim_guard_imp)
|
||
|
apply (rule bisim_split_reflE_dc)+
|
||
|
apply (rule syscall_bisim)
|
||
|
apply (rule bisim_split_reflE_dc [where Q = "\<lambda>_. \<top>" and Q' = "\<lambda>_. \<top>"])+
|
||
|
apply (rule bisim_reflE_dc)
|
||
|
apply wp
|
||
|
apply (rule bisim_when [OF _ refl])
|
||
|
apply (rule handle_fault_bisim)
|
||
|
apply simp
|
||
|
apply (rule bisim_split_reflE_eq)
|
||
|
apply simp
|
||
|
apply (rule decode_invocation_bisim)
|
||
|
apply wp
|
||
|
apply (simp, rule bisim_refl')
|
||
|
apply simp
|
||
|
apply (rule bisim_split_reflE_dc)
|
||
|
apply (rule bisim_splitE_req)
|
||
|
apply (rule perform_invocation_bisim)
|
||
|
apply simp
|
||
|
apply (rule bisim_refl')
|
||
|
apply (wp | simp)+
|
||
|
apply (rule decode_separate_inv)
|
||
|
apply (wp lec_separate_caps | simp add: cur_tcb_def)+
|
||
|
done
|
||
|
|
||
|
lemma bisim_split_catch:
|
||
|
assumes bm: "bisim (f' \<oplus> r) Pn Pn' m m'"
|
||
|
and bc: "\<And>x x'. f' x x' \<Longrightarrow> bisim r (Pf x) (Pf' x') (c x) (c' x')"
|
||
|
and v1: "\<lbrace>P\<rbrace> m \<lbrace>\<lambda>_ _. True\<rbrace>, \<lbrace>Pf\<rbrace>"
|
||
|
and v2: "\<lbrace>P'\<rbrace> m' \<lbrace>\<lambda>_ _. True\<rbrace>, \<lbrace>Pf'\<rbrace>"
|
||
|
shows "bisim r (Pn and P) (Pn' and P') (m <catch> c) (m' <catch> c')"
|
||
|
unfolding catch_def
|
||
|
apply (rule bisim_split [where Q = "\<lambda>r s. sum_case (\<lambda>l. Pf l s) (\<lambda>_. True) r" and Q' = "\<lambda>r s. sum_case (\<lambda>l. Pf' l s) (\<lambda>_. True) r", OF bm, folded validE_def])
|
||
|
apply (case_tac ra)
|
||
|
apply clarsimp
|
||
|
apply (erule bc)
|
||
|
apply clarsimp
|
||
|
apply (rule bisim_return')
|
||
|
apply simp
|
||
|
apply (rule v1)
|
||
|
apply (rule v2)
|
||
|
done
|
||
|
|
||
|
lemma rel_sum_comb_eq:
|
||
|
"(op = \<oplus> op =) = (op =)"
|
||
|
apply (rule ext, rule ext)
|
||
|
apply (case_tac x)
|
||
|
apply auto
|
||
|
done
|
||
|
|
||
|
lemma bisim_split_catch_req:
|
||
|
assumes bm: "bisim (op = \<oplus> op =) Pn Pn' m m'"
|
||
|
and bc: "\<And>x. bisim op = (Pf x) (Pf' x) (c x) (c' x)"
|
||
|
and v1: "\<lbrace>P\<rbrace> m \<lbrace>\<lambda>_ _. True\<rbrace>, \<lbrace>\<lambda>r. Pf r and Pf' r\<rbrace>"
|
||
|
shows "bisim op = (Pn and P) Pn' (m <catch> c) (m' <catch> c')"
|
||
|
unfolding catch_def
|
||
|
apply (rule bisim_split_req [where Q = "\<lambda>r s. sum_case (\<lambda>l. Pf l s) (\<lambda>_. True) r" and Q' = "\<lambda>r s. sum_case (\<lambda>l. Pf' l s) (\<lambda>_. True) r"])
|
||
|
apply (rule bm [simplified rel_sum_comb_eq])
|
||
|
apply (case_tac r)
|
||
|
apply clarsimp
|
||
|
apply (rule bc)
|
||
|
apply clarsimp
|
||
|
apply (rule bisim_return')
|
||
|
apply simp
|
||
|
apply (rule hoare_post_imp [OF _ v1 [unfolded validE_def]])
|
||
|
apply (clarsimp split: sum.split_asm)
|
||
|
done
|
||
|
|
||
|
lemma bisim_injection:
|
||
|
assumes x: "t = injection_handler fn"
|
||
|
assumes y: "t' = injection_handler fn'"
|
||
|
assumes z: "\<And>ft ft'. f' ft ft' \<Longrightarrow> f (fn ft) (fn' ft')"
|
||
|
shows "bisim (f' \<oplus> r) P P' m m'
|
||
|
\<Longrightarrow> bisim (f \<oplus> r) P P' (t m) (t' m')"
|
||
|
apply (simp add: injection_handler_def handleE'_def x y)
|
||
|
apply (rule bisim_guard_imp)
|
||
|
apply (erule bisim_split)
|
||
|
apply (case_tac ra, clarsimp+)[1]
|
||
|
apply (rule bisim_throwError)
|
||
|
apply (simp add: z)
|
||
|
apply clarsimp
|
||
|
apply (rule bisim_return)
|
||
|
apply simp
|
||
|
apply wp
|
||
|
apply simp+
|
||
|
done
|
||
|
|
||
|
lemma cap_fault_injection:
|
||
|
"cap_fault_on_failure addr b = injection_handler (ExceptionTypes_A.CapFault addr b)"
|
||
|
apply (rule ext)
|
||
|
apply (simp add: cap_fault_on_failure_def injection_handler_def o_def)
|
||
|
done
|
||
|
|
||
|
lemma separate_state_cdt [simp]:
|
||
|
"separate_state (s\<lparr>cdt := x\<rparr>) = separate_state s"
|
||
|
unfolding separate_state_def
|
||
|
by (simp add: get_tcb_def)
|
||
|
|
||
|
lemma separate_state_original [simp]:
|
||
|
"separate_state (s\<lparr>is_original_cap := x\<rparr>) = separate_state s"
|
||
|
unfolding separate_state_def
|
||
|
by (simp add: get_tcb_def)
|
||
|
|
||
|
lemma separate_cap_NullCap [simp]: "separate_cap NullCap" by (simp add: separate_cap_def)
|
||
|
|
||
|
lemma set_cap_NullCap_separate_state [wp]:
|
||
|
"\<lbrace>separate_state\<rbrace> set_cap NullCap cptr \<lbrace>\<lambda>_. separate_state\<rbrace>"
|
||
|
unfolding separate_state_def[abs_def] separate_tcb_def separate_cnode_cap_def
|
||
|
apply (simp add: separate_state_def[abs_def] tcb_at_typ)
|
||
|
apply (rule hoare_pre)
|
||
|
apply wps
|
||
|
apply (wp set_cap_typ_at hoare_vcg_all_lift)
|
||
|
apply (subst separate_cnode_cap_def)
|
||
|
apply (clarsimp simp: separate_cap_def)
|
||
|
apply (drule spec, drule (1) mp)
|
||
|
apply (clarsimp cong: option.case_cong cap.case_cong split: option.split_asm)
|
||
|
apply (erule separate_cnode_capE)
|
||
|
apply (simp add: separate_cnode_cap_def)
|
||
|
apply (clarsimp simp add: separate_cnode_cap_def split: option.splits)
|
||
|
done
|
||
|
|
||
|
lemma separate_state_pres:
|
||
|
assumes rl: "(\<And>P t p. \<lbrace>\<lambda>s. P (typ_at t p s) (caps_of_state s)\<rbrace> f \<lbrace>\<lambda>_ s. P (typ_at t p s) (caps_of_state s)\<rbrace>)"
|
||
|
shows "\<lbrace>separate_state\<rbrace> f \<lbrace>\<lambda>_. separate_state\<rbrace>"
|
||
|
unfolding separate_state_def[abs_def]
|
||
|
apply (simp add: tcb_at_typ)
|
||
|
apply (wp hoare_vcg_all_lift rl)
|
||
|
done
|
||
|
|
||
|
lemma separate_state_more_update[simp]:
|
||
|
"separate_state (trans_state f s) =
|
||
|
separate_state s"
|
||
|
by (simp add: separate_state_def)
|
||
|
|
||
|
lemma cap_delete_one_sep [wp]:
|
||
|
"\<lbrace>separate_state\<rbrace> cap_delete_one cptr \<lbrace>\<lambda>_. separate_state\<rbrace>"
|
||
|
unfolding cap_delete_one_def
|
||
|
apply (simp add: unless_when)
|
||
|
apply (wp get_cap_wp')
|
||
|
apply (simp add: empty_slot_def)
|
||
|
apply (wp | simp)+
|
||
|
(* ugh *)
|
||
|
apply (rule separate_state_pres)
|
||
|
apply (rule hoare_pre)
|
||
|
apply (wps set_cdt_typ_at)
|
||
|
apply (wp)
|
||
|
apply assumption
|
||
|
apply (wp get_cap_inv hoare_drop_imps)
|
||
|
apply (simp add: conj_ac)
|
||
|
apply (rule separate_state_pres)
|
||
|
apply (rule hoare_pre)
|
||
|
apply (wps )
|
||
|
apply wp
|
||
|
apply simp
|
||
|
apply (wp get_cap_wp')
|
||
|
apply simp
|
||
|
done
|
||
|
|
||
|
lemma bisim_caller_cap:
|
||
|
assumes bs: "bisim R P P' a (f NullCap)"
|
||
|
shows "bisim R P (P' and tcb_at p and separate_state) a (get_cap (p, tcb_cnode_index 3) >>= f)"
|
||
|
apply (rule bisim_guard_imp)
|
||
|
apply (rule bisim_symb_exec_r [where Pe = \<top>])
|
||
|
apply (rule_tac F = "rv = NullCap" in bisim_gen_asm_r)
|
||
|
apply simp
|
||
|
apply (rule bs)
|
||
|
apply (wp get_cap_wp')
|
||
|
apply fastforce
|
||
|
apply wp
|
||
|
apply simp
|
||
|
apply (clarsimp simp: cte_wp_at_caps_of_state tcb_at_def
|
||
|
caps_of_state_tcb_cap_cases dom_tcb_cap_cases
|
||
|
cong: conj_cong)
|
||
|
apply (drule (1) separate_state_get_tcbD)
|
||
|
apply simp
|
||
|
done
|
||
|
|
||
|
lemma delete_caller_cap_bisim:
|
||
|
"bisim op = \<top> (tcb_at r and separate_state) (return ()) (delete_caller_cap r)"
|
||
|
unfolding delete_caller_cap_def
|
||
|
apply (rule bisim_guard_imp)
|
||
|
apply (simp add: cap_delete_one_def unless_when)
|
||
|
apply (rule bisim_caller_cap)
|
||
|
apply (simp add: when_def)
|
||
|
apply (rule bisim_refl')
|
||
|
apply simp_all
|
||
|
done
|
||
|
|
||
|
lemma bisim_guard_imp_both:
|
||
|
"\<lbrakk> bisim r P P' m m'; \<And>s. R s \<Longrightarrow> P s \<and> P' s \<rbrakk> \<Longrightarrow> bisim r \<top> R m m'"
|
||
|
unfolding bisim_underlying_def by auto
|
||
|
|
||
|
lemma handle_wait_bisim:
|
||
|
"bisim op = \<top> (separate_state and cur_tcb and valid_objs) handle_wait Syscall_A.handle_wait"
|
||
|
unfolding handle_wait_def Syscall_A.handle_wait_def
|
||
|
apply (simp add: Let_def)
|
||
|
apply (rule bisim_guard_imp_both)
|
||
|
apply (rule bisim_split_refl)
|
||
|
apply (rule bisim_symb_exec_r_bs)
|
||
|
apply (rule delete_caller_cap_bisim)
|
||
|
apply (rule bisim_split_refl)
|
||
|
apply (rule bisim_split_catch_req)
|
||
|
apply (simp add: cap_fault_injection)
|
||
|
apply (rule bisim_injection [OF refl refl, where f' = "op ="])
|
||
|
apply simp
|
||
|
apply (rule bisim_split_reflE)
|
||
|
apply (rule_tac cap = rb in bisim_separate_cap_cases)
|
||
|
apply (simp, rule bisim_throwError, rule refl)+
|
||
|
apply (simp split del: split_if)
|
||
|
apply (rule bisim_refl [where P = \<top> and P' = \<top>])
|
||
|
apply (case_tac rc, simp_all)[1]
|
||
|
apply (wp get_cap_wp' lsft_sep | simp add: lookup_cap_def split_def del: hoare_True_E_R)+
|
||
|
apply (rule handle_fault_bisim)
|
||
|
apply (wp | wpc | simp)+
|
||
|
apply (rule_tac Q' = "\<lambda>_. separate_state and valid_objs and tcb_at r" in hoare_post_imp_R)
|
||
|
prefer 2
|
||
|
apply simp
|
||
|
apply (wp | simp add: cur_tcb_def)+
|
||
|
done
|
||
|
|
||
|
lemma handle_reply_bisim:
|
||
|
"bisim op = \<top> (separate_state and cur_tcb) (return ()) Syscall_A.handle_reply"
|
||
|
unfolding Syscall_A.handle_reply_def
|
||
|
apply (rule bisim_guard_imp_both)
|
||
|
apply (rule bisim_symb_exec_r [where Pe = \<top>])
|
||
|
apply (rule bisim_caller_cap)
|
||
|
apply simp
|
||
|
apply (rule bisim_return)
|
||
|
apply simp
|
||
|
apply (wp | simp add: cur_tcb_def)+
|
||
|
done
|
||
|
|
||
|
lemma handle_event_bisim:
|
||
|
"bisim (dc \<oplus> op =) \<top> (separate_state and cur_tcb and valid_objs) (handle_event ev) (Syscall_A.handle_event ev)"
|
||
|
apply (cases ev, simp_all add: handle_send_def Syscall_A.handle_send_def
|
||
|
handle_call_def Syscall_A.handle_call_def
|
||
|
handle_reply_def
|
||
|
cong: syscall.case_cong)
|
||
|
|
||
|
apply (case_tac syscall, simp_all)[1]
|
||
|
|
||
|
apply (rule bisim_guard_imp_both, rule handle_invocation_bisim, simp)
|
||
|
apply (rule bisim_guard_imp_both, rule handle_invocation_bisim, simp)
|
||
|
apply (rule bisim_guard_imp_both, rule handle_invocation_bisim, simp)
|
||
|
apply (rule bisim_guard_imp_both, rule handle_wait_bisim, simp)
|
||
|
apply (rule bisim_guard_imp_both, rule handle_reply_bisim, simp)
|
||
|
|
||
|
apply (rule bisim_guard_imp_both)
|
||
|
apply (rule bisim_symb_exec_r_bs)
|
||
|
apply (rule handle_reply_bisim)
|
||
|
apply (rule handle_wait_bisim)
|
||
|
apply simp
|
||
|
|
||
|
apply (simp add: handle_yield_def Syscall_A.handle_yield_def)
|
||
|
apply (rule bisim_guard_imp_both, rule bisim_refl', simp)
|
||
|
|
||
|
apply (rule bisim_split_refl)
|
||
|
apply (rule handle_fault_bisim)
|
||
|
apply wp
|
||
|
apply (simp add: cur_tcb_def)
|
||
|
|
||
|
apply (rule bisim_split_refl)
|
||
|
apply (rule handle_fault_bisim)
|
||
|
apply wp
|
||
|
apply (simp add: cur_tcb_def)
|
||
|
|
||
|
apply (rule bisim_refl)
|
||
|
apply simp
|
||
|
|
||
|
apply (rule bisim_guard_imp_both)
|
||
|
apply (rule bisim_split_refl)
|
||
|
apply (rule bisim_split_catch_req)
|
||
|
apply (rule bisim_reflE)
|
||
|
apply (rule handle_fault_bisim)
|
||
|
apply wp
|
||
|
apply (case_tac vmfault_type, simp_all)[1]
|
||
|
apply (wp separate_state_pres)
|
||
|
apply (rule hoare_pre, wps, wp, simp)
|
||
|
apply wp
|
||
|
apply (rule hoare_pre, wps, wp, simp)
|
||
|
apply simp
|
||
|
|
||
|
apply (wp separate_state_pres)
|
||
|
apply (rule hoare_pre, wps, wp, simp)
|
||
|
apply wp
|
||
|
apply (rule hoare_pre, wps, wp, simp)
|
||
|
apply simp
|
||
|
|
||
|
apply wp
|
||
|
apply (simp_all add: cur_tcb_def)
|
||
|
done
|
||
|
|
||
|
lemma call_kernel_bisim:
|
||
|
"bisim (op =) \<top> (separate_state and cur_tcb and valid_objs) (call_kernel ev) (Syscall_A.call_kernel ev)"
|
||
|
unfolding call_kernel_def Syscall_A.call_kernel_def
|
||
|
apply (rule bisim_guard_imp_both)
|
||
|
apply simp
|
||
|
apply (rule bisim_split)
|
||
|
apply (rule bisim_split_handle)
|
||
|
apply (rule handle_event_bisim)
|
||
|
apply simp
|
||
|
apply (rule bisim_refl')
|
||
|
apply wp
|
||
|
apply (rule bisim_refl')
|
||
|
apply wp
|
||
|
apply simp
|
||
|
done
|
||
|
|
||
|
end
|