(* * Copyright 2014, General Dynamics C4 Systems * * SPDX-License-Identifier: GPL-2.0-only *) theory KHeapPre_AI imports Machine_AI begin primrec same_caps :: "Structures_A.kernel_object \ Structures_A.kernel_object \ bool" where "same_caps val (CNode sz cs) = (val = CNode sz cs)" | "same_caps val (TCB tcb) = (\tcb'. val = TCB tcb' \ (\(getF, t) \ ran tcb_cap_cases. getF tcb' = getF tcb))" | "same_caps val (Endpoint ep) = is_ep val" | "same_caps val (Notification ntfn) = is_ntfn val" | "same_caps val (ArchObj ao) = (\ao'. val = ArchObj ao')" lemma same_caps_more_simps[simp]: "same_caps (CNode sz cs) val = (val = CNode sz cs)" "same_caps (TCB tcb) val = (\tcb'. val = TCB tcb' \ (\(getF, t) \ ran tcb_cap_cases. getF tcb' = getF tcb))" "same_caps (Endpoint ep) val = is_ep val" "same_caps (Notification ntfn) val = is_ntfn val" "same_caps (ArchObj ao) val = (\ao'. val = ArchObj ao')" by (cases val, (fastforce simp: is_obj_defs)+)+ lemma dmo_return [simp]: "do_machine_op (return x) = return x" by (simp add: do_machine_op_def select_f_def return_def gets_def get_def bind_def modify_def put_def) lemma get_object_sp: "\P\ get_object p \\r. P and ko_at r p\" apply (simp add: get_object_def) apply wp apply (auto simp add: obj_at_def) done definition non_arch_obj :: "kernel_object \ bool" where "non_arch_obj \ \ko. \ako. ko \ ArchObj ako" lemma non_arch_objs[intro]: "non_arch_obj (Endpoint ep)" "non_arch_obj (CNode sz cnode_contents)" "non_arch_obj (TCB tcb)" "non_arch_obj (Notification notification)" by (auto simp add: non_arch_obj_def) definition arch_obj_pred :: "(kernel_object \ bool) \ bool" where "arch_obj_pred P \ \ko ko'. non_arch_obj ko \ non_arch_obj ko' \ P ko = P ko'" lemma arch_obj_predE: "\arch_obj_pred P; non_arch_obj ko; non_arch_obj ko'\ \ P ko = P ko'" apply (unfold arch_obj_pred_def) apply (erule allE[where ?x="ko"]) apply (erule allE[where ?x="ko'"]) by blast lemmas arch_obj_pred_defs = non_arch_obj_def arch_obj_pred_def lemma arch_obj_pred_a_type[intro, simp]: "arch_obj_pred (\ko. a_type ko = AArch T)" by (auto simp add: arch_obj_pred_defs a_type_def split: kernel_object.splits) lemma arch_obj_pred_arch_obj_l[intro, simp]: "arch_obj_pred (\ko. ArchObj ako = ko)" and arch_obj_pred_arch_obj_r[intro, simp]: "arch_obj_pred (\ko. ko = ArchObj ako)" by (auto simp add: arch_obj_pred_defs) lemma arch_obj_pred_fun_lift: "arch_obj_pred (\ko. F (arch_obj_fun_lift P N ko))" by (simp add: arch_obj_pred_defs) lemmas arch_obj_pred_fun_lift_id[simp] = arch_obj_pred_fun_lift[where F=id, simplified] lemmas arch_obj_pred_fun_lift_k[intro] = arch_obj_pred_fun_lift[where F="K R" for R, simplified] lemmas arch_obj_pred_fun_lift_el[simp] = arch_obj_pred_fun_lift[where F="\ S. x \ S" for x, simplified] lemma arch_obj_pred_const_conjI[intro]: "arch_obj_pred P \ arch_obj_pred P' \ arch_obj_pred (\ko. P ko \ P' ko)" apply (simp only: arch_obj_pred_def) apply blast done lemma arch_obj_pred_fI: "(\x. arch_obj_pred (P x)) \ arch_obj_pred (\ko. f (\x :: 'a :: type. P x ko))" apply (simp only: arch_obj_pred_def) apply (intro allI impI) apply (rule arg_cong[where f=f]) by blast declare arch_obj_pred_fI[where f=All, intro] arch_obj_pred_fI[where f=Ex, intro] locale arch_only_obj_pred = fixes P :: "kernel_object \ bool" assumes arch_only: "arch_obj_pred P" lemma set_object_typ_at [wp]: "\\s. P (typ_at T p' s)\ set_object p ko \\rv s. P (typ_at T p' s)\" apply (simp add: set_object_def get_object_def) apply wp apply clarsimp apply (erule rsubst [where P=P]) apply (clarsimp simp: obj_at_def) done lemma set_object_neg_ko: "\not ko_at ko' p' and K (p = p' \ ko \ ko')\ set_object p ko \\_ s. \ ko_at ko' p' s\" apply (simp add: set_object_def get_object_def) apply wp apply (simp add: pred_neg_def obj_at_def) done lemma get_tcb_SomeD: "get_tcb t s = Some v \ kheap s t = Some (TCB v)" apply (case_tac "kheap s t", simp_all add: get_tcb_def) apply (case_tac a, simp_all) done lemma get_tcb_at: "tcb_at t s \ (\tcb. get_tcb t s = Some tcb)" by (simp add: tcb_at_def) lemma typ_at_same_type: assumes "typ_at T p s" "a_type k = a_type ko" "kheap s p' = Some ko" shows "typ_at T p (s\kheap := kheap s(p' \ k)\)" using assms by (clarsimp simp: obj_at_def) lemma hoare_to_pure_kheap_upd: assumes hoare[rule_format]: "\f. (\P p T. \\s. P (typ_at (AArch T) p s)\ f \\r s. P (typ_at (AArch T) p s)\) \ \P\ f \\_. P\" assumes typ_eq: "a_type k = a_type ko" assumes valid: "P (s :: ('z :: state_ext) state)" assumes at: "ko_at ko p s" shows "P (s\kheap := kheap s(p \ k)\)" apply (rule use_valid[where f=" do s' <- get; assert (s' = s); (modify (\s. s\kheap := kheap s(p \ k)\)); return undefined od", OF _ hoare valid]) apply (fastforce simp add: simpler_modify_def get_def bind_def assert_def return_def[abs_def] fail_def)[1] apply wp apply (insert typ_eq at) apply clarsimp apply (erule_tac P=P in rsubst) by (auto simp add: obj_at_def a_type_def split: kernel_object.splits if_splits) lemma set_object_wp: "\\s. Q (s\ kheap := kheap s (p \ v)\) \ set_object p v \\_. Q\" apply (simp add: set_object_def get_object_def) apply wp apply blast done lemma get_object_wp: "\\s. \ko. ko_at ko p s \ Q ko s\ get_object p \Q\" apply (clarsimp simp: get_object_def) apply wp apply (clarsimp simp: obj_at_def) done (* FIXME: move *) lemma hoare_strengthen_pre_via_assert_forward: assumes pos: "\ P \ f \ Q \" assumes rel: "\s. S s \ P s \ N s" assumes neg: "\ N \ f \ \\ \" shows "\ S \ f \ Q \" apply (rule hoare_weaken_pre) apply (rule hoare_strengthen_post) apply (rule hoare_vcg_disj_lift[OF pos neg]) apply simp apply (erule rel) done lemma hoare_set_object_weaken_pre: assumes "\P\ set_object p v \\_. Q\" shows "\\s. \ko. ko_at ko p s \ (a_type v = a_type ko) \ P s\ set_object p v \\_. Q\" apply (rule hoare_strengthen_pre_via_assert_forward [OF assms, where N="\s. \ko. ko_at ko p s \ a_type ko \ a_type v"]) apply fastforce apply (simp add: set_object_def) apply (rule hoare_seq_ext[OF _ get_object_sp]) apply (rule hoare_seq_ext[OF _ assert_sp]) apply (fastforce intro: hoare_weaken_pre[OF hoare_pre_cont]) done lemmas set_object_wp_strong = hoare_set_object_weaken_pre[OF set_object_wp] end