(* * 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 KHeap_DP imports ProofHelpers_DP begin lemma has_slots_simps: "has_slots (Tcb tcb)" "has_slots (CNode cnode)" "has_slots (AsidPool ap)" "has_slots (PageTable pt)" "has_slots (PageDirectory pd)" "\ has_slots Endpoint" "\ has_slots Notification" "\ has_slots (Frame f)" "\ has_slots Untyped" by (simp add: has_slots_def)+ lemma reset_cap_asid_id: "reset_cap_asid cap = reset_cap_asid cap' \ cap = cap' \ (\a b c d e f. cap = FrameCap f a b c d e) \ (\a b c. cap = PageTableCap a b c) \ (\a b c. cap = PageDirectoryCap a b c)" by (case_tac cap, (clarsimp simp: reset_cap_asid_def split: cdl_cap.splits)+) (* Move to Helpers_SD *) definition is_memory_cap :: "cdl_cap \ bool" where "is_memory_cap cap \ (case cap of FrameCap _ _ _ _ _ _ \ True | PageTableCap _ _ _ \ True | PageDirectoryCap _ _ _ \ True | _ \ False)" lemma reset_cap_asid_memory_cap [simp]: "\is_memory_cap cap \ reset_cap_asid cap = cap" by (clarsimp simp: is_memory_cap_def reset_cap_asid_def split: cdl_cap.splits) lemma is_memory_cap_reset_cap_asid [simp]: "is_memory_cap (reset_cap_asid cap) = is_memory_cap cap" by (clarsimp simp: is_memory_cap_def reset_cap_asid_def split: cdl_cap.splits) lemmas reset_cap_asid_simps[simp] = reset_cap_asid_def [THEN meta_eq_to_obj_eq, THEN fun_cong,split_simps cdl_cap.split] lemma reset_cap_asid_simps2: "reset_cap_asid cap = NullCap \ cap = NullCap" "reset_cap_asid cap = RunningCap \ cap = RunningCap" "reset_cap_asid cap = (UntypedCap dev a ra) \ cap = UntypedCap dev a ra" "reset_cap_asid cap = (EndpointCap b c d) \ cap = EndpointCap b c d" "reset_cap_asid cap = (NotificationCap e f g) \ cap = NotificationCap e f g" "reset_cap_asid cap = (ReplyCap h R) \ cap = ReplyCap h R" "reset_cap_asid cap = (MasterReplyCap i) \ cap = MasterReplyCap i" "reset_cap_asid cap = (CNodeCap j k l sz) \ cap = CNodeCap j k l sz" "reset_cap_asid cap = (TcbCap m) \ cap = TcbCap m" "reset_cap_asid cap = DomainCap \ cap = DomainCap" "reset_cap_asid cap = RestartCap \ cap = RestartCap" "reset_cap_asid cap = (PendingSyncSendCap n p q r s rp) \ cap = (PendingSyncSendCap n p q r s rp)" "reset_cap_asid cap = (PendingSyncRecvCap t isf rp) \ cap = (PendingSyncRecvCap t isf rp)" "reset_cap_asid cap = (PendingNtfnRecvCap u) \ cap = (PendingNtfnRecvCap u)" "reset_cap_asid cap = IrqControlCap \ cap = IrqControlCap" "reset_cap_asid cap = (IrqHandlerCap v) \ cap = (IrqHandlerCap v)" "reset_cap_asid cap = AsidControlCap \ cap = AsidControlCap" "reset_cap_asid cap = (AsidPoolCap w x) \ cap = (AsidPoolCap w x)" "reset_cap_asid cap = (IOPortsCap y z) \ cap = (IOPortsCap y z)" "reset_cap_asid cap = IOSpaceMasterCap \ cap = IOSpaceMasterCap" "reset_cap_asid cap = (IOSpaceCap a1) \ cap = (IOSpaceCap a1)" "reset_cap_asid cap = (IOPageTableCap a2) \ cap = (IOPageTableCap a2)" "reset_cap_asid cap = (ZombieCap a3) \ cap = (ZombieCap a3)" "reset_cap_asid cap = (BoundNotificationCap a4) \ cap = (BoundNotificationCap a4)" "reset_cap_asid cap = (FrameCap dev aa rghts sz rset ma) \ \asid. cap = FrameCap dev aa rghts sz rset asid" "reset_cap_asid cap = (PageTableCap aa rights ma) \ \asid. cap = PageTableCap aa rights asid" "reset_cap_asid cap = (PageDirectoryCap aa rights as) \ \asid. cap = PageDirectoryCap aa rights asid" by (clarsimp simp: reset_cap_asid_def split: cdl_cap.splits)+ lemma sep_map_c_any: "(p \c cap \* R) s \ (p \c - \* R) s" by (fastforce simp: sep_any_def sep_conj_exists) lemma pure_extract: "\

* Q> s; pure P \ \

s" by (fastforce simp: pure_def sep_state_projection_def sep_conj_def) lemma throw_on_none_rv: "\\s. case x of Some y \ P y s | otherwise \ False\ throw_on_none x \P\, \Q\" apply (clarsimp simp: throw_on_none_def split: option.splits) apply (wp)+ done lemma oseq: "\ \P\ gets_the f \Q\; \x. \Q x\ gets_the $ g x \R\ \ \ \P\ gets_the (f |>> g) \R\" apply (fastforce simp: gets_def fail_def get_def return_def gets_the_def obind_def valid_def split_def Let_def bind_def assert_opt_def split:option.splits) done lemma hoare_ex_all: "(\x. \P x\ f \Q\) = \\s. \x. P x s\ f \Q\" apply (rule iffI) apply (fastforce simp: valid_def)+ done lemma sep_any_All: "\c - \* R>\ f \Q\ = (\x. \c x \* R>\ f \Q\)" apply (clarsimp simp: sep_any_def sep_conj_exists hoare_ex_all) done (* validE reasoning *) lemma gets_the_wpE: "\\s. case (f s) of None \ True | Some (Inl e) \ E e s | Some (Inr r) \ Q r s \ gets_the f \Q\,\E\" apply (clarsimp simp: validE_def) apply (wp) apply (clarsimp) done lemma gets_the_invE : "\P\ gets_the f \\_. P\, -" apply (wp) apply (clarsimp) done lemma return_rv :"\P r\ return (Inr r) \\rv s. P rv s\, \\_ _. True\" by (clarsimp simp: validE_def, wp, simp split: option.splits) crunch inv[wp]: throw_on_none P lemma hoare_if_simp: "\P\ f \Q\ \ \P\ f \\rv s. (if x then (\rv s. Q rv s) else (\rv s. Q rv s)) rv s\" by (clarsimp) lemma hoare_if_simpE: "\\x. Q x = R x; \P\ f \Q\,-\ \ \P\ f \\rv s. (if x rv s then (\s. Q rv s) else (\s. R rv s)) s\,-" by (clarsimp simp: validE_R_def validE_def split: sum.splits) lemma hoare_gen_asmEx: "(P \ \P'\ f \Q\, \E\) \ \P' and K P\ f \Q\, \E\" by (fastforce simp: valid_def validE_def) lemma unless_wp_not: "\\s. P s \ Q\ unless Q f \\_. P\" by (clarsimp simp: unless_def when_def) lemma false_e_explode: "\P\ f \Q\,\\_ _ . False\ \ \P\ f \Q\,\R\" by (fastforce simp: validE_def valid_def split: sum.splits) (* sep rules *) lemma sep_any_map_c_imp: "(dest \c cap) s \ (dest \c -) s" by (fastforce simp: sep_any_def) lemma obj_exists_map_i: "o obj \* R> s \ \obj'. (cdl_objects s obj_id = Some obj' \ object_clean obj = object_clean obj')" apply (clarsimp simp: sep_map_o_conj) apply (case_tac "cdl_objects s obj_id") apply (drule_tac x = "(obj_id,Fields)" in fun_cong) apply (clarsimp simp: lift_def object_to_sep_state_def object_project_def object_at_heap_def sep_state_projection_def sep_conj_def Let_unfold) apply (rule_tac x = a in exI,simp) apply (rule object_eqI) apply (drule_tac x = "(obj_id,Fields)" in fun_cong) apply (clarsimp simp: lift_def object_to_sep_state_def object_project_def object_at_heap_def sep_state_projection_def Let_unfold) apply (rule ext) apply (drule_tac x= "(obj_id,Slot x)" in fun_cong) apply (clarsimp simp: lift_def object_to_sep_state_def object_project_def sep_state_projection_def Let_unfold) done lemma obj_exists_map_f: "f obj \* R> s \ \obj'. (cdl_objects s obj_id = Some obj' \ object_type obj = object_type obj')" apply (clarsimp simp: sep_map_f_conj Let_def) apply (case_tac "cdl_objects s obj_id") apply (clarsimp simp: lift_def object_to_sep_state_def object_project_def object_at_heap_def sep_state_projection_def sep_conj_def Let_unfold) apply (rule_tac x = a in exI,simp) apply (clarsimp simp: lift_def object_to_sep_state_def object_project_def object_at_heap_def sep_state_projection_def Let_unfold) apply (drule_tac f = object_type in arg_cong) apply simp done lemma object_slots_asid_reset: "object_slots (asid_reset obj) = reset_cap_asid \\<^sub>M (object_slots obj)" by (clarsimp simp: object_slots_def asid_reset_def update_slots_def split: cdl_object.splits) lemma reset_cap_asid_idem [simp]: "reset_cap_asid (reset_cap_asid cap) = reset_cap_asid cap" by (simp add: reset_cap_asid_def split: cdl_cap.splits) lemma opt_cap_sep_imp: "\

c cap \* R> s\ \ \cap'. opt_cap p s = Some cap' \ reset_cap_asid cap' = reset_cap_asid cap" apply (clarsimp simp: opt_cap_def sep_map_c_conj Let_def) apply (clarsimp simp: sep_map_c_def lift_def split_def sep_any_def sep_map_general_def slots_of_def sep_state_projection_def object_project_def object_slots_object_clean Let_unfold split:sep_state.splits option.splits) done lemma opt_cap_sep_any_imp: "\c - \* R> s\ \ \cap. opt_cap (dest) s = Some cap" apply (clarsimp simp: sep_any_exist opt_cap_def sep_map_c_conj Let_def) apply (clarsimp simp: sep_map_c_def lift_def split_def object_slots_object_clean sep_any_def sep_map_general_def slots_of_def sep_state_projection_def object_project_def Let_unfold split:sep_state.splits option.splits) done lemma sep_f_size_opt_cnode: "\< cap_object cnode_cap \f CNode (empty_cnode r) \* R> s; (opt_cnode (cap_object cnode_cap) s) = Some obj \ \ r = cdl_cnode_size_bits obj" apply (clarsimp simp:sep_map_f_conj Let_def) apply (case_tac obj) apply (auto simp: intent_reset_def empty_cnode_def opt_cnode_def update_slots_def sep_state_projection_def object_wipe_slots_def object_project_def object_clean_def asid_reset_def split:cdl_cap.splits cdl_object.splits) done (* concerete wp rules *) lemma swap_parents_wp: "\\ swap_parents src dest \\_. \" by (wpsimp simp: swap_parents_def lift_def sep_state_projection_def) lemma insert_cap_orphan_wp: "\c - \* R>\ insert_cap_orphan cap dest \\_.c cap \* R>\" apply (clarsimp simp: insert_cap_orphan_def) apply (wp set_cap_wp) apply (clarsimp) done lemma move_cap_wp: "\c - \* src \c cap \* R>\ move_cap cap' src dest \\_. c cap' \* src \c NullCap \* R>\" apply (simp add: move_cap_def) apply (wp add: swap_parents_wp sep_wp: insert_cap_orphan_wp set_cap_wp) apply (sep_solve) done lemma swap_cap_wp: "\c cap \* src \c cap' \* R>\ swap_cap cap' src cap dest \\_.c cap' \* src \c cap \* R>\" apply (clarsimp simp add: swap_cap_def) apply (wp add: swap_parents_wp sep_wand: set_cap_wp) apply (sep_solve) done lemma set_parent_wp: "\

\ set_parent child parent \\_.

\" apply (clarsimp simp: set_parent_def sep_state_projection_def) apply wp apply clarsimp done lemma not_untyped_cap_set_full: "\P and K (\ is_untyped_cap cap)\ set_untyped_cap_as_full src_cap cap src \\r. P\" apply (rule hoare_gen_asm) apply (clarsimp simp:set_untyped_cap_as_full_def) done lemma insert_cap_sibling_wp: "\c - \* R> and K (\ is_untyped_cap cap)\ insert_cap_sibling cap src dest \\_. c cap \* R>\" apply (clarsimp simp: insert_cap_sibling_def) apply (wp) apply (clarsimp split: option.splits) apply (safe) apply (wp set_parent_wp set_cap_wp not_untyped_cap_set_full | simp)+ done lemma insert_cap_child_wp: "\c - \* R> and K (\ is_untyped_cap cap)\ insert_cap_child cap src dest \\_. c cap \* R>\" apply (clarsimp simp: insert_cap_child_def) apply (wp insert_cap_orphan_wp set_parent_wp set_cap_wp not_untyped_cap_set_full | simp)+ done lemma remove_parent_wp: "\

\ remove_parent obj \\_.

\" by (wpsimp simp: remove_parent_def lift_def sep_state_projection_def) lemma get_cap_wp: "\P\ get_cap obj \\_. P\" apply (wp) apply (clarsimp simp: opt_cap_def) done lemma get_cap_rv: "\\s. c cap \* R> s \ (\c. ((reset_cap_asid c = reset_cap_asid cap ) \ Q c s)) \ get_cap ptr \ Q \" apply (wp) apply (safe) apply (clarsimp simp: split_def dest!: opt_cap_sep_imp) done lemma get_cap_rv': "\\s. c cap \* R> s \ Q cap s \ \is_memory_cap cap\ get_cap ptr \Q\" by (wp get_cap_rv, fastforce) lemma decode_tcb_invocation: "\P\decode_tcb_invocation cap cap_ref caps (TcbWriteRegistersIntent resume flags count regs) \\_. P\" apply (clarsimp simp: decode_tcb_invocation_def) apply (wp alternative_wp) apply (clarsimp) done lemma get_object_wp: "\P\ get_object ptr \\_. P\" apply (wp gets_the_inv) done lemma empty_slot_wp: "\c - \* R>\ empty_slot dest \\_. c NullCap \* R>\" apply (clarsimp simp: empty_slot_def sep_any_def sep_conj_exists) apply (subst hoare_ex_all [THEN sym], clarsimp) apply (wp set_cap_wp remove_parent_wp get_cap_rv[where R=R]) apply (rule conjI, assumption) apply safe apply (clarsimp simp: reset_cap_asid_def split: cdl_cap.splits) apply sep_solve done lemma invoke_cnode_insert_wp: "\c - \* R> and K (\ is_untyped_cap cap)\ invoke_cnode (InsertCall cap src dest) \\_. c cap \* R>\" apply (rule hoare_gen_asm) apply (clarsimp simp: invoke_cnode_def) apply (wp insert_cap_sibling_wp insert_cap_child_wp alternative_wp) apply (clarsimp) done lemma invoke_cnode_move_cap: "\c - \* src \c cap \* R> \ invoke_cnode (MoveCall cap' src dest) \\_. c cap' \* src \c NullCap \* R>\,\Q\" apply (simp add:validE_def) apply (rule hoare_name_pre_state) apply (clarsimp simp:invoke_cnode_def liftE_bindE validE_def[symmetric]) apply (wp move_cap_wp) apply simp done lemma invoke_cnode_rotate1_wp: "\c cap1 \* src \c cap2 \* R> \ invoke_cnode (RotateCall cap1 cap2 dest src dest) \\_. c cap2 \* src \c cap1 \* R>\" apply (clarsimp simp: invoke_cnode_def) apply (wp sep_wand: swap_cap_wp) apply sep_solve done lemma invoke_cnode_rotate2_wp: "(dest) \ (rnd) \ \c cap1 \* src \c cap2 \* rnd \c - \* R>\ invoke_cnode (RotateCall cap1 cap2 dest src rnd) \\_. c NullCap \* src \c cap1 \* rnd \c cap2 \* R>\" apply (clarsimp simp: invoke_cnode_def) apply (wp sep_wand: move_cap_wp) apply sep_solve done lemma get_cnode_wp [wp]: "\ \s. case (cdl_objects s a) of Some (CNode x) \ P x s | _ \ False \ get_cnode a \ P \" apply (clarsimp simp: get_cnode_def) apply (wp | wpc)+ apply (clarsimp split: cdl_object.splits) done lemma resolve_address_bits_wp: "\ \s. P s \ resolve_address_bits cnode_cap cap_ptr remaining_size \ \_. P \, \ \_. P \" apply (clarsimp simp: gets_the_resolve_cap[symmetric]) apply (wp) apply simp done lemma resolve_cap_wp [wp]: "\ P \ gets_the (resolve_cap cnode_cap cap_ptr remaining_size) \ \_. P \" by (wp gets_the_inv) lemma lookup_slot_for_cnode_op_wp [wp]: "\P\ lookup_slot_for_cnode_op cnode_cap cap_ptr remaining_size \\_. P \" apply (clarsimp simp: lookup_slot_for_cnode_op_def split_def) apply (wp) apply (clarsimp simp: fault_to_except_def) apply (wp) apply (clarsimp simp: gets_the_resolve_cap[symmetric]) apply (wp gets_the_wpE hoare_whenE_wp)+ apply (clarsimp split: option.splits sum.splits) done lemma lookup_slot_for_cnode_op_wpE: "\P\ lookup_slot_for_cnode_op cnode_cap cap_ptr remaining_size \\_. P \,\\_. P \" apply (clarsimp simp: lookup_slot_for_cnode_op_def split_def) apply (wp) apply (clarsimp simp: gets_the_resolve_cap[symmetric]) apply (clarsimp simp: fault_to_except_def) apply (wp gets_the_wpE hoare_whenE_wp)+ apply (clarsimp split: option.splits split: sum.splits) done lemma resolve_cap_rv1: "\\s. Q ((c,slot),0) s \ cap_object cnode_cap = c \ slot = offset cap_ptr r \ < c \f CNode (empty_cnode r) \* (c, slot) \c cap \* R> s \ one_lvl_lookup cnode_cap remaining_size r\ gets_the (resolve_cap cnode_cap cap_ptr remaining_size) \\rv s. Q rv s\,\\_ _ . True\" apply (wp gets_the_wpE) apply (clarsimp simp: one_lvl_lookup_def offset_def) apply (clarsimp simp: split_def split: sum.splits option.splits) apply (simp add: split_def resolve_cap.simps split: if_split_asm) apply (simp add: obind_def split:option.splits) apply (drule sep_f_size_opt_cnode) apply (simp split: if_split_asm)+ done lemma resolve_cap_u: "\\s. Q (((cap_object cnode_cap), offset cap_ptr r), 0) s \ < user_pointer_at (r,r_s) cnode_cap cap_ptr cap \* R> s \ gets_the (resolve_cap cnode_cap cap_ptr r_s) \Q\,\\ _ _. True\" apply (wp gets_the_wpE) apply (clarsimp simp: user_pointer_at_def Let_unfold one_lvl_lookup_def offset_def split:option.splits sum.splits) apply (simp add: split_def resolve_cap.simps split: if_split_asm) apply (simp add: obind_def sep_conj_assoc split:option.splits) apply (sep_drule (direct) sep_f_size_opt_cnode) apply (fastforce split: if_split_asm)+ done lemma resolve_cap_u_nf: "\\s. Q (((cap_object cnode_cap), offset cap_ptr r), 0) s \ < user_pointer_at (r,r_s) cnode_cap cap_ptr cap \* R> s \ gets_the (resolve_cap cnode_cap cap_ptr r_s) \Q\,\Q'\" apply (wp gets_the_wpE) apply (clarsimp simp: user_pointer_at_def Let_unfold guard_equal_def one_lvl_lookup_def offset_def sep.mult_assoc) apply (clarsimp simp: split_def split: sum.splits option.splits) apply (safe) apply (simp add: split_def resolve_cap.simps split: if_split_asm) apply (simp add: obind_def split:option.splits) apply (sep_drule (direct) sep_f_size_opt_cnode) apply (fastforce)+ apply (simp add: split_def resolve_cap.simps split: if_split_asm) apply (simp add: obind_def split:option.splits) apply (sep_drule (direct) sep_f_size_opt_cnode) apply (fastforce split: if_split_asm)+ done lemma resolve_cap_rv: "\\s. cap_object cnode_cap = c \ slot = offset cap_ptr r \ < c \f CNode (empty_cnode r) \* (c, slot) \c cap \* R> s \ one_lvl_lookup cnode_cap remaining_size r\ gets_the (resolve_cap cnode_cap cap_ptr remaining_size) \\rv s. (fst rv) = (c,slot) \ < c \f CNode (empty_cnode r) \* (c,slot) \c cap \* R> s \ (snd rv) = 0\,\\_ _ . True\" apply (wp resolve_cap_rv1 gets_the_invE) apply (clarsimp) apply (safe|fastforce)+ done lemma lookup_slot_for_cnode_op_rv': "\\s. Q (c,slot) s \ cap_object cnode_cap = c \ slot = offset cap_ptr r \ < c \f CNode (empty_cnode r) \* (c, slot) \c cap \* R> s \ one_lvl_lookup cnode_cap remaining_size r\ lookup_slot_for_cnode_op cnode_cap cap_ptr remaining_size \\rv s. Q rv s\,-" apply (clarsimp simp: lookup_slot_for_cnode_op_def gets_the_resolve_cap[symmetric] split_def fault_to_except_def) apply (wp resolve_cap_rv1 hoare_whenE_wp) apply (fastforce) done lemma reset_cap_asid_cap_has_object: "reset_cap_asid cap = reset_cap_asid cap' \ cap_has_object cap = cap_has_object cap'" apply (frule reset_cap_asid_id) apply (safe, (clarsimp simp: reset_cap_asid_def cap_has_object_def split: cdl_cap.splits)+) done lemma cap_object_reset_cap_asid: "\reset_cap_asid cap = reset_cap_asid cap'\ \ cap_object cap = cap_object cap'" apply (case_tac cap',simp_all add:reset_cap_asid_def split:cdl_cap.split_asm) done lemma cap_type_reset_cap_asid[simp]: "cap_type (reset_cap_asid cap) = cap_type cap" by (clarsimp simp: reset_cap_asid_def split: cdl_cap.splits) lemma cap_guard_reset_cap_asid: "is_cnode_cap cap \ cap_guard (reset_cap_asid cap) = cap_guard cap" "is_cnode_cap cap \ cap_guard_size (reset_cap_asid cap) = cap_guard_size cap" by (case_tac cap,simp_all add:reset_cap_asid_def cap_guard_def)+ lemma lookup_slot_for_cnode_op_rvu': "\\s. Q ((cap_object cnode_cap), offset cap_ptr r) s \ remaining_size \ word_bits \ 0 < remaining_size \ < \ (r, remaining_size): cnode_cap cap_ptr \u cap \* R> s \ lookup_slot_for_cnode_op cnode_cap cap_ptr remaining_size \Q\,\Q'\" apply (clarsimp simp: lookup_slot_for_cnode_op_def gets_the_resolve_cap[symmetric] split_def fault_to_except_def) apply (wp resolve_cap_u_nf[where r=r and R=R and cap=cap] hoare_whenE_wp) apply (clarsimp simp add:user_pointer_at_def Let_def guard_equal_def cap_guard_reset_cap_asid one_lvl_lookup_def) done lemma lookup_slot_for_cnode_op_rv_2: "\\s. cap_object cnode_cap = c \ slot = offset cap_ptr r \ < c \f CNode (empty_cnode r) \* (c, slot) \c cap \* R> s \ one_lvl_lookup cnode_cap remaining_size r\ lookup_slot_for_cnode_op cnode_cap cap_ptr remaining_size \\rv s. rv = (c,slot) \ < c \f CNode (empty_cnode r) \* (c,slot) \c cap \* R> s\,-" apply (wp lookup_slot_for_cnode_op_rv') apply (fastforce) done lemma derive_cap_rv: "\\s. case cap of FrameCap dev p r sz b x \ False | otherwise \ P s\ derive_cap slot cap \\rv s. P s \ ( rv = cap \ rv = NullCap )\, \\_ _. True\" apply (clarsimp simp: derive_cap_def returnOk_def split: cdl_cap.splits,safe) apply (wp return_rv hoare_whenE_wp alternativeE_wp | clarsimp simp: ensure_no_children_def)+ done lemma derive_cap_wp [wp]: "\P\ derive_cap slot cap \\_. P\" apply (clarsimp simp: derive_cap_def returnOk_def split: cdl_cap.splits) apply (safe) apply ((wp alternative_wp hoare_whenE_wp)|(clarsimp simp: ensure_no_children_def))+ done lemma derive_cap_wpE: "\P\ derive_cap slot cap \\_.P\,\\_.P\" apply (clarsimp simp: derive_cap_def) apply (case_tac cap, (wp hoare_whenE_wp alternative_wp | simp add: ensure_no_children_def)+) done lemma derive_cap_wp2: "\P\ derive_cap slot cap \\rv s. if rv = NullCap then True else P s\, -" apply (rule hoare_post_imp_R) apply (wp (once) derive_cap_wpE) apply (clarsimp) done lemma ensure_empty_wpE [wp]: "\P\ ensure_empty x \ \_. P \,\\_. P\" apply (clarsimp simp: ensure_empty_def) apply (wp liftE_wp unlessE_wp) apply (clarsimp) done lemma decode_cnode_copy_wp: "\P\ decode_cnode_invocation target target_ref caps (CNodeCopyIntent dest_index dest_depth src_index src_depth rights) \ \_. P \,\\_. P\" apply (clarsimp simp: decode_cnode_invocation_def split_def) apply (wp hoare_whenE_wp hoare_drop_imps | simp cong: if_cong)+ done lemma ensure_empty_wp [wp]: "\P\ ensure_empty slot \\_. P\" by (clarsimp simp: ensure_empty_def,wp unlessE_wp,clarsimp) lemma ensure_no_children_wp [wp]: "\P\ ensure_no_children slot \\_. P\" apply (clarsimp simp: ensure_no_children_def) apply (wp hoare_whenE_wp) apply (clarsimp) done lemma mapu_dest_opt_cap: "< \ (sz, r): cr ci \u cap \* R> s \ \cap'. opt_cap (cap_object cr, offset ci sz) s = Some cap' \ reset_cap_asid cap' = reset_cap_asid cap" apply (clarsimp simp: user_pointer_at_def Let_unfold sep.mult_assoc) apply (sep_drule (direct) opt_cap_sep_imp) apply (clarsimp) done lemma ensure_empty_no_exception: "\ < dest_slot \c NullCap \* R> and Q \ ensure_empty dest_slot \\r. Q \, \Q'\" apply (simp add:ensure_empty_def) apply (wp unlessE_wp) apply (clarsimp dest!:opt_cap_sep_imp reset_cap_asid_simps2) done lemma reset_cap_asid_cap_type: "reset_cap_asid cap = reset_cap_asid cap' \ cap_type cap = cap_type cap'" by (clarsimp simp: reset_cap_asid_def split: cdl_cap.splits) lemma ep_related_cap_update_cap_rights[simp]: "ep_related_cap (update_cap_rights rights cap) = ep_related_cap cap" "\ is_ep_cap cap \ \ cap_badge (update_cap_rights rights cap) = cap_badge cap" "\ is_ntfn_cap cap \ \ cap_badge (update_cap_rights rights cap) = cap_badge cap" by (auto simp:ep_related_cap_def cap_badge_def cap_type_def update_cap_rights_def split:cdl_cap.splits) lemma reset_cap_asid_cap_badge: "\reset_cap_asid cap = reset_cap_asid cap';ep_related_cap cap\ \ cap_badge cap = cap_badge cap'" apply (clarsimp simp: ep_related_cap_def split:cdl_cap.splits) by (simp_all add: ep_related_cap_def reset_cap_asid_def split:cdl_cap.splits) lemma reset_cap_asid_ep_related_cap: "reset_cap_asid cap = reset_cap_asid cap' \ ep_related_cap cap = ep_related_cap cap'" apply (clarsimp simp: ep_related_cap_def) apply (case_tac cap, (case_tac cap', simp_all add: reset_cap_asid_def)+) done lemma reset_cap_asid_ep_cap: "reset_cap_asid cap = reset_cap_asid cap' \ is_ep_cap cap = is_ep_cap cap'" apply (case_tac cap; case_tac cap'; simp add: reset_cap_asid_def) done lemma reset_cap_asid_ntfn_cap: "reset_cap_asid cap = reset_cap_asid cap' \ is_ntfn_cap cap = is_ntfn_cap cap'" apply (case_tac cap; case_tac cap'; simp add: reset_cap_asid_def) done lemma cap_rights_reset_cap_asid: "reset_cap_asid cap = reset_cap_asid cap' \ cap_rights cap = cap_rights cap'" apply (clarsimp simp: cap_rights_def reset_cap_asid_def) apply (case_tac cap; (case_tac cap'; simp)) done (* Lemmas about valid_src_cap *) lemma reset_cap_asid_cnode_cap: "\reset_cap_asid cap' = reset_cap_asid cap ; is_cnode_cap cap\ \ cap' = cap" apply (drule sym) apply (drule reset_cap_asid_id) apply (clarsimp simp: cap_type_def split: cdl_cap.splits) done lemma valid_src_cap_asid_cong: "reset_cap_asid cap' = reset_cap_asid cap \ valid_src_cap cap' = valid_src_cap cap" apply (rule ext) apply (clarsimp simp:valid_src_cap_def) apply (rule iffI[rotated]) apply (drule sym) apply (clarsimp dest!:reset_cap_asid_cnode_cap)+ done lemma derive_cap_invE: "\P (derived_cap cap) and Q\ derive_cap slot cap \P\, \\r. Q\" apply (simp add:derive_cap_def) apply (rule hoare_pre) apply (wp alternative_wp alternativeE_wp|wpc|simp)+ apply (auto simp:derived_cap_def) done lemma cap_type_null: "cap_has_type cap \ cap \ NullCap" "cap_type cap = Some type \ cap \ NullCap" by (clarsimp simp: cap_type_def)+ lemma decode_cnode_move_rvu: "\\s. intent = CNodeMoveIntent dest_index dest_depth src_index src_depth \ get_index caps 0 = Some (cap ,cap_ref) \ src_cap \ NullCap \ (\src_cap'. reset_cap_asid src_cap' = reset_cap_asid src_cap \ Q (MoveCall (src_cap') (cap_object cap, offset src_index sz) (cap_object target, offset dest_index sz')) s) \ unat src_depth \ word_bits \ 0 < unat src_depth \ unat dest_depth \ word_bits \ 0 < unat dest_depth \ < \ (sz, (unat src_depth)): cap src_index \u src_cap \* \ (sz', (unat dest_depth)): target dest_index \u NullCap \* R> s \ decode_cnode_invocation target target_ref caps intent \\rv s. Q rv s\, \Q'\" apply (unfold validE_def) apply (rule hoare_name_pre_state) apply (unfold validE_def[symmetric]) apply (clarsimp simp: decode_cnode_invocation_def split_def split: sum.splits) apply wp apply (simp add: if_apply_def2) apply (rule lookup_slot_for_cnode_op_rvu' [where r=sz and cap=src_cap and R="\ (sz', (unat dest_depth)): target dest_index \u NullCap \* R"]) apply simp apply (rule ensure_empty_no_exception) apply (rule lookup_slot_for_cnode_op_rvu'[where r=sz' and cap=NullCap and R="\ (sz, (unat src_depth)): cap src_index \u src_cap \* R"]) apply (simp, wp throw_on_none_rv validE_R_validE) apply (clarsimp split: option.splits) apply (intro conjI) apply (clarsimp simp:user_pointer_at_def Let_def) apply (clarsimp simp:sep_conj_assoc) apply (sep_solve) apply (clarsimp dest!: mapu_dest_opt_cap cap_type_null reset_cap_asid_simps2[OF sym] simp: cap_type_def) apply (sep_solve) done crunch preserve [wp]: decode_cnode_invocation "P" (wp: derive_cap_wpE unlessE_wp hoare_whenE_wp select_wp hoare_drop_imps simp: if_apply_def2 throw_on_none_def) lemma decode_invocation_wp: "\P\ decode_invocation (CNodeCap x y z sz) ref caps (CNodeIntent intent) \\_. P\, -" apply (clarsimp simp: decode_invocation_def) apply (wp) apply (clarsimp simp: comp_def) apply (wpsimp simp: throw_opt_def)+ done lemma lookup_slot_wp: "\P\ lookup_slot cnode_ptr ptr \\_. P\, \\_. P\" apply (clarsimp simp: lookup_slot_def) apply (clarsimp simp: gets_the_resolve_cap[symmetric] split_def) apply (wp get_cap_wp) apply (clarsimp) done lemma always_empty_wp: "\c - \* R>\ always_empty_slot ptr \\_. < ptr \c NullCap \* R>\" by (clarsimp simp: always_empty_slot_def, wp remove_parent_wp set_cap_wp) lemma fast_finalise_cap_non_ep_wp: "\

and K (\ ep_related_cap cap') \ fast_finalise cap' final \\y.

\" by (case_tac cap',simp_all add:ep_related_cap_def) crunch inv [wp]: is_final_cap "\s. P" (wp:crunch_wps select_wp simp:split_def unless_def) lemma delete_cap_simple_wp: "\\s. c cap \* R> s \ \ ep_related_cap cap\ delete_cap_simple ptr \\_. < ptr \c NullCap \* R>\" apply (clarsimp simp: delete_cap_simple_def is_final_cap_def) apply (wp hoare_unless_wp always_empty_wp fast_finalise_cap_non_ep_wp) apply clarsimp apply (frule opt_cap_sep_imp) apply (clarsimp, rule conjI) apply clarsimp apply (metis reset_cap_asid_simps2(1)) apply clarsimp apply (rule conjI) apply sep_solve apply (metis reset_cap_asid_ep_related_cap) done lemma is_cnode_cap_has_object [simp]: "is_cnode_cap cnode_cap \ cap_has_object cnode_cap" by (clarsimp simp: cap_type_def cap_has_object_def split: cdl_cap.splits) (* MOVEME *) lemma K_extract: "(K P \* Q) s \ P" by (auto simp: sep_conj_def) lemmas K_extract' = K_extract [simplified K_def] lemma user_pointer_at_cnode_cap': "(\ (r, word_bits) : cnode_cap cap_ptr \u cap') s \ is_cnode_cap cnode_cap" by (clarsimp simp: user_pointer_at_def Let_unfold) lemma user_pointer_at_cnode_cap: "(\ (r, word_bits) : cnode_cap cap_ptr \u cap' \* R) s \ is_cnode_cap cnode_cap" by (drule sep_conj_impl, erule user_pointer_at_cnode_cap', assumption+, erule K_extract') lemma lookup_slot_rvu: "\\s. Q (cap_object cnode_cap, offset cap_ptr r) s \ < (thread,tcb_cspace_slot) \c cnode_cap \* \ (r, word_bits) : cnode_cap cap_ptr \u cap' \* R> s\ lookup_slot thread cap_ptr \Q\, \Q'\ " apply (clarsimp simp: lookup_slot_def gets_the_resolve_cap[symmetric] split_def) apply (rule hoare_vcg_seqE)+ apply (rule returnOk_wp) apply (rule resolve_cap_u_nf [where r=r]) apply (rule hoare_pre, wp) apply (clarsimp simp: mapu_dest_opt_cap) apply (sep_frule (direct) opt_cap_sep_imp ) apply (sep_frule (direct) user_pointer_at_cnode_cap) apply (clarsimp) apply (frule (1) reset_cap_asid_cnode_cap) apply fastforce done lemma lookup_cap_rvu : "\\s. (\c. reset_cap_asid c = reset_cap_asid cap' \ Q c s) \ < (thread,tcb_cspace_slot) \c cnode_cap \* \ (r, word_bits) : cnode_cap cap_ptr \u cap' \* R> s\ lookup_cap thread cap_ptr \Q\, \\_ _. False\" apply (clarsimp simp: lookup_cap_def) using hoare_vcg_prop[wp del] apply (wp lookup_slot_rvu [where cnode_cap=cnode_cap] get_cap_rv) apply (clarsimp) apply safe apply (clarsimp simp: user_pointer_at_def sep_conj_assoc Let_unfold) apply (sep_solve) apply clarsimp apply sep_solve done lemma lookup_cap_wp: "\P\ lookup_cap thread cap_ptr \\_. P\, \\_ .P \ " apply (clarsimp simp: lookup_cap_def) apply (wp lookup_slot_wp get_cap_wp) apply (clarsimp) apply (wp lookup_slot_wp) apply assumption done lemma lookup_cap_and_slot_rvu: "\\s. (\c. reset_cap_asid c = reset_cap_asid cap' \ Q (c, (cap_object cap, offset cap_ptr r) ) s) \ < (thread,tcb_cspace_slot) \c cap \* \ (r, word_bits) : cap cap_ptr \u cap' \* R> s\ lookup_cap_and_slot thread cap_ptr \Q\, \Q'\ " apply (clarsimp simp: lookup_cap_and_slot_def) apply (rule hoare_vcg_seqE)+ apply (rule returnOk_wp) apply (wp get_cap_rv) apply (rule hoare_pre, wp lookup_slot_rvu) apply (safe) apply (clarsimp simp: user_pointer_at_def Let_unfold sep.mult_assoc) apply sep_solve apply clarsimp apply fastforce done lemma update_cap_data: "\\s. valid_src_cap cap badge \ cap_has_type cap \ ((is_ep_cap cap \ is_ntfn_cap cap) \ \ preserve \ cap_badge cap = 0) \ Q (update_cap_data_det badge cap) s \ update_cap_data preserve badge cap \\rv s. Q rv s\" apply (rule hoare_name_pre_state) apply (clarsimp simp: Let_def update_cap_data_def update_cap_data_det_def valid_src_cap_def cnode_cap_size_def ep_related_cap_def guard_update_def split: cdl_cap.splits | wp)+ done lemma is_exclusive_cap_update_cap_data: "safe_for_derive (update_cap_data_det badge cap) = safe_for_derive cap" apply (rule iffI) apply (simp_all add: safe_for_derive_def update_cap_data_def update_cap_data_det_def) apply (case_tac cap, simp_all add: safe_for_derive_def badge_update_def split: if_split_asm) apply (case_tac cap, simp_all add: badge_update_def guard_update_def update_cap_badge_def split: if_split_asm) done lemma cap_object_update_cap_rights: "cap_object (update_cap_rights rights src_cap) = cap_object src_cap" apply (simp add: cap_object_def update_cap_rights_def split: cdl_cap.splits) done lemma derived_cap_update_cap_data_det_NullCap [simp]: "(derived_cap (update_cap_data_det badge cap) = NullCap) = (derived_cap cap = NullCap)" by (clarsimp simp: derived_cap_def update_cap_data_det_def badge_update_def update_cap_badge_def guard_update_def split: cdl_cap.splits if_split_asm) lemma derived_cap_update_cap_rights_NullCap [simp]: "(derived_cap (update_cap_rights rights cap) = NullCap) = (derived_cap cap = NullCap)" by (clarsimp simp: derived_cap_def update_cap_rights_def split: cdl_cap.splits if_split_asm) lemma derived_cap_reset_cap_asid_NullCap: "\reset_cap_asid cap = reset_cap_asid cap'; derived_cap cap = NullCap\ \ derived_cap cap' = NullCap" by (clarsimp simp: derived_cap_def reset_cap_asid_def split: cdl_cap.splits) lemma derived_cap_update_cap_data_det: "derived_cap (update_cap_data_det badge cap) = update_cap_data_det badge (derived_cap cap)" apply (clarsimp simp: derived_cap_def update_cap_data_det_def) apply (case_tac cap, simp_all add: update_cap_data_det_def badge_update_def derived_cap_def update_cap_badge_def guard_update_def) done lemma cnode_cap_size_upd_cap_rights[simp]: "is_cnode_cap src_cap \ cnode_cap_size (update_cap_rights rights src_cap) = cnode_cap_size src_cap" by (simp add: update_cap_rights_def cnode_cap_size_def split: cdl_cap.splits) lemma has_type_default_not_non: "cap_type spec_cap = Some type \ default_cap type ids sz dev \ NullCap" by (clarsimp simp: default_cap_def cap_type_def split: cdl_cap.splits) lemma ep_related_cap_default_cap: "cap_type cap = Some type \ ep_related_cap (default_cap type ids sz dev) = ep_related_cap cap" by (fastforce simp: cap_type_def ep_related_cap_def default_cap_def split: cdl_cap.splits cdl_object_type.splits) lemma cap_has_type_update_rights[simp]: "cap_has_type (update_cap_rights rights cap) = cap_has_type cap" by (clarsimp simp: cap_type_def update_cap_rights_def split: cdl_cap.splits) lemma cap_has_type_asid_cong: "reset_cap_asid cap' = reset_cap_asid src_cap \ cap_has_type cap' = cap_has_type src_cap" by (drule reset_cap_asid_cap_type, simp) (* FIXME: MOVE *) fun is_reply_cap where "is_reply_cap (ReplyCap _ _) = True" | "is_reply_cap _ = False" lemma ep_related_capI: "is_ep_cap cap \ ep_related_cap cap" "is_ntfn_cap cap \ ep_related_cap cap" "is_reply_cap cap \ ep_related_cap cap" by (cases cap; simp add: ep_related_cap_def cap_type_def)+ lemma decode_cnode_mint_rvu: "\\s. caps \ [] \ cap_has_type src_cap \ valid_src_cap src_cap badge \ ((is_ep_cap src_cap \ is_ntfn_cap src_cap) \ cap_badge src_cap = 0) \ (\src_cap'. (reset_cap_asid src_cap' = reset_cap_asid src_cap) \ (let x = update_cap_data_det badge (update_cap_rights (cap_rights src_cap \ rights) src_cap') in Q (InsertCall (derived_cap x) (cap_object (fst $ the $ get_index caps 0), offset src_index src_sz) (cap_object target, offset dest_index dest_sz)) s )) \ unat src_depth \ word_bits \ 0 < unat src_depth \ unat dest_depth \ word_bits \ 0 < unat dest_depth \ < \ (src_sz, (unat src_depth)): (fst (the $ get_index caps 0)) src_index \u src_cap \* \ (dest_sz, (unat dest_depth)): target dest_index \u NullCap \* R> s \ Q' s \ decode_cnode_invocation target target_ref caps (CNodeMintIntent dest_index dest_depth src_index src_depth rights badge) \\rv s. Q rv s\, \\r. Q'\" apply (unfold validE_def) apply (rule hoare_name_pre_state) apply (unfold validE_def[symmetric]) apply (clarsimp simp: neq_Nil_conv decode_cnode_invocation_def split_def split: sum.splits) apply (wp derive_cap_invE) apply (wp update_cap_data)+ apply (rule validE_validE_R) apply (simp add: if_apply_def2) apply (rule lookup_slot_for_cnode_op_rvu' [where r=src_sz and cap=src_cap and R="\ (dest_sz, (unat dest_depth)): target dest_index \u NullCap \* R"]) apply simp apply (rule ensure_empty_no_exception) apply (rule_tac R="\ (src_sz, (unat src_depth)): a src_index \u src_cap \* R" in lookup_slot_for_cnode_op_rvu'[where r=dest_sz and cap=NullCap]) apply (simp, wp throw_on_none_rv validE_R_validE) apply (clarsimp simp:Let_def get_index_def split: option.splits cong:cap_rights_reset_cap_asid cap_object_reset_cap_asid) apply (intro conjI) apply (clarsimp simp:user_pointer_at_def Let_def) apply (clarsimp simp:sep_conj_assoc) apply (sep_erule sep_cancel, assumption) apply (clarsimp dest!: mapu_dest_opt_cap simp:conj_comms is_exclusive_cap_update_cap_data safe_for_derive_not_non valid_src_cap_def) apply (intro conjI impI allI) apply (metis reset_cap_asid_cap_type) apply (frule (1) reset_cap_asid_ep_cap[THEN iffD1]) apply simp apply (metis reset_cap_asid_cap_badge ep_related_capI) apply (frule (1) reset_cap_asid_ntfn_cap[THEN iffD1]) apply simp apply (metis reset_cap_asid_cap_badge ep_related_capI) apply (metis option.inject reset_cap_asid_cnode_cap) apply (metis cap_rights_reset_cap_asid) apply sep_solve done lemma non_cap_cong: "reset_cap_asid cap' = reset_cap_asid src_cap \ (cap' = NullCap) = (src_cap = NullCap)" by (rule iffI,simp_all add:reset_cap_asid_def split:cdl_cap.splits) lemma update_cap_data_non: "(update_cap_data_det badge cap' = NullCap) = (cap' = NullCap)" by (rule iffI, simp_all add: update_cap_data_det_def badge_update_def guard_update_def update_cap_badge_def split: cdl_cap.splits if_split_asm) lemma decode_cnode_mutate_rvu: "\\s. caps \ [] \ < \ (src_sz, (unat src_depth)): (fst (the $ get_index caps 0)) src_index \u src_cap \* \ (dest_sz, (unat dest_depth)): target dest_index \u NullCap \* R> s \ valid_src_cap src_cap badge \ \ ep_related_cap src_cap \ cap_has_type src_cap \ unat src_depth \ word_bits \ 0 < unat src_depth \ unat dest_depth \ word_bits \ 0 < unat dest_depth \ (\src_cap'. reset_cap_asid src_cap' = reset_cap_asid src_cap \ Q (MoveCall (update_cap_data_det badge src_cap') (cap_object (fst (the $ get_index caps 0)), offset src_index src_sz) (cap_object target, offset dest_index dest_sz)) s)\ decode_cnode_invocation target target_ref caps (CNodeMutateIntent dest_index dest_depth src_index src_depth badge) \\rv s. Q rv s\, \Q'\" apply (unfold validE_def) apply (rule hoare_name_pre_state) apply (unfold validE_def[symmetric]) apply clarsimp apply (frule cap_type_null) apply (clarsimp simp: decode_cnode_invocation_def split_def neq_Nil_conv split:sum.splits) apply wp apply (wp update_cap_data)+ apply (simp add: if_apply_def2) apply (rule lookup_slot_for_cnode_op_rvu' [where r=src_sz and cap=src_cap and R="\ (dest_sz, (unat dest_depth)): target dest_index \u NullCap \* R"]) apply simp apply (rule ensure_empty_no_exception) apply (rule_tac R="\ (src_sz, (unat src_depth)): a src_index \u src_cap \* R" in lookup_slot_for_cnode_op_rvu'[where r=dest_sz and cap=NullCap]) apply (simp, wp throw_on_none_rv validE_R_validE) apply (clarsimp simp:Let_def get_index_def split: option.splits) apply (intro conjI) apply (clarsimp simp:user_pointer_at_def Let_def) apply (clarsimp simp:sep_conj_assoc) apply (sep_solve) apply (clarsimp dest!: mapu_dest_opt_cap simp: conj_comms update_cap_data_non cong:non_cap_cong) apply (subst (asm) reset_cap_asid_ep_related_cap[OF sym], assumption) apply (metis reset_cap_asid_cap_type reset_cap_asid_ep_related_cap valid_src_cap_asid_cong ep_related_capI) apply sep_solve done crunch preserve [wp]: decode_cnode_invocation "P" (wp: derive_cap_wpE unlessE_wp hoare_whenE_wp select_wp hoare_drop_imps simp: hoare_if_simpE if_apply_def2 throw_on_none_def) lemma do_kernel_op_pull_back: "\\s. P s\ oper \\r. Q r\ \ \\s. P (kernel_state s)\ do_kernel_op oper \\r s. Q r (kernel_state s)\" apply (simp add:do_kernel_op_def) apply (wp|wpc)+ apply (auto simp:valid_def) done lemma get_thread_sep_wp: "\tcb_at' Q thread\ get_thread thread \\rv s. Q rv\" apply (simp add: get_thread_def | wp | wpc)+ apply (auto simp: object_at_def) done lemma get_thread_inv: "\ Q \ get_thread thread \\t s. Q s\" by (simp add:get_thread_def | wp | wpc)+ lemma get_thread_sep_wp_precise: "\\s. tcb_at' (\tcb. Q tcb s) thread s \ get_thread thread \\rv. Q rv\" apply (simp add:get_thread_def | wp | wpc)+ apply (auto simp: object_at_def) done (* We are not interested in ep related invocation *) definition nonep_invocation :: "cdl_invocation \ bool" where "nonep_invocation iv \ case iv of InvokeEndpoint cdl_endpoint_invocation \ False | InvokeNotification cdl_notification_invocation \ False | InvokeReply cdl_reply_invocation \ False | _ \ True" lemma has_restart_cap_sep_wp: "\\s. < (thread,tcb_pending_op_slot) \c cap \* sep_true> s \ Q (cap = RestartCap) s\ has_restart_cap thread \\rv. Q rv\" apply (rule hoare_name_pre_state) apply (clarsimp simp: object_at_def) apply (simp add: object_at_def get_thread_def has_restart_cap_def | wp+ | wpc | intro conjI)+ apply (clarsimp dest!: opt_cap_sep_imp simp: opt_cap_def slots_of_def) apply (clarsimp simp: object_slots_def) apply (erule rsubst) apply (clarsimp simp: reset_cap_asid_def split: cdl_cap.splits) done lemma lift_do_kernel_op': "\\s'. P s'\ f \\_ s'. Q s'\ \ \\s. P (kernel_state s)\ do_kernel_op f \\_ s. Q (kernel_state s)\" apply (simp add: do_kernel_op_def split_def) apply (wp select_wp) apply (simp add: valid_def split_def) done lemma lift_do_kernel_op: "\\s. s = s'\ f \\_ s. s = s'\ \ \\s. (kernel_state s) = s'\ do_kernel_op f \\_ s. (kernel_state s) = s'\" apply (simp add: do_kernel_op_def split_def) apply (wp select_wp) apply (simp add: valid_def split_def) done lemma switch_to_thread_wp: "\\s. P (cdl_objects s)\ switch_to_thread t \\r s. P (cdl_objects s)\" by (wpsimp simp: switch_to_thread_def) lemma switch_to_thread_current_thread_wp: "\\s. P t\ switch_to_thread t \\r s. P (cdl_current_thread s)\" by (wpsimp simp: switch_to_thread_def) lemma schedule_no_choice_wp: "\\s. cdl_current_thread s = Some current_thread \ cdl_current_domain s = current_domain \ P s \ schedule \\r s. cdl_current_thread s = Some current_thread \ cdl_current_domain s = current_domain \ P s\" apply (simp add:schedule_def switch_to_thread_def change_current_domain_def) apply (wp alternative_wp select_wp) apply (case_tac s,clarsimp) done end