lemma lense_ucast_signed: "lense (unsigned :: 'a::len word ==> 'a signed word) (λv x. unsigned (v (unsigned x)))" by (rule lenseI_equiv) (simp_all add: ucast_ucast_id)
lemma pointer_lense_ucast_signed: fixes r :: "'h ==> 'a::len8 word ptr ==> 'a word" assumes"pointer_lense r w" shows"pointer_lense (λh p. UCAST('a → 'a signed) (r h (PTR_COERCE('a signed word → 'a word) p))) (λp m. w (PTR_COERCE('a signed word → 'a word) p) (λw. UCAST('a signed → 'a) (m (UCAST('a → 'a signed) w))))" proof - interpret pointer_lense r w by fact note scast_ucast_norm[simp del] note ucast_ucast_id[simp] show ?thesis apply unfold_locales apply (simp add: read_write_same) apply (simp add: write_same) apply (simp add: comp_def) apply (simp add: write_other_commute typ_uinfo_t_signed_word_word_conv
flip: size_of_tag typ_uinfo_size) done qed
lemma (in xmem_type) length_to_bytes: "length (to_bytes (v::'a) bs) = size_of TYPE('a)" by (simp add: to_bytes_def lense.access_result_size)
lemma (in xmem_type) heap_update_padding_eq: "length bs = size_of TYPE('a) ==> heap_update_padding p v bs h = heap_update p v (heap_update_list (ptr_val p) bs h)" using u.max_size by (simp add: heap_update_padding_def heap_update_def size_of_def
heap_list_heap_update_list_id heap_update_list_overwrite)
lemma (in xmem_type) heap_update_padding_eq': "length bs = size_of TYPE('a) ==> heap_update_padding p v bs = heap_update p v ∘ heap_update_list (ptr_val p) bs" by (simp add: fun_eq_iff heap_update_padding_eq)
lemma split_disj_asm: "P (x ∨ y) = (¬ (x ∧¬ P x ∨¬ x ∧¬ P y))" by (smt (verit, best))
lemma comp_commute_of_fold: assumes x: "x = fold f xs" assumes xs: "list_all (λx. f x o a = a o f x) xs" shows"x o a = a o x" unfolding x using xs by (induction xs) (simp_all add: fun_eq_iff)
definition padding_closed_under_all_fields where "padding_closed_under_all_fields t ⟷ (∀s f n bs bs'. field_lookup t f 0 = Some (s, n) ⟶ eq_upto_padding t bs bs' ⟶ eq_upto_padding s (take (size_td s) (drop n bs)) (take (size_td s) (drop n bs')))"
lemma padding_closed_under_all_fields_typ_uinfo_t: "padding_closed_under_all_fields (typ_uinfo_t TYPE('a::xmem_type))" unfolding padding_closed_under_all_fields_def proof safe fix s f n bs bs' assume s_n: "field_lookup (typ_uinfo_t TYPE('a)) f 0 = Some (s, n)" and bs_bs': "eq_upto_padding (typ_uinfo_t TYPE('a)) bs bs'" thenhave len: "length bs = size_of TYPE('a)""length bs' = size_of TYPE('a) " by (auto simp: eq_upto_padding_def size_of_def)
from s_n[THEN field_lookup_uinfo_Some_rev] obtain k where
k: "field_lookup (typ_info_t TYPE('a)) f 0 = Some (k, n)"and k_s: "export_uinfo k = s" by auto have [simp]: "size_td k = size_td s"by (simp flip: k_s) from xmem_type_field_lookup_eq_upto_padding_focus[OF k len bs_bs'] show"eq_upto_padding s (take (size_td s) (drop n bs)) (take (size_td s) (drop n bs'))" unfolding k_s by simp qed
lemma (in open_types) plift_heap_update_list_eq_upto_padding: assumes t: "mem_type_u t"and t': "padding_closed_under_all_fields t" assumes a: "ptr_valid_u t (hrs_htd h) a" assumes bs_bs': "eq_upto_padding t bs bs'" shows"plift (hrs_mem_update (heap_update_list a bs) h) = (plift (hrs_mem_update (heap_update_list a bs') h)::'a::xmem_type ptr ==> 'a option)" apply (rule plift_eq_plift, simp_all add: h_val_def hrs_mem_update) proof - from bs_bs' have [simp]: "length bs = size_td t""length bs' = size_td t" by (simp_all add: eq_upto_padding_def) have [arith]: "size_td t < addr_card" using mem_type_u.max_size[OF t] by simp have a_bnd: "size_of TYPE('a) ≤ addr_card" using max_size[where 'a='a] by arith let ?A = "typ_uinfo_t TYPE('a)"
fix p :: "'a ptr"assume p: "ptr_valid (hrs_htd h) p" from ptr_valid_u_cases_weak[OF t a this[unfolded ptr_valid_def]] show"from_bytes (heap_list (heap_update_list a bs (hrs_mem h)) (size_of TYPE('a)) (ptr_val p)) = (from_bytes (heap_list (heap_update_list a bs' (hrs_mem h)) (size_of TYPE('a)) (ptr_val p))::'a)" proof (elim disjE exE conjE) assume"disjnt {a..+size_td t} {ptr_val p..+size_td (typ_uinfo_t TYPE('a))}" with bs_bs' show ?thesis unfolding heap_upd_list_def by (subst (12) heap_list_update_disjoint_same; simp add: size_of_def disjnt_def) next fix path assume path: "addressable_field t path ?A"and
p_eq: "ptr_val p = a + word_of_nat (field_offset_untyped t path)" let ?n = "field_offset_untyped t path" have sz: "size_of TYPE('a) + ?n ≤ size_td t" using field_lookup_offset_size'[OF addressable_fieldD_field_lookup'[OF path]] by (simp add: size_of_def) let ?s = "typ_uinfo_t TYPE('a)" from addressable_fieldD_field_lookup'[OF path] t' bs_bs' have *: "eq_upto_padding ?s (take (size_td ?s) (drop ?n bs)) (take (size_td ?s) (drop ?n bs'))" unfolding padding_closed_under_all_fields_def by (auto simp flip: typ_uinfo_size)
show ?thesis unfolding p_eq using eq_upto_padding_from_bytes_eq[OF *] sz apply (subst (12) heap_list_update_list) apply (simp_all add: size_of_def) done next fix path assume path: "addressable_field ?A path t" and p_eq: "a = ptr_val p + word_of_nat (field_offset_untyped ?A path)" let ?n = "field_offset_untyped ?A path" have sz: "size_td t + ?n ≤ size_of TYPE('a)" using field_lookup_offset_size'[OF addressable_fieldD_field_lookup'[OF path]] by (simp add: size_of_def) from field_lookup_uinfo_Some_rev[OF addressable_fieldD_field_lookup'[OF path]] obtain k where k: "field_lookup (typ_info_t TYPE('a)) path 0 = Some (k, ?n)" and eq_t: "export_uinfo k = t"by blast thenhave [simp]: "size_td k = size_td t" by (simp flip: eq_t)
lemma admissible_nondet_ord_L2Tcorres [corres_admissible]: "ccpo.admissible Inf (≥) (λA. L2Tcorres st A C)" unfolding L2Tcorres_def apply (rule admissible_nondet_ord_corresXF) done
lemma admissible_nondet_ord_L2Tcorres_mcont: "mcont Inf (≥) Inf (≥) F ==> ccpo.admissible Inf (≥) (λA. L2Tcorres st (F A) C)" using admissible_nondet_ord_L2Tcorres apply (rule admissible_subst) apply assumption done
lemma L2Tcorres_top [corres_top]: "L2Tcorres st ⊤ C" by (auto simp add: L2Tcorres_def corresXF_def)
lemma L2Tcorres_le_trans[corres_le_trans]: "L2Tcorres st A C ==> A ≤ A' ==> L2Tcorres st A' C" by (auto simp add: L2Tcorres_def corres_le_trans)
(* Abstraction predicates for inner expressions. *) definition"abs_guard st A C ≡∀s. A (st s) ⟶ C s" definition"abs_expr st P A C ≡∀s. P (st s) ⟶ C s = A (st s)" definition"abs_modifies st P A C ≡∀s. P (st s) ⟶ st (C s) = A (st s)"
(* Predicates to enable some transformations on the input expressions (namely,rewritingusesoffield_lvalue)thatarebestdone asapreprocessingstage(st=id). ThecorresTArulesshouldensurethattheseareusedtorewrite
any inner expressions before handing off to the predicates above. *) definition"struct_rewrite_guard A C ≡∀s. A s ⟶ C s" definition"struct_rewrite_expr P A C ≡∀s. P s ⟶ C s = A s" definition"struct_rewrite_modifies P A C ≡∀s. P s ⟶ C s = A s"
(* Standard heap abstraction rules. *)
named_theorems heap_abs and more_heap_abs (* Rules that require first-order matching. *)
named_theorems heap_abs_fo
named_theorems derived_heap_defs and
valid_array_defs and
heap_upd_cong and
valid_same_typ_descs
locale heap_abs_known_function_upto = fixes st:: "'s ==> 't" fixes known_function_upto_prev:: "unit ptr ==> bool" fixes known_function_upto_hl:: "unit ptr ==> bool" assumes strengthen: "∧p. known_function_upto_hl p ==> known_function_upto_prev p" begin lemma abs_guard_known_function_upto [more_heap_abs]: "abs_guard st (λ_. known_function_upto_hl p) (λ_. known_function_upto_prev p)" by (auto simp add: strengthen abs_guard_def) end
lemma deepen_heap_upd_cong: "f = f' ==> upd f s = upd f' s" by simp
lemma deepen_heap_map_cong: "f = f' ==> upd f p s = upd f' p s" by simp
(* fun_app2 is like fun_app, but it skips an abstraction. *Weusethisfortermslike"\<lambda>sa.Array.updateak(fs)".
* fixme: ideally, the first order conversion code can skip abstractions. *)
lemma abs_expr_fun_app2 [heap_abs_fo]: "[ abs_expr st P f f'; abs_expr st Q g g' ]==> abs_expr st (λs. P s ∧ Q s) (λs a. f s a (g s a)) (λs a. f' s a $ g' s a)" by (simp add: abs_expr_def)
lemma abs_expr_fun_app [heap_abs_fo]: "[ abs_expr st Y x x'; abs_expr st X f f' ]==> abs_expr st (λs. X s ∧ Y s) (λs. f s (x s)) (λs. f' s $ x' s)" apply (clarsimp simp: abs_expr_def) done
lemma abs_expr_Pair [heap_abs]: " abs_expr st X f1 f1' ==> abs_expr st Y f2 f2' ==> abs_expr st (λs. X s ∧ Y s) (λs. (f1 s, f2 s)) (λs. (f1' s, f2' s))" apply (clarsimp simp: abs_expr_def) done
lemma abs_expr_constant [heap_abs]: "abs_expr st (λ_. True) (λs. a) (λs. a)" apply (clarsimp simp: abs_expr_def) done
lemma abs_guard_expr [heap_abs]: "abs_expr st P a' a ==> abs_guard st (λs. P s ∧ a' s) a" by (simp add: abs_expr_def abs_guard_def)
lemma abs_guard_constant [heap_abs]: "abs_guard st (λ_. P) (λ_. P)" by (clarsimp simp: abs_guard_def)
lemma abs_guard_conj [heap_abs]: "[ abs_guard st G G'; abs_guard st H H' ] ==> abs_guard st (λs. G s ∧ H s) (λs. G' s ∧ H' s)" by (clarsimp simp: abs_guard_def)
lemma L2Tcorres_modify [heap_abs]: "[ struct_rewrite_modifies P b c; abs_guard st P' P; abs_modifies st Q a b ]==> L2Tcorres st (L2_seq (L2_guard (λs. P' s ∧ Q s)) (λ_. (L2_modify a))) (L2_modify c)" apply (auto intro!: refines_bind_guard_right refines_modify
simp: corresXF_refines_conv
L2Tcorres_def L2_defs abs_modifies_def abs_guard_def struct_rewrite_modifies_def struct_rewrite_guard_def) done
lemma L2Tcorres_gets [heap_abs]: "[ struct_rewrite_expr P b c; abs_guard st P' P; abs_expr st Q a b ]==> L2Tcorres st (L2_seq (L2_guard (λs. P' s ∧ Q s)) (λ_. L2_gets a n)) (L2_gets c n)" apply (auto intro!: refines_bind_guard_right refines_gets
simp: corresXF_refines_conv L2Tcorres_def L2_defs abs_expr_def abs_guard_def struct_rewrite_expr_def struct_rewrite_guard_def) done
lemma L2Tcorres_gets_const [heap_abs]: "L2Tcorres st (L2_gets (λ_. a) n) (L2_gets (λ_. a) n)" apply (simp add: corresXF_refines_conv refines_gets L2Tcorres_def L2_defs) done
lemma L2Tcorres_guard [heap_abs]: "[ struct_rewrite_guard b c; abs_guard st a b ]==> L2Tcorres st (L2_guard a) (L2_guard c)" apply (simp add: corresXF_def L2Tcorres_def L2_defs abs_guard_def struct_rewrite_guard_def) done
lemma L2Tcorres_while [heap_abs]: assumes body_corres [simplified THIN_def,rule_format]: "PROP THIN (∧x. L2Tcorres st (B' x) (B x))" and cond_rewrite [simplified THIN_def,rule_format]: "PROP THIN (∧r. struct_rewrite_expr (G r) (C' r) (C r))" and guard_abs[simplified THIN_def,rule_format]: "PROP THIN (∧r. abs_guard st (G' r) (G r))" and guard_impl_cond[simplified THIN_def,rule_format]: "PROP THIN (∧r. abs_expr st (H r) (C'' r) (C' r))" shows"L2Tcorres st (L2_guarded_while (λi s. G' i s ∧ H i s) C'' B' i n) (L2_while C B i n)" proof -
have cond_match: "∧r s. G' r (st s) ∧ H r (st s) ==> C'' r (st s) = C r s" using cond_rewrite guard_abs guard_impl_cond by (clarsimp simp: abs_expr_def abs_guard_def struct_rewrite_expr_def)
have"corresXF st (λr _. r) (λr _. r) (λ_. True) (do { _ ← guard (λs. G' i s ∧ H i s); whileLoop C'' (λi. do { r ← B' i; _ ← guard (λs. G' r s ∧ H r s); return r }) i }) (whileLoop C B i)" apply (rule corresXF_guard_imp) apply (rule corresXF_guarded_while [where P="λ_ _. True"and P'="λ_ _. True"]) apply (clarsimp cong: corresXF_cong) apply (rule corresXF_guard_imp) apply (rule body_corres [unfolded L2Tcorres_def]) apply simp apply (clarsimp simp: cond_match) apply clarsimp apply (simp add: runs_to_partial_def_old split: xval_splits) apply simp apply simp apply simp done
thus ?thesis by (clarsimp simp: L2Tcorres_def L2_defs gets_return top_fun_def) qed
named_theorems abs_spec
definition"abs_spec st P (A :: ('a × 'a) set) (C :: ('c × 'c) set) ≡ (∀s t. P (st s) ⟶ (((s, t) ∈ C) ⟶ ((st s, st t) ∈ A))) ∧ (∀s. P (st s) ⟶ (∃x. (st s, x) ∈ A) ⟶ (∃x. (s, x) ∈ C))"
lemma L2Tcorres_spec [heap_abs]: "[ abs_spec st P A C ] ==> L2Tcorres st (L2_seq (L2_guard P) (λ_. (L2_spec A))) (L2_spec C)" unfolding corresXF_refines_conv L2Tcorres_def L2_defs apply (clarsimp simp add: abs_spec_def) apply (intro refines_bind_guard_right refines_bind_bind_exn_wp refines_state_select) apply (force intro!: refines_select simp add: abs_spec_def split: xval_splits) apply blast done
definition"abs_assume st P (A :: 'a ==> ('b × 'a) set) (C :: 'c ==> ('b × 'c) set) ≡ (∀s t r. P (st s) ⟶ (((r, t) ∈ C s) ⟶ ((r, st t) ∈ A (st s))))"
(* FIXME: replace refines_assume_result_and_state in spec monad *) lemma refines_assume_result_and_state': "refines (assume_result_and_state P) (assume_result_and_state Q) s t R" if"sim_set (λ(v, s) (w, t). R (Result v, s) (Result w, t)) (P s) (Q t)" using that by (force simp: refines_def_old sim_set_def rel_set_def case_prod_unfold)
lemma L2Tcorres_assume [heap_abs]: "[ abs_assume st P A C ] ==> L2Tcorres st (L2_seq (L2_guard P) (λ_. (L2_assume A))) (L2_assume C)" unfolding corresXF_refines_conv L2Tcorres_def L2_defs apply (clarsimp simp add: abs_assume_def) thm refines_mono [OF _ refines_assume_result_and_state] apply (intro refines_bind_guard_right refines_bind_bind_exn_wp refines_assume_result_and_state' ) apply (auto simp add: sim_set_def) done
lemma L2Tcorres_condition [heap_abs]: "[PROP THIN (Trueprop (L2Tcorres st L L')); PROP THIN (Trueprop (L2Tcorres st R R')); PROP THIN (Trueprop (struct_rewrite_expr P C' C)); PROP THIN (Trueprop (abs_guard st P' P)); PROP THIN (Trueprop (abs_expr st Q C'' C'))]==> L2Tcorres st (L2_seq (L2_guard (λs. P' s ∧ Q s)) (λ_. L2_condition C'' L R)) (L2_condition C L' R')" unfolding THIN_def L2_defs L2Tcorres_def corresXF_refines_conv apply clarsimp apply (intro refines_bind_guard_right refines_condition) apply (auto simp add: abs_expr_def abs_guard_def struct_rewrite_expr_def struct_rewrite_guard_def) done
lemma L2Tcorres_seq [heap_abs]: "[PROP THIN (Trueprop (L2Tcorres st L' L)); PROP THIN (∧r. L2Tcorres st (R' r) (R r)) ] ==> L2Tcorres st (L2_seq L' R') (L2_seq L R)" unfolding THIN_def L2_defs L2Tcorres_def corresXF_refines_conv apply clarsimp apply (intro refines_bind_bind_exn_wp)
subgoal for t apply (erule_tac x=t in allE) apply (rule refines_weaken) apply assumption apply (auto split: xval_splits) done done
lemma L2Tcorres_guarded_simple [heap_abs]: assumes b_c: "struct_rewrite_guard b c" assumes a_b: "abs_guard st a b" assumes f_g: "∧s s'. c s ==> a (st s) ==> s' = st s ==> L2Tcorres st f g" shows"L2Tcorres st (L2_guarded a f) (L2_guarded c g)" unfolding L2_guarded_def L2_defs L2Tcorres_def corresXF_refines_conv using b_c a_b f_g by (fastforce simp add: refines_def_old L2Tcorres_def corresXF_refines_conv reaches_bind succeeds_bind
struct_rewrite_guard_def abs_guard_def abs_expr_def split: xval_splits)
lemma L2Tcorres_catch [heap_abs]: "[PROP THIN (Trueprop (L2Tcorres st L L')); PROP THIN (∧r. L2Tcorres st (R r) (R' r)) ]==> L2Tcorres st (L2_catch L R) (L2_catch L' R')" unfolding THIN_def apply (clarsimp simp: L2Tcorres_def L2_defs) apply (rule corresXF_guard_imp) apply (erule corresXF_except [where P'="λx y s. x = y"and Q="λ_. True"]) apply (simp add: corresXF_refines_conv) apply (simp add: runs_to_partial_def_old split: xval_splits) apply simp apply simp done
lemma L2Tcorres_throw [heap_abs]: "L2Tcorres st (L2_throw x n) (L2_throw x n)" apply (clarsimp simp: L2Tcorres_def L2_defs) apply (rule corresXF_throw) apply simp done
lemma L2Tcorres_split [heap_abs]: "[∧x y. L2Tcorres st (P x y) (P' x y) ]==> L2Tcorres st (case a of (x, y) ==> P x y) (case a of (x, y) ==> P' x y)" apply (clarsimp simp: split_def) done
lemma L2Tcorres_seq_unused_result [heap_abs]: "[PROP THIN (Trueprop (L2Tcorres st L L')); PROP THIN (Trueprop (L2Tcorres st R R')) ] ==> L2Tcorres st (L2_seq L (λ_. R)) (L2_seq L' (λ_. R'))" apply (rule L2Tcorres_seq, auto) done
lemma abs_expr_split [heap_abs]: "[∧a b. abs_expr st (P a b) (A a b) (C a b) ] ==> abs_expr st (case r of (a, b) ==> P a b) (case r of (a, b) ==> A a b) (case r of (a, b) ==> C a b)" apply (auto simp: split_def) done
lemma abs_guard_split [heap_abs]: "[∧a b. abs_guard st (A a b) (C a b) ] ==> abs_guard st (case r of (a, b) ==> A a b) (case r of (a, b) ==> C a b)" apply (auto simp: split_def) done
lemma abs_expr_id [heap_abs]: "abs_expr id (λ_. True) A A" apply (clarsimp simp: abs_expr_def) done
lemma abs_expr_lambda_null [heap_abs]: "abs_expr st P A C ==> abs_expr st P (λs r. A s) (λs r. C s)" apply (clarsimp simp: abs_expr_def) done
lemma abs_modify_id [heap_abs]: "abs_modifies id (λ_. True) A A" apply (clarsimp simp: abs_modifies_def) done
lemma corresXF_exec_concrete [intro?]: "corresXF id ret_xf ex_xf P A C ==> corresXF st ret_xf ex_xf P (exec_concrete st A) C" by (force simp add: corresXF_refines_conv refines_def_old reaches_exec_concrete succeeds_exec_concrete_iff split: xval_splits)
lemma L2Tcorres_exec_concrete [heap_abs]: "L2Tcorres id A C ==> L2Tcorres st (exec_concrete st (L2_call A emb ns)) (L2_call C emb ns)" apply (clarsimp simp: L2Tcorres_def L2_call_def map_exn_catch_conv) apply (rule corresXF_exec_concrete) apply (rule CorresXF.corresXF_except [ where P' = "λx y s. x = y"]) apply assumption
subgoal by (auto simp add: corresXF_refines_conv)
subgoal by (auto simp add: runs_to_partial_def_old split: xval_splits)
subgoal by simp done
lemma corresXF_exec_abstract [intro?]: "corresXF st ret_xf ex_xf P A C ==> corresXF id ret_xf ex_xf P (exec_abstract st A) C" by (force simp: corresXF_refines_conv refines_def_old reaches_exec_abstract split: xval_splits)
lemma L2Tcorres_exec_abstract [heap_abs]: "L2Tcorres st A C ==> L2Tcorres id (exec_abstract st (L2_call A emb ns)) (L2_call C emb ns)" apply (clarsimp simp: L2_call_def map_exn_catch_conv L2Tcorres_def) apply (rule corresXF_exec_abstract) apply (rule CorresXF.corresXF_except [ where P' = "λx y s. x = y"]) apply assumption
subgoal by (auto simp add: corresXF_refines_conv)
subgoal by (auto simp add: runs_to_partial_def_old split: xval_splits)
subgoal by simp done
lemma L2Tcorres_call [heap_abs]: "L2Tcorres st A C ==> L2Tcorres st (L2_call A emb ns) (L2_call C emb ns)" unfolding L2Tcorres_def L2_call_def map_exn_catch_conv apply (rule CorresXF.corresXF_except [ where P' = "λx y s. x = y"]) apply assumption
subgoal by (auto simp add: corresXF_refines_conv)
subgoal by (auto simp add: runs_to_partial_def_old split: xval_splits)
subgoal by simp done
named_theorems
valid_implies_c_guard and
read_commutes and
write_commutes and
field_write_commutes and
write_valid_preservation and
lift_heap_update_padding_heap_update_conv
assumes write_padding_commutes[write_commutes]: "v (st s) p ==> length bs = size_of TYPE('a) ==> st (t_hrs_upd (hrs_mem_update (heap_update_padding p x bs)) s) = w p (λ_. x) (st s)"
begin lemma write_commutes[write_commutes]: assumes valid: "v (st s) p" shows"st (t_hrs_upd (hrs_mem_update (heap_update p x)) s) = w p (λ_. x) (st s)" proof - have eq: "hrs_mem_update (heap_update p x) = hrs_mem_update (λh. heap_update_padding p x (heap_list h (size_of TYPE('a)) (ptr_val p)) h)" using heap_update_heap_update_padding_conv by metis
show ?thesis apply (simp only: eq) apply (subst write_padding_commutes [symmetric, where bs="heap_list (hrs_mem (t_hrs s)) (size_of TYPE('a)) (ptr_val p)"]) apply (rule valid) apply clarsimp by (metis (no_types, lifting) heap.upd_cong) qed
lemma lift_heap_update_padding_heap_update_conv[lift_heap_update_padding_heap_update_conv]: "v (st s) p ==> length bs = size_of TYPE('a) ==> st (t_hrs_upd (hrs_mem_update (heap_update_padding p x bs)) s) = st (t_hrs_upd (hrs_mem_update (heap_update p x)) s)" using write_padding_commutes write_commutes by auto
lemma write_commutes_atomic: "∀s p x. v (st s) p ⟶ st (t_hrs_upd (hrs_mem_update (heap_update p x)) s) = w p (λ_. x) (st s)" using write_commutes by blast
end
locale write_preserves_valid = fixes v ::"'t ==> 'a::c_type ptr ==> bool" fixes w :: "'a ptr ==> ('b ==> 'b) ==> 't ==> 't" assumes valid_preserved: "v (w p' f s) p = v s p" begin lemma valid_preserved_pointless[simp]: "v (w p' f s) = v s" by (rule ext) (rule valid_preserved) end
locale valid_only_typ_desc_dependent = fixes t_hrs :: "('s ==> heap_raw_state)" fixes st ::"'s ==> 't" fixes v ::"'t ==> 'a::c_type ptr ==> bool" assumes valid_same_typ_desc [valid_same_typ_descs]: "hrs_htd (t_hrs s) = hrs_htd (t_hrs t) ==> v (st s) p = v (st t) p"
locale heap_typing_simulation =
open_types T + t_hrs: heap_raw_state t_hrs t_hrs_upd + heap_typing_state heap_typing heap_typing_upd for Tand
t_hrs :: "('s ==> heap_raw_state)"and
t_hrs_upd :: "(heap_raw_state ==> heap_raw_state) ==> ('s ==> 's)"and
heap_typing :: "'t ==> heap_typ_desc"and
heap_typing_upd :: "(heap_typ_desc ==> heap_typ_desc) ==> 't ==> 't" + fixes st ::"'s ==> 't" assumes heap_typing_commutes[simp]: "heap_typing (st s) = hrs_htd (t_hrs s)" assumes lift_heap_update_list_stack_byte_independent: "(∧i. i < length bs ==> root_ptr_valid (hrs_htd (t_hrs s)) ((p::stack_byte ptr) +p int i)) ==> st (t_hrs_upd (hrs_mem_update (heap_update_list (ptr_val p) bs)) s) = st s" assumes st_eq_upto_padding: "mem_type_u t ==> padding_closed_under_all_fields t ==> ptr_valid_u t (hrs_htd (t_hrs s)) a ==> eq_upto_padding t bs bs' ==> st (t_hrs_upd (hrs_mem_update (heap_update_list a bs)) s) = st (t_hrs_upd (hrs_mem_update (heap_update_list a bs')) s)" begin
lemma write_simulation_alt: assumes v: "∧s p. v (st s) p ==> ptr_valid (hrs_htd (t_hrs s)) p" assumes *: "∧s (p::'a::xmem_type ptr) x. v (st s) p ==> st (t_hrs_upd (hrs_mem_update (heap_update p x)) s) = w p (λ_. x) (st s)" shows"write_simulation t_hrs t_hrs_upd st v w" proof fix s p x and bs :: "byte list"assume p: "v (st s) p"and bs: "length bs = size_of TYPE('a)"
have [simp]: "t_hrs_upd (hrs_mem_update (heap_update p x)) s = t_hrs_upd (hrs_mem_update (heap_update_list (ptr_val p) (to_bytes x (heap_list (hrs_mem (t_hrs s)) (size_of TYPE('a)) (ptr_val p))))) s" by (rule t_hrs.heap.upd_cong) (simp add: heap_update_def)
show"st (t_hrs_upd (hrs_mem_update (heap_update_padding p x bs)) s) = w p (λ_. x) (st s)" apply (subst *[OF p, symmetric]) apply (simp add: heap_update_padding_def[abs_def]) apply (rule st_eq_upto_padding[where t="typ_uinfo_t TYPE('a)"]) apply (rule typ_uinfo_t_mem_type) apply (rule padding_closed_under_all_fields_typ_uinfo_t) apply (subst ptr_valid_def[symmetric]) apply (simp add: v p) unfolding to_bytes_def typ_uinfo_t_def apply (rule field_lookup_access_ti_eq_upto_padding[where f="[]"and 'b='a]) apply (simp_all add: bs size_of_def) done qed
end
locale typ_heap_simulation =
heap_raw_state t_hrs t_hrs_update +
read_simulation st v r t_hrs +
write_simulation t_hrs t_hrs_update st v w +
write_preserves_valid v w +
valid_implies_cguard st v +
valid_only_typ_desc_dependent t_hrs st v +
pointer_lense r w for
st:: "'s ==> 't"and
r:: "'t ==> ('a::xmem_type) ptr ==> 'a"and
w:: "'a ptr ==> ('a ==> 'a) ==> 't ==> 't"and
v:: "'t ==> ('a::xmem_type) ptr ==> bool"and
t_hrs :: "'s ==> heap_raw_state"and
t_hrs_update:: "(heap_raw_state ==> heap_raw_state) ==> 's ==> 's" begin
lemma write_valid_preservation [write_valid_preservation]: shows"v (st (t_hrs_update (hrs_mem_update (heap_update q x)) s)) p = v (st s) p" by (metis hrs_htd_mem_update get_upd valid_same_typ_desc)
lemma write_padding_valid_preservation [write_valid_preservation]: shows"v (st (t_hrs_update (hrs_mem_update (heap_update_padding q x bs)) s)) p = v (st s) p" by (metis hrs_htd_mem_update get_upd valid_same_typ_desc)
end
locale stack_simulation =
heap_typing_simulation T t_hrs t_hrs_update heap_typing heap_typing_upd st +
typ_heap_typing r w heap_typing heap_typing_upd S for Tand
st:: "'s ==> 't"and
r:: "'t ==> ('a::xmem_type) ptr ==> 'a"and
w:: "'a ptr ==> ('a ==> 'a) ==> 't ==> 't"and
t_hrs :: "'s ==> heap_raw_state"and
t_hrs_update:: "(heap_raw_state ==> heap_raw_state) ==> 's ==> 's"and
heap_typing :: "'t ==> heap_typ_desc"and
heap_typing_upd :: "(heap_typ_desc ==> heap_typ_desc) ==> 't ==> 't"and S:: "addr set" + assumes sim_stack_alloc: "∧p d vs bs s n. (p, d) ∈ stack_allocs n S TYPE('a) (hrs_htd (t_hrs s)) ==> length vs = n ==> length bs = n * size_of TYPE ('a) ==> st (t_hrs_update (hrs_mem_update (fold (λi. heap_update_padding (p +p int i) (vs!i) (take (size_of TYPE('a)) (drop (i * size_of TYPE('a)) bs))) [0..<n]) ∘ hrs_htd_update (λ_. d)) s) = (fold (λi. w (p +p int i) (λ_. (vs ! i))) [0..<n]) (heap_typing_upd (λ_. d) (st s))"
assumes sim_stack_release: "∧p s n. (∧i. i < n ==> root_ptr_valid (hrs_htd (t_hrs s)) (p +p int i)) ==> length bs = n * size_of TYPE('a) ==> st (t_hrs_update (hrs_mem_update (heap_update_list (ptr_val p) bs) ∘ hrs_htd_update (stack_releases n p)) s) = ((heap_typing_upd (stack_releases n p) (fold (λi. w (p +p int i) (λ_. c_type_class.zero)) [0..<n] (st s))))"
assumes stack_byte_zero: "∧p d i. (p, d) ∈ stack_allocs n S TYPE('a) (hrs_htd (t_hrs s)) ==> i < n ==> r (st s) (p +p int i) = ZERO('a)"
lemma (in typ_heap_simulation) L2Tcorres_IO_modify_paddingE [heap_abs]: assumes"abs_expr st P a c" shows"L2Tcorres st (L2_seq (L2_guard (λt. v t p ∧ P t)) (λ_. (L2_modify (λs. w p (λ_. a s) s)))) (IO_modify_heap_paddingE (p::'a ptr) c)" using assms using length_to_bytes write_padding_commutes unfolding liftE_IO_modify_heap_padding by (auto simp add: abs_expr_def L2Tcorres_def corresXF_refines_conv L2_defs
IO_modify_heap_padding_def refines_def_old reaches_bind succeeds_bind split: xval_splits)
locale typ_heap_typing_stack_simulation =
typ_heap_simulation st r w v t_hrs t_hrs_update +
stack_simulation T st r w t_hrs t_hrs_update heap_typing heap_typing_upd S for Tand
st:: "'s ==> 't"and
r:: "'t ==> ('a::xmem_type) ptr ==> 'a"and
w:: "'a ptr ==> ('a ==> 'a) ==> 't ==> 't"and
v:: "'t ==> ('a::xmem_type) ptr ==> bool"and
t_hrs :: "'s ==> heap_raw_state"and
t_hrs_update:: "(heap_raw_state ==> heap_raw_state) ==> 's ==> 's"and
heap_typing :: "'t ==> heap_typ_desc"and
heap_typing_upd :: "(heap_typ_desc ==> heap_typ_desc) ==> 't ==> 't"and S:: "addr set" begin
sublocale monolithic: stack_heap_raw_state t_hrs t_hrs_update S by (unfold_locales)
lemma rel_prod_rel_split_heap_conv: "rel_prod (=) rel_split_heap = (λ(v, t) (r, s). s = st t ∧ (case v of Exn x ==> r = Exn x | Result x ==> r = Result x)) " by (auto simp add: rel_split_heap_def rel_prod_conv fun_eq_iff split: prod.splits xval_splits)
lemma L2Tcorres_refines: "L2Tcorres st fa fc==> refines fc fa s (st s) (rel_prod (=) rel_split_heap)" by (simp add: L2Tcorres_def corresXF_refines_conv rel_prod_rel_split_heap_conv)
lemma refines_L2Tcorres: assumes f: "∧s. refines fc fa s (st s) (rel_prod (=) rel_split_heap)" shows"L2Tcorres st fa fc" using f by (simp add: L2Tcorres_def corresXF_refines_conv rel_prod_rel_split_heap_conv)
lemma L2Tcorres_refines_conv: "L2Tcorres st fa fc⟷ (∀s. refines fc fa s (st s) (rel_prod (=) rel_split_heap))" by (auto simp add: L2Tcorres_refines refines_L2Tcorres)
subgoal for p t t' apply (rule refines_runs_to_partial_rel_prod_on_exit [where S'="rel_split_heap"and P="typing.unchanged_typing_on S t"]) apply (subst (asm) rel_split_heap_def ) apply simp apply (rule f) apply (rule typing_unchanged)
subgoal for sc sa tc apply clarsimp apply (clarsimp simp add: rel_split_heap_def) apply (subst sim_stack_release)
subgoal for bs i using typing.unchanged_typing_on_root_ptr_valid_preservation [where S=Sand s=t and t=scand p=" (p +p int i)"] by auto
subgoal by auto
subgoal by auto done
subgoal by (simp add: Ex_list_of_length) done done
lemma sim_assume_with_fresh_stack_ptr: fixes fc:: "'a ptr ==> ('b, 'c, 's) exn_monad" assumes init: "inita (st s) = initc s" assumes f: "∧s p::'a ptr. refines (fc p) (fa p) s (st s) (rel_prod (=) rel_split_heap)" assumes typing_unchanged: "∧s p::'a ptr. (fc p) ∙ s ?{λr t. typing.unchanged_typing_on S s t}" shows"refines (monolithic.with_fresh_stack_ptr n initc fc) (assume_with_fresh_stack_ptr n inita fa) s (st s) (rel_prod (=) rel_split_heap)" unfolding monolithic.with_fresh_stack_ptr_def assume_with_fresh_stack_ptr_def
stack_ptr_acquire_def stack_ptr_release_def assume_stack_alloc_def apply (rule refines_bind_bind_exn [where Q= "λ(r,t) (r',t'). (rel_prod (=) rel_split_heap) (r,t) (r',t') ∧ (∃p. r = Result p ∧ (∀i < n. ptr_span (p +p int i) ⊆S∧ root_ptr_valid (heap_typing t') (p +p int i)))"])
subgoal apply (rule refines_assume_result_and_state') using sim_stack_alloc stack_byte_zero stack_allocs_S apply (clarsimp simp add: sim_set_def init rel_split_heap_def hrs_htd_update stack_allocs_root_ptr_valid_same) apply blast done apply simp apply simp apply simp
subgoal for p q t t' apply (rule refines_runs_to_partial_rel_prod_assume_on_exit [where S'="rel_split_heap"and P="typing.unchanged_typing_on S t"]) apply (subst (asm) rel_split_heap_def ) apply simp apply (rule f) apply (rule typing_unchanged)
subgoal for sc sa tc apply clarsimp apply (clarsimp simp add: rel_split_heap_def) apply (subst sim_stack_release)
subgoal for bs i using typing.unchanged_typing_on_root_ptr_valid_preservation [where S=Sand s=t and t=scand p=" (p +p int i)"] by auto
subgoal by auto
subgoal by auto done
subgoal by (simp add: Ex_list_of_length)
subgoal for sc sa apply clarsimp apply (clarsimp simp add: rel_split_heap_def)
subgoal for i using typing.unchanged_typing_on_root_ptr_valid_preservation [where S=Sand s=t and t=scand p=" (p +p int i)"] by auto done done done
lemma L2Tcorres_guard_with_fresh_stack_ptr [heap_abs]: assumes rew: "struct_rewrite_expr P initc' initc" assumes grd: "abs_guard st P' P" assumes expr: "abs_expr st Q inita initc'" assumes f[simplified THIN_def, rule_format]: "PROP THIN (∧p::'a ptr. L2Tcorres st (fa p) (fc p))" shows"L2Tcorres st (L2_seq (L2_guard (λs. P' s ∧ Q s)) (λ_. (guard_with_fresh_stack_ptr n inita (L2_VARS fa nm)))) (monolithic.with_fresh_stack_ptr n initc (L2_VARS fc nm))" apply (rule refines_L2Tcorres) apply (simp add: L2_seq_def L2_guard_def L2_VARS_def ) apply (rule refines_bind_guard_right) apply clarsimp apply (rule sim_guard_with_fresh_stack_ptr)
subgoal for s using rew grd expr by (auto simp add: struct_rewrite_expr_def abs_guard_def abs_expr_def)
subgoal for s s' p apply (rule L2Tcorres_refines) apply (rule f) done done
lemma L2Tcorres_with_fresh_stack_ptr: assumes typing_unchanged: "∧s p::'a ptr. (fc p) ∙ s ?{λr t. typing.unchanged_typing_on S s t}" assumes rew: "struct_rewrite_expr P initc' initc" assumes grd: "abs_guard st P' P" assumes expr: "abs_expr st Q inita initc'" assumes f[simplified THIN_def, rule_format]: "PROP THIN (∧p::'a ptr. L2Tcorres st (fa p) (fc p))" shows"L2Tcorres st (L2_seq (L2_guard (λs. P' s ∧ Q s)) (λ_. (with_fresh_stack_ptr n inita (L2_VARS fa nm)))) (monolithic.with_fresh_stack_ptr n initc (L2_VARS fc nm))" apply (rule refines_L2Tcorres) apply (simp add: L2_seq_def L2_guard_def L2_VARS_def) apply (rule refines_bind_guard_right) apply clarsimp apply (rule sim_with_fresh_stack_ptr)
subgoal for s using rew grd expr by (auto simp add: struct_rewrite_expr_def abs_guard_def abs_expr_def)
subgoal for s s' p apply (rule L2Tcorres_refines) apply (rule f) done using typing_unchanged by blast
lemma L2Tcorres_assume_with_fresh_stack_ptr[heap_abs]: assumes typing_unchanged: "∧s p::'a ptr. (fc p) ∙ s ?{λr t. typing.unchanged_typing_on S s t}" assumes rew: "struct_rewrite_expr P initc' initc" assumes grd: "abs_guard st P' P" assumes expr: "abs_expr st Q inita initc'" assumes f[simplified THIN_def, rule_format]: "PROP THIN (∧p::'a ptr. L2Tcorres st (fa p) (fc p))" shows"L2Tcorres st (L2_seq (L2_guard (λs. P' s ∧ Q s)) (λ_. (assume_with_fresh_stack_ptr n inita (L2_VARS fa nm)))) (monolithic.with_fresh_stack_ptr n initc (L2_VARS fc nm))" apply (rule refines_L2Tcorres) apply (simp add: L2_seq_def L2_guard_def L2_VARS_def) apply (rule refines_bind_guard_right) apply clarsimp apply (rule sim_assume_with_fresh_stack_ptr)
subgoal for s using rew grd expr by (auto simp add: struct_rewrite_expr_def abs_guard_def abs_expr_def)
subgoal for s s' p apply (rule L2Tcorres_refines) apply (rule f) done using typing_unchanged by blast
lemma unchanged_typing_commutes: "typing.unchanged_typing_on S s t ==> unchanged_typing_on S (st s) (st t)" using heap_typing_commutes [of s] heap_typing_commutes [of t] by (auto simp add: unchanged_typing_on_def typing.unchanged_typing_on_def) end
(* The following lemmas help to establish that reading from stack_byte typed locations
results in ZERO('a) *)
named_theorems read_stack_byte_ZERO_base and read_stack_byte_ZERO_step and read_stack_byte_ZERO_step_subst
lemma (in open_types) ptr_span_with_stack_byte_type_implies_ptr_invalid: fixes p :: "('a :: {mem_type, stack_type}) ptr" assumes *: "∀a ∈ ptr_span p. root_ptr_valid d (PTR (stack_byte) a)" shows"¬ ptr_valid_u (typ_uinfo_t TYPE('a)) d (ptr_val p)" by (metis assms disjoint_iff fold_ptr_valid' in_ptr_span_itself ptr_exhaust_eq
ptr_valid_stack_byte_disjoint)
lemma (in open_types)
ptr_span_with_stack_byte_type_implies_ZERO[read_stack_byte_ZERO_base]: fixes p :: "('a :: {mem_type, stack_type}) ptr" assumes"∀a ∈ ptr_span p. root_ptr_valid (hrs_htd d) (PTR (stack_byte) a)" shows"the_default (ZERO('a)) (plift d p) = ZERO('a)" using ptr_span_with_stack_byte_type_implies_ptr_invalid[OF assms] by (simp add: fold_ptr_valid' plift_None)
lemma read_stack_byte_ZERO_array_intro[read_stack_byte_ZERO_step]: fixes q :: "('a :: {array_outer_max_size}['b :: array_max_count]) ptr" assumes ptr_span_has_stack_byte_type: "∀a∈ptr_span q. root_ptr_valid d (PTR(stack_byte) a)" assumes subtype_reads_ZERO: "∧p :: 'a ptr. ∀a∈ptr_span p. root_ptr_valid d (PTR(stack_byte) a) ==> r s p = ZERO('a)" shows"(ARRAY i. r s (array_ptr_index q c i)) = ZERO('a['b])" apply (rule array_ext) apply (simp add: array_index_zero) apply (rule subtype_reads_ZERO) using ptr_span_has_stack_byte_type ptr_span_array_ptr_index_subset_ptr_span by blast
lemma read_stack_byte_ZERO_array_2dim_intro[read_stack_byte_ZERO_step]: fixes q :: "('a :: {array_inner_max_size}['b :: array_max_count]['c :: array_max_count]) ptr" assumes ptr_span_has_stack_byte_type: "∀a∈ptr_span q. root_ptr_valid d (PTR(stack_byte) a)" assumes subtype_reads_ZERO: "∧p :: 'a ptr. ∀a∈ptr_span p. root_ptr_valid d (PTR(stack_byte) a) ==> r s p = ZERO('a)" shows"(ARRAY i j. r s (array_ptr_index (array_ptr_index q c i) c j)) = ZERO('a['b]['c])" apply (rule array_ext) apply (simp add: array_index_zero) apply (rule array_ext) apply (simp add: array_index_zero) apply (rule subtype_reads_ZERO) by (metis (no_types, opaque_lifting) subset_iff ptr_span_has_stack_byte_type
ptr_span_array_ptr_index_subset_ptr_span)
lemma read_stack_byte_ZERO_field_intro[read_stack_byte_ZERO_step]: fixes q :: "'a :: mem_type ptr" assumes ptr_span_has_stack_byte_type: "∀a∈ptr_span q. root_ptr_valid d (PTR(stack_byte) a)" assumes subtype_reads_ZERO: "∧p :: 'b :: mem_type ptr. ∀a∈ptr_span p. root_ptr_valid d (PTR(stack_byte) a) ==> r s p = ZERO('b)" assumes subtype_lookup: "field_lookup (typ_uinfo_t TYPE('a)) f 0 = Some (typ_uinfo_t TYPE('b), n)" shows"r s (PTR('b) (&(q→f))) = ZERO('b)" proof - have"ptr_span (PTR('b) (&(q→f))) ⊆ ptr_span q" using TypHeapSimple.field_tag_sub'[OF subtype_lookup] by (simp, metis size_of_fold) thus ?thesis using ptr_span_has_stack_byte_type subtype_lookup subtype_reads_ZERO by blast qed
context open_types begin
lemma ptr_span_with_stack_byte_type_implies_read_dedicated_heap_ZERO[simp]: "∀a∈ptr_span p. root_ptr_valid (hrs_htd s) (PTR(stack_byte) a) ==> read_dedicated_heap s p = ZERO('a::{stack_type, xmem_type})" unfolding read_dedicated_heap_def ptr_span_with_stack_byte_type_implies_ZERO[of p] merge_addressable_fields.idem ..
lemma write_simulationI: fixes R :: "'s ==> 'a::xmem_type ptr ==> 'a" assumes fs: "map_of T (typ_uinfo_t TYPE('a)) = Some fs" assumes"heap_typing_simulation T t_hrs t_hrs_update heap_typing heap_typing_update l" and l_w: "list_all2 (λf w. ∀t u n h (p::'a ptr) x. field_ti TYPE('a) f = Some t ⟶ field_lookup (typ_uinfo_t TYPE('a)) f 0 = Some (u, n) ⟶ ptr_valid_u u (hrs_htd (t_hrs h)) &(p→f) ⟶ l (t_hrs_update (hrs_mem_update (heap_upd_list (size_td u) &(p→f) (access_ti t x))) h) = w p x (l h)) fs ws" and l_u: "∧(p::'a ptr) (x::'a) (s::'b). ptr_valid (hrs_htd (t_hrs s)) p ==> l (t_hrs_update (write_dedicated_heap p x) s) = u (upd_fun p (λold. merge_addressable_fields old x)) (l s)" assumes V: "∧h p. V (l h) p ⟷ ptr_valid (hrs_htd (t_hrs h)) p" assumes W: "∧p f h. W p f h = fold (λw. w p (f (R h p))) ws (u (upd_fun p (λold. merge_addressable_fields old (f (R h p)))) h)" shows"write_simulation t_hrs t_hrs_update l V W" proof - interpret hrs: heap_typing_simulation T t_hrs t_hrs_update heap_typing heap_typing_update l by fact
have valid: "list_all (λf. ∀u n. field_lookup (typ_uinfo_t TYPE('a)) f 0 = Some (u, n) ⟶ ptr_valid_u u h &(p→f)) fs" if *: "ptr_valid_u (typ_uinfo_t TYPE('a)) h (ptr_val p)"for h and p :: "'a ptr" using ptr_valid_u_step[OF fs _ _ *] by (auto simp: list_all_iff field_lvalue_def field_offset_def)
have fold': "l (fold (λxa. t_hrs_update (hrs_mem_update (heap_upd_list (size_td (the (field_ti TYPE('a) xa))) &(p→xa) (access_ti (the (field_ti TYPE('a) xa)) x)))) fs s) = fold (λw. w p x) ws (l s)" if p: "ptr_valid_u (typ_uinfo_t TYPE('a)) (hrs_htd (t_hrs s)) (ptr_val p)" for p x s using l_w wf_T[OF fs] p[THEN valid] proof (induction arbitrary: s) case (Cons f fs w ws) from Cons.prems obtain u n where f_u :"field_lookup (typ_uinfo_t TYPE('a)) f 0 = Some (u, n)" and [simp]: "list_all (λf. ∃a b. field_lookup (typ_uinfo_t TYPE('a)) f 0 = Some (a, b)) fs" by auto from f_u[THEN field_lookup_uinfo_Some_rev] obtain k where "field_lookup (typ_info_t TYPE('a)) f 0 = Some (k, n)"and u_eq: "u = export_uinfo k" by auto thenhave [simp]: "field_ti TYPE('a) f = Some k"by (simp add: field_ti_def) have [simp]: "size_td k = size_td u" by (simp add: u_eq) have [simp]: "ptr_valid_u u (hrs_htd (t_hrs s)) &(p→f)" using Cons.prems(2) f_u by auto show ?case using Cons.prems Cons.hyps by (simp add: Cons.IH f_u) qed simp
have fold: "l ((fold (t_hrs_update ∘ (λ(f, u). hrs_mem_update (heap_upd_list (size_td u) &(p>→f) (access_ti u x)))) (addressable_fields TYPE('a)) ∘ t_hrs_update (write_dedicated_heap p x)) s) = fold (λw. w p x) ws (u (upd_fun p (λold. merge_addressable_fields old x)) (l s))" if p: "ptr_valid_u (typ_uinfo_t TYPE('a)) (hrs_htd (t_hrs s)) (ptr_val p)" for p x s by (subst addressable_fields_def)
(simp add: fs fold_map fold' p ptr_valid_def l_u cong: fold_cong)
locale stack_simulation_heap_typing =
typ_heap_simulation st r w "λt p. open_types.ptr_valid T (heap_typing t) p" t_hrs t_hrs_update +
heap_typing_simulation T t_hrs t_hrs_update heap_typing heap_typing_upd st +
typ_heap_typing r w heap_typing heap_typing_upd S for
st:: "'s ==> 't"and
r:: "'t ==> ('a::{xmem_type, stack_type}) ptr ==> 'a"and
w:: "'a ptr ==> ('a ==> 'a) ==> 't ==> 't"and
t_hrs :: "'s ==> heap_raw_state"and
t_hrs_update:: "(heap_raw_state ==> heap_raw_state) ==> 's ==> 's"and
heap_typing :: "'t ==> heap_typ_desc"and
heap_typing_upd :: "(heap_typ_desc ==> heap_typ_desc) ==> 't ==> 't"and S:: "addr set"and T:: "(typ_uinfo * qualified_field_name list) list" +
assumes sim_stack_alloc_heap_typing: "∧p d s n. (p, d) ∈ stack_allocs n S TYPE('a) (hrs_htd (t_hrs s)) ==> st (t_hrs_update (hrs_mem_update (fold (λi. heap_update (p +p int i) c_type_class.zero) [0..<n]) ∘ hrs_htd_update (λ_. d)) s) = (heap_typing_upd (λ_. d) (st s))"
assumes sim_stack_release_heap_typing: "∧(p::'a ptr) s n. (∧i. i < n ==> root_ptr_valid (hrs_htd (t_hrs s)) (p +p int i)) ==> st (t_hrs_update (hrs_htd_update (stack_releases n p)) s) = heap_typing_upd (stack_releases n p) (st (t_hrs_update (hrs_mem_update (fold (λi. heap_update (p +p int i) c_type_class.zero) [0..<n])) s))"
assumes sim_stack_stack_byte_zero[read_stack_byte_ZERO_step]: "∧p s. ∀a∈ptr_span p. root_ptr_valid (hrs_htd (t_hrs s)) (PTR(stack_byte) a) ==> r (st s) p = ZERO('a)"(* " *)
begin
lemma fold_heap_update_simulation: assumes valid: "∧i. i < n ==> ptr_valid (heap_typing (st s)) (p +p int i)" shows"st (t_hrs_update (hrs_mem_update (fold (λi. heap_update (p +p int i) (vs i)) [0..<n])) s) = fold (λi. w (p +p int i) (λ_. vs i)) [0..<n] (st s)" using valid proof (induct n arbitrary: vs s) case0 thenshow ?case by (simp add: case_prod_unfold hrs_mem_update_def) next case (Suc n) from Suc.prems obtain
valid: "∧i. i < Suc n ==> ptr_valid (heap_typing (st s)) (p +p int i)"by blast
from valid have valid': "∧i. i < n ==> ptr_valid (heap_typing (st s)) (p +p int i)"byauto note hyp = Suc.hyps [OF valid'] show ?case apply (simp add: hyp [symmetric]) apply (subst write_commutes [symmetric]) using valid apply simp using TypHeapSimple.hrs_mem_update_comp hrs_mem_update_def apply simp done qed
lemma fold_heap_update_padding_simulation: assumes valid: "∧i. i < n ==> ptr_valid (heap_typing (st s)) (p +p int i)" assumes lbs: "length bs = n * size_of TYPE('a)" shows"st (t_hrs_update (hrs_mem_update (fold (λi. heap_update_padding (p +p int i) (vs i) (take (size_of TYPE('a)) (drop (i * size_of TYPE('a)) bs))) [0..<n])) s) = fold (λi. w (p +p int i) (λ_. vs i)) [0..<n] (st s)" using valid lbs proof (induct n arbitrary: bs vs s ) case0 thenshow ?case by (simp add: case_prod_unfold hrs_mem_update_def) next case (Suc n) from Suc.prems obtain
valid: "∧i. i < Suc n ==> ptr_valid (heap_typing (st s)) (p +p int i)"and
lbs': "length (take (n * (size_of TYPE('a))) bs) = n * size_of TYPE('a)" by auto
from valid have valid': "∧i. i < n ==> ptr_valid (heap_typing (st s)) (p +p int i)"byauto note hyp = Suc.hyps [OF valid' lbs'] have take_eq: "∧i. i < n ==> take (size_of TYPE('a)) (drop (i * size_of TYPE('a)) (take (n * size_of TYPE('a)) bs)) = take (size_of TYPE('a)) (drop (i * size_of TYPE('a)) bs)" by (metis Groups.mult_ac(2) mult_less_cancel1 not_less not_less_eq
order_less_imp_le take_all take_drop_take times_nat.simps(2))
have fold_eq: "∧h. fold (λi. heap_update_padding (p +p int i) (vs i) (take (size_of TYPE('a)) (drop (i * size_of TYPE('a)) (take (n * size_of TYPE('a)) bs)))) [0..<n] h = fold (λi. heap_update_padding (p +p int i) (vs i) (take (size_of TYPE('a)) (drop (i * size_of TYPE('a)) bs))) [0..<n] h"
show ?case apply (simp add: hyp [symmetric]) apply (subst write_padding_commutes [symmetric, where bs = "take (size_of TYPE('a)) (drop (n * size_of TYPE('a)) bs)"])
subgoal using valid by simp
subgoal using Suc.prems by simp
subgoal using TypHeapSimple.hrs_mem_update_comp hrs_mem_update_def by (simp add: fold_eq) done qed
lemma sim_stack_alloc': assumes alloc: "(p, d) ∈ stack_allocs n S TYPE('a) (hrs_htd (t_hrs s))" assumes len: "length vs = n" assumes lbs: "length bs = n * size_of TYPE('a)" shows"st (t_hrs_update (hrs_mem_update (fold (λi. heap_update_padding (p +p int i) (vs!i) (take (size_of TYPE('a)) (drop (i * size_of TYPE('a)) bs))) [0..<n]) ∘ hrs_htd_update (λ_. d)) s) = (fold (λi. w (p +p int i) (λ_. (vs ! i))) [0..<n]) (heap_typing_upd (λ_. d) (st s))" proof -
{ fix i assume i_bound: "i < n" have"ptr_valid (heap_typing (st (t_hrs_update (hrs_mem_update (fold (λi. heap_update (p +p int i) c_type_class.zero) [0..<n]) ∘ hrs_htd_update (λ_. d)) s))) (p +p int i)" proof - from stack_allocs_cases [OF alloc] i_bound have ptr_valid: "ptr_valid d (p +p int i)" using root_ptr_valid_ptr_valid by auto thus ?thesis using heap_typing_upd_commutes by (simp, metis) qed
} note valids = this
from stack_allocs_cases [OF alloc] obtain
bound: "unat (ptr_val p) + n * size_of TYPE('a) ≤ addr_card"and
not_null: "ptr_val p ≠ 0" by (metis Ptr_ptr_val c_guard_NULL_simp)
lemma sim_stack_release': fixes p :: "'a ptr" assumes roots: "∧i. i < n ==> root_ptr_valid (hrs_htd (t_hrs s)) (p +p int i)" shows"st (t_hrs_update (hrs_htd_update (stack_releases n p)) s) = ((heap_typing_upd (stack_releases n p) ((fold (λi. w (p +p int i) (λ_. c_type_class.zero)) [0..<n]) (st s))))" proof - from roots root_ptr_valid_ptr_valid heap_typing_commutes have valids: "∧i . i < n ==> ptr_valid (heap_typing (st s)) (p +p int i)" by metis note commutes = fold_heap_update_simulation [OF valids, symmetric, of n, simplified] show ?thesis apply (simp add: commutes ) apply (simp add: sim_stack_release_heap_typing [OF roots]) done qed
lemma sim_stack_release'': fixes p :: "'a ptr" assumes roots: "∧i. i < n ==> root_ptr_valid (hrs_htd (t_hrs s)) (p +p int i)" assumes lbs: "length bs = n * size_of TYPE('a)" shows"st (t_hrs_update (hrs_mem_update (heap_update_list (ptr_val p) bs) o hrs_htd_update (stack_releases n p)) s) = ((heap_typing_upd (stack_releases n p) ((fold (λi. w (p +p int i) (λ_. c_type_class.zero)) [0..<n]) (st s))))" proof -
{ fix i assume bound_i: "i < length bs" have"root_ptr_valid (hrs_htd (t_hrs (t_hrs_update (hrs_htd_update (stack_releases n p)) s))) ((PTR_COERCE('a → stack_byte) p) +p int i)" proof - have span: "ptr_val (((PTR_COERCE('a → stack_byte) p) +p int i)) ∈ {ptr_val p..+n * size_of TYPE('a)}" using lbs bound_i intvlI by (auto simp add: ptr_add_def) from roots have"∀i<n. c_guard (p +p int i)" using root_ptr_valid_c_guard by blast from stack_releases_root_ptr_valid_footprint [OF span this] show ?thesis using typing.get_upd by force qed
} note sb = this
show ?thesis apply (simp add: lift_heap_update_list_stack_byte_independent [OF sb, simplified]) apply (simp add: sim_stack_release' [OF roots]) done qed
lemma stack_byte_zero': assumes"(p, d) ∈ stack_allocs n S TYPE('a) (hrs_htd (t_hrs s))" assumes"i < n" shows"r (st s) (p +p int i) = ZERO('a)" by (rule sim_stack_stack_byte_zero)
(meson assms stack_allocs_cases stack_allocs_contained subsetD)
sublocale stack_simulation using sim_stack_alloc' sim_stack_release'' stack_byte_zero' by (unfold_locales) auto
sublocale typ_heap_typing_stack_simulation T st r w "λt p. open_types.ptr_valid T (heap_typing t) p" t_hrs t_hrs_update heap_typing heap_typing_upd S by (unfold_locales)
lemma typ_heap_simulation_get_hvalD: "[ typ_heap_simulation st r w v t_hrs t_hrs_update; v (st s) p ]==> h_val (hrs_mem (t_hrs s)) p = r (st s) p" by (clarsimp simp: read_simulation.read_commutes [OF typ_heap_simulation.axioms(2)])
lemma valid_struct_fieldI [intro]: fixes field_getter :: "('a::xmem_type) ==> ('f::xmem_type)" shows"[ ∧s f. f (field_getter s) = (field_getter s) ==> field_setter f s = s; ∧s f f'. f (field_getter s) = f' (field_getter s) ==> field_setter f s = field_setter f' s; ∧s f. field_getter (field_setter f s) = f (field_getter s); ∧s f g. field_setter f (field_setter g s) = field_setter (f ∘ g) s; field_ti TYPE('a) field_name = Some (adjust_ti (typ_info_t TYPE('f)) field_getter (field_setter ∘ (λx _. x))); ∧(p::'a ptr). c_guard p ==> c_guard (Ptr &(p→field_name) :: 'f ptr); ∧s x. t_hrs (t_hrs_update x s) = x (t_hrs s); ∧s f. f (t_hrs s) = t_hrs s ==> t_hrs_update f s = s; ∧s f f'. f (t_hrs s) = f' (t_hrs s) ==> t_hrs_update f s = t_hrs_update f' s; ∧s f g. t_hrs_update f (t_hrs_update g s) = t_hrs_update (λx. f (g x)) s ]==> valid_struct_field field_name field_getter field_setter t_hrs t_hrs_update" apply (unfold valid_struct_field_def lense_def o_def) apply (safe | assumption | rule ext)+ done
lemma typ_heap_simulation_t_hrs_updateD: "[ typ_heap_simulation st r w v t_hrs t_hrs_update; v (st s) p ]==> st (t_hrs_update (hrs_mem_update (heap_update p v')) s) = w p (λx. v') (st s)" by (clarsimp simp: write_simulation.write_commutes [OF typ_heap_simulation.axioms(3)])
lemma heap_abs_expr_guard [heap_abs]: "[ typ_heap_simulation st getter setter vgetter t_hrs t_hrs_update; abs_expr st P x' x ]==> abs_guard st (λs. P s ∧ vgetter s (x' s)) (λs. (c_guard (x s :: ('a::xmem_type) ptr)))" apply (clarsimp simp: abs_expr_def abs_guard_def
simple_lift_def root_ptr_valid_def
valid_implies_cguard.valid_implies_c_guard [OF typ_heap_simulation.axioms(5)]) done
lemma heap_abs_expr_h_val [heap_abs]: "[ typ_heap_simulation st r w v t_hrs t_hrs_update; abs_expr st P x' x ]==> abs_expr st (λs. P s ∧ v s (x' s)) (λs. (r s (x' s))) (λs. (h_val (hrs_mem (t_hrs s))) (x s))" apply (clarsimp simp: abs_expr_def simple_lift_def) apply (metis typ_heap_simulation_get_hvalD) done
lemma heap_abs_modifies_heap_update__unused: "[ typ_heap_simulation st r w v t_hrs t_hrs_update; abs_expr st Pb b' b; abs_expr st Pc c' c ]==> abs_modifies st (λs. Pb s ∧ Pc s ∧ v s (b' s)) (λs. w (b' s) (λx. (c' s)) s) (λs. t_hrs_update (hrs_mem_update (heap_update (b s :: ('a::xmem_type) ptr) (c s))) s)" apply (clarsimp simp: typ_simple_heap_simps abs_expr_def abs_modifies_def) apply (metis typ_heap_simulation_t_hrs_updateD) done
(* See comment for heap_lift__wrap_h_val. *) definition"heap_lift__h_val ≡ h_val"
(* See the comment for struct_rewrite_modifies_field. *Inthiscasewerelyonniceunificationfor?c. *Theheap_abs_syntaxgeneratoralsoreliesonthisrule
* and would need to be modified if the previous rule was used instead. *) (* (\<lambda>s. setter (\<lambda>x. x(b' s := c' (x (b' s)) s)) s) *) lemma heap_abs_modifies_heap_update [heap_abs]: "[ typ_heap_simulation st r w v t_hrs t_hrs_update; abs_expr st Pb b' b; ∧v. abs_expr st Pc (c' v) (c v) ]==> abs_modifies st (λs. Pb s ∧ Pc s ∧ v s (b' s)) (λs. w (b' s) (λ_. (c' (r s (b' s)) s)) s) (λs. t_hrs_update (hrs_mem_update (heap_update (b s :: ('a::xmem_type) ptr) (c (heap_lift__h_val (hrs_mem (t_hrs s)) (b s)) s))) s)" apply (clarsimp simp: typ_simple_heap_simps abs_expr_def abs_modifies_def heap_lift__h_val_def)
subgoal for s apply (rule subst[where t = "h_val (hrs_mem (t_hrs s)) (b' (st s))" and s = "r (st s) (b' (st s))"]) apply (clarsimp simp: read_simulation.read_commutes [OF typ_heap_simulation.axioms(2)]) apply (simp add: write_simulation.write_commutes [OF typ_heap_simulation.axioms(3)]) done done
lemma struct_rewrite_guard_expr [heap_abs]: "struct_rewrite_expr P a' a ==> struct_rewrite_guard (λs. P s ∧ a' s) a" by (simp add: struct_rewrite_expr_def struct_rewrite_guard_def)
lemma struct_rewrite_guard_conj [heap_abs]: "[ struct_rewrite_guard b' b; struct_rewrite_guard a' a ]==> struct_rewrite_guard (λs. a' s ∧ b' s) (λs. a s ∧ b s)" by (clarsimp simp: struct_rewrite_guard_def)
lemma struct_rewrite_guard_split [heap_abs]: "[∧a b. struct_rewrite_guard (A a b) (C a b) ] ==> struct_rewrite_guard (case r of (a, b) ==> A a b) (case r of (a, b) ==> C a b)" apply (auto simp: split_def) done
lemma struct_rewrite_guard_c_guard_field [heap_abs]: "[ valid_struct_field field_name (field_getter :: ('a :: xmem_type) ==> ('f :: xmem_type)) field_setter t_hrs t_hrs_update; struct_rewrite_expr P p' p; struct_rewrite_guard Q (λs. c_guard (p' s)) ]==> struct_rewrite_guard (λs. P s ∧ Q s) (λs. c_guard (Ptr (field_lvalue (p s :: 'a ptr) field_name) :: 'f ptr))" by (simp add: valid_struct_field_def struct_rewrite_expr_def struct_rewrite_guard_def)
lemma c_guard_array: "[ 0 ≤ k; nat k < CARD('b); c_guard (p :: (('a::array_outer_max_size)['b::array_max_count]) ptr) ] ==> c_guard (ptr_coerce p +p k :: 'a ptr)" apply (clarsimp simp: CTypesDefs.ptr_add_def c_guard_def c_null_guard_def) apply (rule conjI[rotated]) apply (erule contrapos_nn) apply (clarsimp simp: intvl_def)
subgoal for i apply (rule exI[where x = "nat k * size_of TYPE('a) + i"]) apply clarsimp apply (rule conjI) apply (simp add: field_simps) apply (rule less_le_trans[where y = "Suc (nat k) * size_of TYPE('a)"]) apply simp apply (metis less_eq_Suc_le mult_le_mono2 mult.commute) done apply (subgoal_tac "ptr_aligned (ptr_coerce p :: 'a ptr)") apply (frule_tac p = "ptr_coerce p"and i = "k"in ptr_aligned_plus) apply (clarsimp simp: CTypesDefs.ptr_add_def) apply (clarsimp simp: ptr_aligned_def align_of_array) done
lemma struct_rewrite_guard_c_guard_Array_field [heap_abs]: "[ valid_struct_field field_name (field_getter :: ('a :: xmem_type) ==> ('f::array_outer_max_size ['n::array_max_count])) field_setter t_hrs t_hrs_update; struct_rewrite_expr P p' p; struct_rewrite_guard Q (λs. c_guard (p' s)) ]==> struct_rewrite_guard (λs. P s ∧ Q s ∧ 0 ≤ k ∧ nat k < CARD('n)) (λs. c_guard (ptr_coerce (Ptr (field_lvalue (p s :: 'a ptr) field_name) :: (('f['n]) ptr)) +p k :: 'f ptr))" by (simp del: ptr_coerce.simps add: valid_struct_field_def struct_rewrite_expr_def struct_rewrite_guard_def c_guard_array)
(* struct_rewrite_expr rules *)
(* This is only used when heap lifting is turned off, *whereweexpectnorewritingtohappenanyway. *TODO:itmightbesafetoenablethisunconditionally,
* as long as it happens after heap_abs_fo. *) lemma struct_rewrite_expr_id: "struct_rewrite_expr (λ_. True) A A" by (simp add: struct_rewrite_expr_def)
lemma struct_rewrite_expr_fun_app2 [heap_abs_fo]: "[ struct_rewrite_expr P f f'; struct_rewrite_expr Q g g' ]==> struct_rewrite_expr (λs. P s ∧ Q s) (λs a. f s a (g s a)) (λs a. f' s a $ g' s a)" by (simp add: struct_rewrite_expr_def)
lemma struct_rewrite_expr_fun_app [heap_abs_fo]: "[ struct_rewrite_expr Y x x'; struct_rewrite_expr X f f' ]==> struct_rewrite_expr (λs. X s ∧ Y s) (λs. f s (x s)) (λs. f' s $ x' s)" by (clarsimp simp: struct_rewrite_expr_def)
lemma struct_rewrite_expr_constant [heap_abs]: "struct_rewrite_expr (λ_. True) (λ_. a) (λ_. a)" by (clarsimp simp: struct_rewrite_expr_def)
lemma struct_rewrite_expr_lambda_null [heap_abs]: "struct_rewrite_expr P A C ==> struct_rewrite_expr P (λs _. A s) (λs _. C s)" by (clarsimp simp: struct_rewrite_expr_def)
lemma struct_rewrite_expr_split [heap_abs]: "[∧a b. struct_rewrite_expr (P a b) (A a b) (C a b) ] ==> struct_rewrite_expr (case r of (a, b) ==> P a b) (case r of (a, b) ==> A a b) (case r of (a, b) ==> C a b)" apply (auto simp: split_def) done
lemma struct_rewrite_expr_indirect_h_val [heap_abs]: "struct_rewrite_expr P a c ==> struct_rewrite_expr P (λs. h_val (h s) (a s)) (λs. h_val (h s) (c s))" by (simp add: struct_rewrite_expr_def)
lemma abs_expr_field [heap_abs]: "[ valid_struct_field field_name (field_getter :: ('a :: xmem_type) ==> ('f :: xmem_type)) field_setter t_hrs t_hrs_update; abs_expr st P a c] ==> abs_expr st P (λs. field_getter (a s)) (λs. field_getter (c s))" by (clarsimp simp add: valid_struct_field_def abs_expr_def)
(* Descend into struct fields that are themselves arrays. *) lemma struct_rewrite_expr_Array_field [heap_abs]: "[ valid_struct_field field_name (field_getter :: ('a :: xmem_type) ==> 'f::array_outer_max_size ['n::array_max_count]) field_setter t_hrs t_hrs_update; struct_rewrite_expr P p' p; struct_rewrite_expr Q a (λs. h_val (hrs_mem (t_hrs s)) (p' s)) ] ==> struct_rewrite_expr (λs. P s ∧ Q s ∧ k ≥ 0 ∧ nat k < CARD('n)) (λs. index (field_getter (a s)) (nat k)) (λs. h_val (hrs_mem (t_hrs s)) (ptr_coerce (Ptr (field_lvalue (p s) field_name) :: ('f['n]) ptr) +p k))" apply (cases k) apply (clarsimp simp: struct_rewrite_expr_def simp del: ptr_coerce.simps)
subgoal for n s apply (subst struct_rewrite_expr_field
[unfolded struct_rewrite_expr_def, simplified, rule_format, symmetric, where field_getter = field_getter and P = P and Q = Q and p = p and p' = p']) apply assumption apply simp apply simp apply simp apply (rule subst[where s = "p s"and t = "p' s"]) apply simp apply (rule heap_access_Array_element[symmetric]) apply simp done apply (simp add: struct_rewrite_expr_def) done declare struct_rewrite_expr_Array_field [unfolded ptr_coerce.simps, heap_abs]
(* struct_rewrite_modifies rules *)
lemma struct_rewrite_modifies_id [heap_abs]: "struct_rewrite_modifies (λ_. True) A A" by (simp add: struct_rewrite_modifies_def)
(* We need some typ_heap_simulation, but we're really only after t_hrs_update. *Weartificiallyconstrainthetypeofvtolimitbacktracking,
* since specialisation of typ_heap_simulation will generate one rule per 'a. *) lemma struct_rewrite_modifies_basecase [heap_abs]: "[ typ_heap_simulation st (getter :: 's ==> 'a ptr ==> ('a::xmem_type)) setter vgetter t_hrs t_hrs_update; struct_rewrite_expr P p' p; struct_rewrite_expr Q v' v ]==> struct_rewrite_modifies (λs. P s ∧ Q s) (λs. t_hrs_update (hrs_mem_update (heap_update (p' s) (v' s :: 'a))) s) (λs. t_hrs_update (hrs_mem_update (heap_update (p s) (v s :: 'a))) s)" by (simp add: struct_rewrite_expr_def struct_rewrite_modifies_def)
(* \<approx> heap_update_field.
* We probably need this rule to generalise struct_rewrite_modifies_field. *) lemma heap_update_field_unpacked: "[ field_ti TYPE('a::mem_type) f = Some (t :: 'a xtyp_info); c_guard (p :: 'a::mem_type ptr); export_uinfo t = export_uinfo (typ_info_t TYPE('b::mem_type)) ]==> heap_update (Ptr &(p→f) :: 'b ptr) v hp = heap_update p (update_ti t (to_bytes_p v) (h_val hp p)) hp" oops
(* \<approx> heap_update_Array_element. Would want this for struct_rewrite_modifies_Array_field. *) lemma heap_update_Array_element_unpacked: "n < CARD('b::array_max_count) ==> heap_update (ptr_coerce p' +p int n) w hp = heap_update (p'::('a::array_outer_max_size['b::array_max_count]) ptr) (Arrays.update (h_val hp p') n w) hp" oops
lemma heap_lift_wrap_h_val [heap_abs]: "heap_lift__wrap_h_val (heap_lift__h_val s p) (h_val s p)" by (simp add: heap_lift__h_val_def heap_lift__wrap_h_val_def)
lemma heap_lift_wrap_h_val_skip [heap_abs]: "heap_lift__wrap_h_val (h_val s (Ptr (field_lvalue p f))) (h_val s (Ptr (field_lvalue p f)))" by (simp add: heap_lift__wrap_h_val_def)
lemma heap_lift_wrap_h_val_skip_array [heap_abs]: "heap_lift__wrap_h_val (h_val s (ptr_coerce p +p k)) (h_val s (ptr_coerce p +p k))" by (simp add: heap_lift__wrap_h_val_def)
(* These are valid rules, but produce redundant output. *) lemma struct_rewrite_modifies_field__unused: "[ valid_struct_field field_name (field_getter :: ('a::xmem_type) ==> ('f::xmem_type)) field_setter t_hrs t_hrs_update; struct_rewrite_expr P p' p; struct_rewrite_expr Q f' f; struct_rewrite_modifies R (λs. t_hrs_update (hrs_mem_update (heap_update (p'' s) (u s (field_setter (λ_. f' s))))) s) (λs. t_hrs_update (hrs_mem_update (heap_update (p' s) (field_setter (λ_. f' s) (h_val (hrs_mem (t_hrs s)) (p' s))))) s); struct_rewrite_guard S (λs. c_guard (p' s)) ]==> struct_rewrite_modifies (λs. P s ∧ Q s ∧ R s ∧ S s) (λs. t_hrs_update (hrs_mem_update (heap_update (p'' s) (u s (field_setter (λ_. f' s))))) s) (λs. t_hrs_update (hrs_mem_update (heap_update (Ptr (field_lvalue (p s) field_name)) (f s))) s)" apply (clarsimp simp: struct_rewrite_expr_def struct_rewrite_guard_def struct_rewrite_modifies_def valid_struct_field_def) apply (erule_tac x = s in allE)+ apply (erule impE, assumption)+ apply (erule_tac t = "t_hrs_update (hrs_mem_update (heap_update (p'' s) (u s (field_setter (λ_. f' s))))) s" and s = "t_hrs_update (hrs_mem_update (heap_update (p' s) (field_setter (λ_. f' s) (h_val (hrs_mem (t_hrs s)) (p' s))))) s" in subst) apply (rule lense.upd_cong[where get = t_hrs and upd = t_hrs_update]) apply assumption apply (rule lense.upd_cong[OF read_write_valid_hrs_mem]) apply (subst heap_update_field_root_conv''') apply assumption+ apply (simp add: typ_uinfo_t_def lense.fg_cons) apply (subst update_ti_update_ti_t) apply (simp add: size_of_def) apply (subst update_ti_s_adjust_ti_to_bytes_p) apply (erule lense.fg_cons) apply simp done
lemma struct_rewrite_modifies_Array_field__unused: "[ valid_struct_field field_name (field_getter :: ('a::xmem_type) ==> (('f::array_outer_max_size)['n::array_max_count])) field_setter t_hrs t_hrs_update; struct_rewrite_expr P p' p; struct_rewrite_expr Q f' f; struct_rewrite_modifies R (λs. t_hrs_update (hrs_mem_update (heap_update (p'' s) (u s (field_setter (λa. Arrays.update a (nat k) (f' s)))))) s) (λs. t_hrs_update (hrs_mem_update (heap_update (p' s) (field_setter (λa. Arrays.update a (nat k) (f' s)) (h_val (hrs_mem (t_hrs s)) (p' s))))) s); struct_rewrite_guard S (λs. c_guard (p' s)) ]==> struct_rewrite_modifies (λs. P s ∧ Q s ∧ R s ∧ S s ∧ 0 ≤ k ∧ nat k < CARD('n)) (λs. t_hrs_update (hrs_mem_update (heap_update (p'' s) (u s (field_setter (λa. Arrays.update a (nat k) (f' s)))))) s) (λs. t_hrs_update (hrs_mem_update (heap_update (ptr_coerce (Ptr (field_lvalue (p s) field_name) :: ('f['n]) ptr) +p k) (f s))) s)" using ptr_coerce.simps [simp del] apply (clarsimp simp: struct_rewrite_expr_def struct_rewrite_guard_def struct_rewrite_modifies_def valid_struct_field_def)
subgoal for s apply (erule_tac x = s in allE)+ apply (erule impE, assumption)+ apply (erule_tac t = "t_hrs_update (hrs_mem_update (heap_update (p'' s) (u s(field_setter (λa. Arrays.update a (nat k) (f' s)))))) s" and s = "t_hrs_update (hrs_mem_update (heap_update (p' s) (field_setter (λa. Arrays.update a (nat k) (f' s)) (h_val (hrs_mem (t_hrs s)) (p' s))))) s" in subst) apply (rule lense.upd_cong[where get = t_hrs and upd = t_hrs_update]) apply assumption apply (rule lense.upd_cong[OF read_write_valid_hrs_mem]) apply (cases k, clarsimp) apply (subst heap_update_array_element[symmetric]) apply assumption apply simp apply (subst heap_update_field_root_conv''') apply assumption+ apply (simp add: typ_uinfo_t_def lense.fg_cons) apply (subst h_val_field_from_bytes') apply assumption+ apply (simp add: lense.fg_cons) apply clarsimp apply (subst update_ti_update_ti_t) apply (simp add: size_of_def) apply (subst update_ti_s_adjust_ti_to_bytes_p) apply (erule lense.fg_cons) apply clarsimp apply (subst lense.upd_cong[of field_getter field_setter]) apply auto done done
(* *Theseproducelessredundantoutput(weavoid"t_update(\<lambda>_.foo(tx))x" *wherexissomehugeterm). *Thecatch:werelyontheunifiertoproducea"greedy"instantiationfor?f. *Namely,ifwearematching"?fs(h_valsp)"on *"b_update(a_update(\<lambda>_.foo(h_valsp)))(h_valsp)", *weexpect?ftobeinstantiatedto *"\<lambda>sv.b_update(a_update(\<lambda>_.foov))v" *eventhoughthereareothervalidones. *Itjustsohappensthatisabelle'sunifierproducessuchaninstantiation. *Arewelucky,orpresumptuous?
*) lemma struct_rewrite_modifies_field [heap_abs]: "[ valid_struct_field field_name (field_getter :: ('a::xmem_type) ==> ('f::xmem_type)) field_setter t_hrs t_hrs_update; struct_rewrite_expr P p' p; struct_rewrite_expr Q f' f; ∧s. heap_lift__wrap_h_val (h_val_p' s) (h_val (hrs_mem (t_hrs s)) (p' s)); struct_rewrite_modifies R (λs. t_hrs_update (hrs_mem_update (heap_update (p'' s) (u s (field_setter (f' s))))) s) (λs. t_hrs_update (hrs_mem_update (heap_update (p' s) (field_setter (f' s) (h_val_p' s)))) s); struct_rewrite_guard S (λs. c_guard (p' s)) ]==> struct_rewrite_modifies (λs. P s ∧ Q s ∧ R s ∧ S s) (λs. t_hrs_update (hrs_mem_update (heap_update (p'' s) (u s (field_setter (f' s))))) s) (λs. t_hrs_update (hrs_mem_update (heap_update (Ptr (field_lvalue (p s) field_name)) (f s (h_val (hrs_mem (t_hrs s)) (Ptr (field_lvalue (p s) field_name)))))) s)" apply (clarsimp simp: struct_rewrite_expr_def struct_rewrite_guard_def struct_rewrite_modifies_def valid_struct_field_def heap_lift__wrap_h_val_def) apply (erule_tac x = s in allE)+ apply (erule impE, assumption)+ apply (erule_tac t = "t_hrs_update (hrs_mem_update (heap_update (p'' s) (u s (field_setter (f' s))))) s" and s = "t_hrs_update (hrs_mem_update (heap_update (p' s) (field_setter (f' s) (h_val (hrs_mem (t_hrs s)) (p' s))))) s" in subst) apply (rule lense.upd_cong[where get = t_hrs and upd = t_hrs_update]) apply assumption apply (rule lense.upd_cong[OF read_write_valid_hrs_mem]) apply (subst heap_update_field_root_conv''') apply assumption+ apply (simp add: typ_uinfo_t_def lense.fg_cons) apply (subst h_val_field_from_bytes') apply assumption+ apply (simp add: lense.fg_cons) apply (subst update_ti_update_ti_t) apply (simp add: size_of_def) apply (subst update_ti_s_adjust_ti_to_bytes_p) apply (erule lense.fg_cons) apply (subst lense.upd_cong[where get = field_getter and upd = field_setter]) apply auto done
(* fixme: this is nearly a duplicate. Would a standalone array rule work instead? *) lemma struct_rewrite_modifies_Array_field [heap_abs]: "[ valid_struct_field field_name (field_getter :: ('a::xmem_type) ==> (('f::array_outer_max_size)['n::array_max_count])) field_setter t_hrs t_hrs_update; struct_rewrite_expr P p' p; struct_rewrite_expr Q f' f; ∧s. heap_lift__wrap_h_val (h_val_p' s) (h_val (hrs_mem (t_hrs s)) (p' s)); struct_rewrite_modifies R (λs. t_hrs_update (hrs_mem_update (heap_update (p'' s) (u s (field_setter (λa. Arrays.update a (nat k) (f' s (index a (nat k)))))))) s) (λs. t_hrs_update (hrs_mem_update (heap_update (p' s) (field_setter (λa. Arrays.update a (nat k) (f' s (index a (nat k)))) (h_val_p' s)))) s); struct_rewrite_guard S (λs. c_guard (p' s)) ]==> struct_rewrite_modifies (λs. P s ∧ Q s ∧ R s ∧ S s ∧ 0 ≤ k ∧ nat k < CARD('n)) (λs. t_hrs_update (hrs_mem_update (heap_update (p'' s) (u s (field_setter (λa. Arrays.update a (nat k) (f' s (index a (nat k)))))))) s) (λs. t_hrs_update (hrs_mem_update (heap_update (ptr_coerce (Ptr (field_lvalue (p s) field_name) :: ('f['n]) ptr) +p k) (f s (h_val (hrs_mem (t_hrs s)) (ptr_coerce (Ptr (field_lvalue (p s) field_name) :: ('f['n]) ptr) +p k :: 'f ptr))))) s)" using ptr_coerce.simps[simp del] apply (clarsimp simp: struct_rewrite_expr_def struct_rewrite_guard_def struct_rewrite_modifies_def valid_struct_field_def heap_lift__wrap_h_val_def)
subgoal for s apply (erule_tac x = s in allE)+ apply (erule impE, assumption)+ apply (erule_tac t = "t_hrs_update (hrs_mem_update (heap_update (p'' s) (u s(field_setter (λa. Arrays.update a (nat k) (f' s (index a (nat k)))))))) s" and s = "t_hrs_update (hrs_mem_update (heap_update (p' s) (field_setter (λa. Arrays.update a (nat k) (f' s (index a (nat k)))) (h_val (hrs_mem (t_hrs s)) (p' s))))) s" in subst) apply (rule lense.upd_cong[where get = t_hrs and upd = t_hrs_update]) apply assumption apply (rule lense.upd_cong[OF read_write_valid_hrs_mem]) apply (cases k, clarsimp) apply (subst heap_update_array_element[symmetric]) apply assumption apply simp apply (subst heap_update_field_root_conv''') apply assumption+ apply (simp add: typ_uinfo_t_def lense.fg_cons) apply (subst h_val_field_from_bytes') apply assumption+ apply (simp add: lense.fg_cons) apply (subst heap_access_Array_element[symmetric]) apply simp apply (subst h_val_field_from_bytes') apply assumption+ apply (simp add: lense.fg_cons) apply clarsimp apply (subst update_ti_update_ti_t) apply (simp add: size_of_def) apply (subst update_ti_s_adjust_ti_to_bytes_p) apply (erule lense.fg_cons) apply clarsimp apply (subst lense.upd_cong[of field_getter field_setter]) apply auto done done
lemma struct_rewrite_modifies_globals_setter [heap_abs]: "[ valid_globals_field st old_getter old_setter new_getter new_setter; ∧old. struct_rewrite_expr (P old) (v' old) (v old) ] ==> struct_rewrite_modifies (λs. ∀old. P old s) (λs. old_setter (λold. v' old s) s) (λs. old_setter (λold. v old s) s)" apply (clarsimp simp: valid_globals_field_def struct_rewrite_expr_def struct_rewrite_modifies_def) done
(* Translate Hoare modifies specs generated by the C parser. *Amodifiesspecisoftheform *{(s,s').\<exists>v1v2...s'=s\<lparr>field1:=v1,field2:=v2,...\<rparr>}
* except using mex and meq instead of \<exists> and =. *) lemma abs_spec_may_not_modify_globals[heap_abs]: "abs_spec st (λ_. True) {(a, b). meq b a} {(a, b). meq b a}" apply (clarsimp simp: abs_spec_def meq_def) done
lemma abs_spec_modify_global[heap_abs]: "valid_globals_field st old_getter old_setter new_getter new_setter ==> abs_spec st (λ_. True) {(a, b). C a b} {(a, b). C' a b} ==> abs_spec st (λ_. True) {(a, b). mex (λx. C (new_setter (λ_. x) a) b)} {(a, b). mex (λx. C' (old_setter (λ_. x) a) b)}" apply (fastforce simp: abs_spec_def mex_def valid_globals_field_def) done (* NB: Polish will unfold meq and mex. The reason is explained there. *)
(* Signed words are stored on the heap as unsigned words. *)
lemma to_bytes_signed_word: "to_bytes (x :: 'a::len8 signed word) p = to_bytes (scast x :: 'a word) p" by (clarsimp simp: uint_scast to_bytes_def typ_info_word word_rsplit_def)
lemma from_bytes_signed_word: "length p = len_of TYPE('a) div 8 ==> (from_bytes p :: 'a::len8 signed word) = ucast (from_bytes p :: 'a word)" by (clarsimp simp: from_bytes_def word_rcat_def scast_def cast_simps typ_info_word)
lemma hrs_mem_update_signed_word: "hrs_mem_update (heap_update (ptr_coerce p :: 'a::len8 word ptr) (scast val :: 'a::len8 word)) = hrs_mem_update (heap_update p (val :: 'a::len8 signed word))" apply (rule ext) apply (clarsimp simp: hrs_mem_update_def split_def) apply (clarsimp simp: heap_update_def to_bytes_signed_word
size_of_def typ_info_word) done
lemma h_val_signed_word: "(h_val a p :: 'a::len8 signed word) = ucast (h_val a (ptr_coerce p :: 'a word ptr))" apply (clarsimp simp: h_val_def) apply (subst from_bytes_signed_word) apply (clarsimp simp: size_of_def typ_info_word) apply (clarsimp simp: size_of_def typ_info_word) done
lemma align_of_signed_word: "align_of TYPE('a::len8 signed word) = align_of TYPE('a word)" by (clarsimp simp: align_of_def typ_info_word)
lemma size_of_signed_word: "size_of TYPE('a::len8 signed word) = size_of TYPE('a word)" by (clarsimp simp: size_of_def typ_info_word)
lemma word_rsplit_signed: "(word_rsplit (ucast v' :: ('a::len) signed word) :: 8 word list) = word_rsplit (v' :: 'a word)" apply (clarsimp simp: word_rsplit_def) apply (clarsimp simp: cast_simps) done
lemma heap_update_signed_word: "heap_update (ptr_coerce p :: 'a word ptr) (scast v) = heap_update (p :: ('a::len8) signed word ptr) v" "heap_update (ptr_coerce p' :: 'a signed word ptr) (ucast v') = heap_update (p' :: ('a::len8) word ptr) v'" apply (auto simp: heap_update_def to_bytes_def typ_info_word word_rsplit_def cast_simps uint_scast) done
lemma heap_update_padding_signed_word: "heap_update_padding (ptr_coerce p :: 'a word ptr) (scast v) bs = heap_update_padding (p :: ('a::len8) signed word ptr) v bs" "heap_update_padding (ptr_coerce p :: 'a word ptr) (ucast v) bs = heap_update_padding (p :: ('a::len8) signed word ptr) v bs" "heap_update_padding (ptr_coerce p' :: 'a signed word ptr) (ucast v') bs = heap_update_padding (p' :: ('a::len8) word ptr) v' bs" by (auto simp: heap_update_padding_def to_bytes_def typ_info_word word_rsplit_def cast_simps uint_scast)
lemma typ_heap_simulation_c_guard: "[ typ_heap_simulation st r w v t_hrs t_hrs_update; v (st s) p ]==> c_guard p" by (clarsimp simp: valid_implies_cguard.valid_implies_c_guard [OF typ_heap_simulation.axioms(5)])
abbreviation (input)
scast_f :: "(('a::len) signed word ptr ==> 'a signed word) ==> ('a word ptr ==> 'a word)" where "scast_f f ≡ (λp. scast (f (ptr_coerce p)))"
abbreviation (input)
ucast_f :: "(('a::len) word ptr ==> 'a word) ==> ('a signed word ptr ==> 'a signed word)" where "ucast_f f ≡ (λp. ucast (f (ptr_coerce p)))"
abbreviation (input)
cast_f' :: "('a ptr ==> 'x) ==> ('b ptr ==> 'x)" where "cast_f' f ≡ (λp. f (ptr_coerce p))"
lemma read_write_validE_weak: "[ lense r w; [∧f s. r (w f s) = f (r s); ∧f s. f (r s) = (r s) ==> w f s = s ]==> R ] ==> R" apply atomize_elim apply (unfold lense_def) apply metis done
lemma lense_transcode: "[ lense r w; ∧v. f' (f v) = v; ∧v. f (f' v) = v ]==> lense (λs. f' (r s)) (λg s. w (λold. f (g (f' old))) s)" apply (unfold lense_def) apply (simp add:comp_def) done
(* fixme: This is a sublocale relation.*) lemma typ_heap_simulation_signed_word: notes align_of_signed_word [simp]
size_of_signed_word [simp]
heap_update_signed_word [simp] shows "[ typ_heap_simulation st (r :: 's ==> ('a::len8) word ptr ==> 'a word) w v t_hrs t_hrs_update ] ==> typ_heap_simulation st (λs p. ucast (r s (ptr_coerce p)) :: 'a signed word) (λp f. (w (ptr_coerce p) ((λx. ucast (f (ucast x)))) )) (λs p. v s (ptr_coerce p)) t_hrs t_hrs_update" apply (clarsimp simp: typ_heap_simulation_def
map.compositionality o_def c_guard_ptr_coerce) apply (intro conjI impI)
subgoal apply (clarsimp simp add: read_simulation_def) apply (drule_tac x=s in spec)+ apply (drule_tac x="ptr_coerce p"in spec)+ by (simp add: h_val_signed_word)
subgoal apply (clarsimp simp add: write_simulation_def write_simulation_axioms_def)
subgoal for s p bs x apply (erule_tac x=s in allE) apply (erule_tac x="(PTR_COERCE('a signed word → 'a word) p)"in allE) apply clarsimp apply (erule_tac x=bs in allE) apply clarsimp apply (erule_tac x= " UCAST('a signed → 'a) x"in allE) using heap_update_padding_signed_word by (metis (mono_tags, lifting) hrs_mem_update_cong) done
subgoal by (clarsimp simp add: write_preserves_valid_def)
subgoal apply (clarsimp simp add: valid_implies_cguard_def) apply (drule spec, drule spec, erule (1) impE)+ apply (subst (asm) c_guard_ptr_coerce, simp, simp) by blast
subgoal apply (simp (no_asm_use) add: valid_only_typ_desc_dependent_def) by blast
subgoal
supply scast_ucast_norm[simp del]
supply ucast_ucast_id[simp] apply (unfold_locales)
subgoal by (simp add: pointer_lense.read_write_same)
subgoal by (simp add: pointer_lense.write_same)
subgoal by (simp add: pointer_lense.write_comp comp_def)
subgoal by (simp add: pointer_lense.write_other_commute) done done
lemma c_guard_ptr_ptr_coerce: "[ c_guard (a :: ('a::c_type) ptr ptr); ptr_val a = ptr_val b ]==> c_guard (b :: ('b::c_type) ptr ptr)" by (clarsimp simp: c_guard_def ptr_aligned_def c_null_guard_def)
abbreviation (input)
ptr_coerce_f :: "('a ptr ptr ==> 'a ptr) ==> ('b ptr ptr ==> 'b ptr)" where "ptr_coerce_f f ≡ (λp. ptr_coerce (f (ptr_coerce p)))"
(* fixme: this is a sublocale *) lemma typ_heap_simulation_ptr_coerce: "[ typ_heap_simulation st (r :: 's ==> ('a::c_type) ptr ptr ==> 'a ptr) w v t_hrs t_hrs_update ] ==> typ_heap_simulation st (λs p. ptr_coerce (r s (ptr_coerce p)) :: ('b::c_type) ptr) (λp f. (w (ptr_coerce p) ((λx. ptr_coerce (f (ptr_coerce x)))))) (λs p. v s (ptr_coerce p)) t_hrs t_hrs_update" apply (clarsimp simp: typ_heap_simulation_def fun_upd_def) apply (intro conjI impI)
subgoal by (clarsimp simp: read_simulation_def h_val_def typ_info_ptr from_bytes_def)
subgoal apply (clarsimp simp add: write_simulation_def write_simulation_axioms_def) apply (erule allE, erule allE, erule (1) impE)+ apply (erule_tac x="bs"in allE) apply clarsimp apply (erule_tac x="ptr_coerce x"in allE) apply (clarsimp simp: heap_update_padding_def [abs_def] to_bytes_def typ_info_ptr) done
subgoal apply (clarsimp simp add: write_preserves_valid_def) done
subgoal apply (clarsimp simp add: valid_implies_cguard_def) apply (drule spec, drule spec, erule (1) impE)+ apply (subst (asm) c_guard_ptr_coerce, simp, simp) by blast
subgoal apply (simp (no_asm_use) add: valid_only_typ_desc_dependent_def) by blast
subgoal apply (simp (no_asm_use) add: pointer_lense_def) apply clarsimp by (metis comp_apply ptr_coerce_id ptr_coerce_idem) done
(* *Nastyhack:Convertsignedwordpointers-to-pointerstoword *pointers-to-pointers. * *Theideahereisthattypesoftheform: * *int***x; * *needtobeconvertedtoaccessesofthe"unsignedint***"heap.
*) lemmas signed_typ_heap_simulations =
typ_heap_simulation_signed_word
typ_heap_simulation_ptr_coerce [where 'a="('x::len8) word"and 'b="('x::len8) signed word"]
typ_heap_simulation_ptr_coerce [where 'a="('x::len8) word ptr"and 'b="('x::len8) signed word ptr"]
typ_heap_simulation_ptr_coerce [where 'a="('x::len8) word ptr ptr"and 'b="('x::len8) signed word ptr ptr"]
typ_heap_simulation_ptr_coerce [where 'a="('x::len8) word ptr ptr ptr"and 'b="('x::len8) signed word ptr ptr ptr"]
(* *Theabovelemmasgenerateamessinitsoutput,generatingthings *like: * *(heap_w32_update *(\<lambda>ab.scast *(((\<lambda>b.ucast(a(ptr_coerceb)))(a:=3)) *(ptr_coerceb)))) * *Thistheoremcleansitupalittle.
*) lemma ptr_coerce_eq: "(ptr_coerce x = ptr_coerce y) = (x = y)" by (cases x, cases y, auto)
lemma signed_word_heap_opt [L2opt]: "(scast (((λx. ucast (a (ptr_coerce x))) (p := v :: 'a::len signed word)) (b :: 'a signed word ptr))) = ((a(ptr_coerce p := (scast v :: 'a word))) ((ptr_coerce b) :: 'a word ptr))" by (auto simp: fun_upd_def ptr_coerce_eq)
lemma signed_word_heap_ptr_coerce_opt [L2opt]: "(ptr_coerce (((λx. ptr_coerce (a (ptr_coerce x))) (p := v :: 'a ptr)) (b :: 'a ptr ptr))) = ((a(ptr_coerce p := (ptr_coerce v :: 'b ptr))) ((ptr_coerce b) :: 'b ptr ptr))" by (auto simp: fun_upd_def ptr_coerce_eq)
(* array rules *) lemma heap_abs_expr_c_guard_array [heap_abs]: "[ typ_heap_simulation st r w v t_hrs t_hrs_update; abs_expr st P x' (λs. ptr_coerce (x s) :: 'a ptr) ]==> abs_guard st (λs. P s ∧ (∀a ∈ set (array_addrs (x' s) CARD('b)). v s a)) (λs. c_guard (x s :: ('a::array_outer_max_size, 'b::array_max_count) array ptr))" apply (clarsimp simp: abs_expr_def abs_guard_def simple_lift_def root_ptr_valid_def) apply (subgoal_tac "∀a∈set (array_addrs (x' (st s)) CARD('b)). c_guard a") apply (erule allE, erule (1) impE) apply (rule c_guard_array_c_guard) apply (subst (asm) (2) set_array_addrs) apply force apply clarsimp apply (erule (1) my_BallE) apply (drule (1) typ_heap_simulation_c_guard) apply simp done
(* begin machinery for heap_abs_array_update *) lemma fold_over_st: "[ xs = ys; P s; ∧s x. x ∈ set xs ∧ P s ==> P (g x s) ∧ f x (st s) = st (g x s) ]==> fold f xs (st s) = st (fold g ys s)" apply (erule subst) apply (induct xs arbitrary: s) apply simp apply simp done
lemma fold_lift_write: "[ xs = ys; lense r w ]==> fold (λi. w (f i)) xs s = w (fold f ys) s" apply (erule subst) apply (induct xs arbitrary: s) apply (simp add: lense.upd_same) apply (simp add: lense.upd_compose) done
(* cf. heap_update_nmem_same *) lemma fold_heap_update_list_nmem_same: "[ n * size_of TYPE('a :: mem_type) < addr_card; n * size_of TYPE('a) ≤ k; k < addr_card; ∧i h. length (pad i h) = size_of TYPE('a) ]==> h (ptr_val (p :: 'a ptr) + of_nat k) = (fold (λi h. heap_update_list (ptr_val (p +p int i)) (to_bytes (val i h :: 'a) (pad i h)) h) [0..<n] h) (ptr_val p + of_nat k)" apply (induct n arbitrary: k) apply simp apply (clarsimp simp: CTypesDefs.ptr_add_def simp del: mult_Suc) apply (subst heap_update_nmem_same) apply (subst len) apply simp apply (simp add: intvl_def) apply (intro allI impI) apply (subst (asm) of_nat_mult[symmetric] of_nat_add[symmetric])+ apply (rename_tac j) apply (erule_tac Q = "of_nat k = of_nat (n * size_of TYPE('a) + j)"in contrapos_pn) apply (subst of_nat_inj) apply (subst len_of_addr_card) apply simp apply (subst len_of_addr_card) apply simp apply simp apply simp done
lemma heap_list_of_disjoint_fold_heap_update_list: "[ n * size_of TYPE('a :: mem_type) < addr_card; n * size_of TYPE('a) + k < addr_card; ∧i h. length (pad i h) = size_of TYPE('a) ]==> heap_list (fold (λi h. heap_update_list (ptr_val ((p :: 'a ptr) +p int i)) (to_bytes (val i h :: 'a) (pad i h)) h) [0..<n] h) k (ptr_val (p +p int n)) = heap_list h k (ptr_val (p +p int n))" apply (rule nth_equalityI, force)
subgoal for i apply (clarsimp simp: heap_list_nth) apply (rule subst[where t = "ptr_val (p +p int n) + of_nat i" and s = "ptr_val p + of_nat (n * size_of TYPE('a) + i)"]) apply (clarsimp simp: CTypesDefs.ptr_add_def) apply (rule fold_heap_update_list_nmem_same[symmetric]) apply simp_all done done
(* remove false dependency *) lemma fold_heap_update_list: "n * size_of TYPE('a :: mem_type) < 2^addr_bitsize ==> fold (λi h. heap_update_list (ptr_val ((p :: 'a ptr) +p int i)) (to_bytes (val i :: 'a) (heap_list h (size_of TYPE('a)) (ptr_val (p +p int i)))) h) [0..<n] h = fold (λi. heap_update_list (ptr_val (p +p int i)) (to_bytes (val i) (heap_list h (size_of TYPE('a)) (ptr_val (p +p int i))))) [0..<n] h" apply (induct n) apply simp apply clarsimp apply (subst heap_list_of_disjoint_fold_heap_update_list) apply (simp add: len_of_addr_card[symmetric])+ done
(* cf. access_ti_list_array *) lemma access_ti_list_array_unpacked: "[∀n. size_td_tuple (f n) = v3; length xs = v3 * n; ∀m xs. length xs = v3 ∧ m < n ⟶ access_ti_tuple (f m) (FCP g) xs = h m xs ]==> access_ti_list (map f [0 ..< n]) (FCP g) xs = foldl (@) [] (map (λm. h m (take v3 (drop (v3 * m) xs))) [0 ..< n])" apply (subgoal_tac "∀ys. size_td_list (map f ys) = v3 * length ys") prefer2
subgoal apply (rule allI)
subgoal for ys by (induct ys) auto done apply (induct n arbitrary: xs) apply simp apply (simp add: access_ti_append) apply (rule foldl_cong) apply simp apply (rule map_cong[OF refl]) apply (subst take_drop) apply (subst take_take) apply (subst min_absorb1) apply clarsimp apply (metis Suc_leI mult_Suc_right nat_mult_le_cancel_disj) apply (subst take_drop[symmetric]) apply (rule refl) apply simp done
lemma concat_nth_chunk: "[∀x ∈ set xs. length (f x) = chunk; n < length xs ] ==> take chunk (drop (n * chunk) (concat (map f xs))) = f (xs ! n)" apply (induct xs arbitrary: n, force)
subgoal for x xs n apply (cases n) apply clarsimp apply clarsimp done done
(* fixme: proof should be much nicer when done within locale *) lemma array_update_split: "[ typ_heap_simulation st (r :: 's ==> ('a::array_outer_max_size) ptr ==> 'a) w v t_hrs t_hrs_update; ∀x ∈ set (array_addrs (ptr_coerce p) CARD('b::array_max_count)). v (st s) x ]==> st (t_hrs_update (hrs_mem_update (heap_update p (arr :: 'a['b]))) s) = fold (λi. w (ptr_coerce p +p int i) (λx. index arr i)) [0 ..< CARD('b)] (st s)" apply (clarsimp simp: typ_heap_simulation_def heap_raw_state_def valid_implies_cguard_def read_simulation_def write_preserves_valid_def)
(* unwrap st *) apply (subst fold_over_st[OF refl, where P = "λs. ∀x∈set (array_addrs (ptr_coerce p) CARD('b)). v (st s) x" and g = "λi. t_hrs_update (hrs_mem_update (heap_update (ptr_coerce p +p int i) (index arr i)))"]) apply simp
subgoal for sa x apply (subgoal_tac "v (st sa) (ptr_coerce p +p int x)") apply clarsimp apply (clarsimp simp: set_array_addrs) apply metis done apply (rule arg_cong[where f = st]) apply (subst hrs_mem_update_def)+
(* unwrap t_hrs_update *) apply (subst fold_lift_write[OF refl, where w = t_hrs_update]) apply assumption apply (rule arg_cong[where f = "λf. t_hrs_update f s"]) apply (rule ext) apply (subst fold_lift_write[OF refl, where r = fst and w = "λf s. case s of (h, z) ==> (f h, z)"]) apply (simp (no_asm) add: lense_def) apply clarsimp
(* split up array update *) apply (clarsimp simp: heap_update_def[abs_def]) apply (subst coerce_heap_update_to_heap_updates[unfolded foldl_conv_fold, where chunk = "size_of TYPE('a)"and m = "CARD('b)"]) apply (rule size_of_array[simplified mult.commute]) apply simp
(* remove false dependency *) apply (subst fold_heap_update_list[OF array_count_size]) apply (rule fold_cong[OF refl refl])
subgoal for a x
apply (clarsimp simp: CTypesDefs.ptr_add_def) apply (rule arg_cong[where f = "heap_update_list (ptr_val p + of_nat x * of_nat (size_of TYPE('a)))"])
lemma fold_update_id: "[ lense getter setter; ∀i ∈ set xs. ∀j ∈ set xs. (i = j) = (ind i = ind j); ∀i ∈ set xs. val i = getter s (ind i) ]==> fold (λi. setter (λx. x(ind i := val i))) xs s = s" apply (induct xs) apply simp apply (rename_tac a xs) apply clarsimp apply (subgoal_tac "setter (λx. x(ind a := getter s (ind a))) s = s") apply simp apply (subst (asm) lense_def) apply simp done
lemma fold_update_id': "[ pointer_lense r w; ∀i ∈ set xs. ∀j ∈ set xs. (i = j) = (ind i = ind j); ∀i ∈ set xs. val i = r s (ind i) ]==> fold (λi. w (ind i) (λ_. val i)) xs s = s" apply (induct xs) apply simp apply (rename_tac a xs) apply clarsimp apply (subgoal_tac "w (ind a) (λx. r s (ind a)) s = s") apply simp apply (subst (asm) pointer_lense_def) apply simp done
lemma array_count_index: "[ i < CARD('b::array_max_count); j < CARD('b) ] ==> (i = j) = ((of_nat (i * size_of TYPE('a::array_outer_max_size)) :: addr) = of_nat (j * size_of TYPE('a)))" apply (rule subst[where t = "i = j"and s = "i * size_of TYPE('a) = j * size_of TYPE('a)"]) apply clarsimp apply (subgoal_tac "∧ i. i < CARD('b) ==> i * size_of TYPE('a) < 2 ^ LENGTH(addr_bitsize)") apply (rule of_nat_inj[symmetric]; force) apply (rule subst[where t = "len_of TYPE(addr_bitsize)"and s = addr_bitsize], force) apply (rule less_trans) apply (erule_tac b = "CARD('b)"in mult_strict_right_mono) apply (rule sz_nzero) apply (rule array_count_size) done
(* end machinery for heap_abs_array_update *)
lemma le_outside_intvl: "p < a ==> 0 ∉ {a ..+b} ==> p ∉ {a ..+b}" apply (clarsimp simp: intvl_def not_le not_less) by (metis Word_Lemmas_Internal.word_wrap_of_natD add_increasing2 le0 le_iff_add less_le not_less)
lemma intvl_mult_split: "{p ..+ a * b} = (∪i<b. {p + of_nat (i * a) ..+ a})" proof cases assume a: "0 < a" note of_nat_add[simp del, symmetric, simp] of_nat_mult[simp del, symmetric, simp] show ?thesis using a apply (clarsimp simp: intvl_def, intro set_eqI iffI; clarsimp)
subgoal for i by (intro bexI[of _ "i div a"] exI[of _ "i mod a"])
(simp_all add: dme pos_mod_bound less_mult_imp_div_less ac_simps)
subgoal for j k by (intro exI[of _ "j * a + k"]) (simp add: nat_index_bound) done qed simp
lemma intvl_mul_disjnt: fixes n i :: "'a::len word" assumes n: "unat n < b"and i: "unat i < b"and b: "sz * b ≤ 2^LENGTH('a)" assumes ni: "n ≠ i" shows"{n * word_of_nat sz..+sz} ∩ {i * word_of_nat sz..+sz} = {}" proof -
{ fix j l assume j: "j < sz"and l: "l < sz" assume"n * word_of_nat sz + word_of_nat j = i * word_of_nat sz + word_of_nat l" thenhave"(word_of_nat (unat n * sz + j) :: 'a word) = word_of_nat (unat i * sz + l)"by simp moreoverhave"unat n * sz + j < 2^LENGTH('a)" by (intro less_le_trans[OF nat_index_bound b] n j) moreoverhave"unat i * sz + l < 2^LENGTH('a)" by (intro less_le_trans[OF nat_index_bound b] i l) ultimatelyhave"(unat n * sz + j) div sz = (unat i * sz + l) div sz" by (subst (asm) of_nat_inj) simp_all thenhave"unat n = unat i" using j l by simp with ni have False by simp } thenshow ?thesis by (auto simp: intvl_def) qed
lemma array_disj_helper: fixes p :: "('a::mem_type['b]) ptr" assumes ni: "n < CARD('b)""i < CARD('b)""n ≠ i" assumes valid: "∀x∈set (array_addrs (PTR_COERCE('a['b] → 'a) p) CARD('b)). c_guard x" shows"{ptr_val p + word_of_nat n * word_of_nat (size_of TYPE('a))..+size_of TYPE('a)} ∩ {ptr_val p + word_of_nat i * word_of_nat (size_of TYPE('a))..+size_of TYPE('a)} = {}" proof - have [arith]: "CARD('b) ≤ size_of TYPE('a) * CARD('b)" using sz_nzero[where 'a='a, arith] by simp
have"0 ∉ (∪b<CARD('b). {ptr_val p + of_nat (b * size_of TYPE('a)) ..+ size_of TYPE('a)})" using valid apply (clarsimp simp: set_array_addrs c_guard_def c_null_guard_def)
subgoal premises prems for b using prems(2-) prems(1)[rule_format, OF exI, of "Ptr (ptr_val p + word_of_nat b * word_of_nat (size_of TYPE('a)))" b] by (simp add: ptr_add_def) done thenhave"0 ∉ {ptr_val p ..+ size_of TYPE('a) * CARD('b)}" unfolding intvl_mult_split . from zero_not_in_intvl_no_overflow[OF this] have"size_of TYPE('a) * CARD('b) ≤ addr_card" by (simp add: addr_card) moreovernote ni ultimatelyshow ?thesis by (smt (verit, ccfv_SIG) ‹CARD('b) ≤ size_of TYPE('a) * CARD('b)› addr_card_len_of_conv
intvl_disj_offset intvl_mul_disjnt order_less_le_trans unat_of_nat_len) qed
theorem heap_abs_array_update [heap_abs]: "[ typ_heap_simulation st (r :: 's ==> 'a ptr ==> 'a) w v t_hrs t_hrs_update; abs_expr st Pb b' b; abs_expr st Pn n' n; abs_expr st Pv y' y ]==> abs_modifies st (λs. Pb s ∧ Pn s ∧ Pv s ∧ n' s < CARD('b) ∧ (∀ptr ∈ set (array_addrs (ptr_coerce (b' s)) CARD('b)). (v s ptr))) (λs. w (ptr_coerce (b' s) +p int (n' s)) (λv. y' s) s) (λs. t_hrs_update (hrs_mem_update ( heap_update (b s) (Arrays.update ((h_val (hrs_mem (t_hrs s)) (b s)) :: ('a::array_outer_max_size)['b::array_max_count]) (n s) (y s)))) s)" apply (clarsimp simp: abs_modifies_def abs_expr_def)
subgoal for s (* rewrite heap_update of array *) apply (subst array_update_split
[where st = st and t_hrs = t_hrs and t_hrs_update = t_hrs_update]) apply assumption apply assumption apply (clarsimp simp: typ_heap_simulation_def valid_implies_cguard_def read_simulation_def write_preserves_valid_def) apply (drule write_simulation.write_commutes_atomic) apply (subst fold_cong[OF refl refl, where g = "λi. w (ptr_coerce (b' (st s)) +p int i) (λx. if i = n' (st s) then y' (st s) else r (st s) (ptr_coerce (b' (st s)) +p int i))"])
subgoal for x apply (cases "x = n' (st s)") apply simp apply (subst index_update2) apply simp apply simp apply (rule arg_cong[where x = "index (h_val (hrs_mem (t_hrs s)) (b' (st s))) x"]) apply (subst heap_access_Array_element) apply simp apply (clarsimp simp: set_array_addrs) apply metis done
(* split away the indices that don't change *) apply (subst split_upt_on_n[where n = "n s"]) apply simp apply clarsimp thm fold_update_id
(* [Suc n..<CARD('b)] doesn't change *) apply (subst fold_update_id') apply assumption apply (clarsimp simp: CTypesDefs.ptr_add_def) apply (subst of_nat_mult[symmetric])+ apply (erule array_count_index) apply assumption apply clarsimp (* index n is disjoint *) apply (subst pointer_lense.read_write_other[where r = r and w = w]) apply assumption apply (clarsimp simp: CTypesDefs.ptr_add_def disjnt_def) apply (rule array_disj_helper) apply simp apply assumption apply simp apply blast apply (rule refl) apply (rule refl) done done
(* Array access, which is considerably simpler than updating. *) lemma heap_abs_array_access[heap_abs]: "[ typ_heap_simulation st (r :: 's ==> ('a::xmem_type) ptr ==> 'a) w v t_hrs t_hrs_update; abs_expr st Pb b' b; abs_expr st Pn n' n ]==> abs_expr st (λs. Pb s ∧ Pn s ∧ n' s < CARD('b::finite) ∧ v s (ptr_coerce (b' s) +p int (n' s))) (λs. r s (ptr_coerce (b' s) +p int (n' s))) (λs. index (h_val (hrs_mem (t_hrs s)) (b s :: ('a['b]) ptr)) (n s))" apply (clarsimp simp: typ_heap_simulation_def abs_expr_def valid_implies_cguard_def read_simulation_def write_simulation_def write_preserves_valid_def) apply (subst heap_access_Array_element) apply simp apply (simp add: set_array_addrs) done
lemma the_fun_upd_lemma1: "(λx. the (f x))(p := v) = (λx. the ((f (p := Some v)) x))" by auto
lemma the_fun_upd_lemma2: "∃z. f p = Some z ==> (λx. ∃z. (f (p := Some v)) x = Some z) = (λx. ∃z. f x = Some z) " by auto
lemma the_fun_upd_lemma3: "((λx. the (f x))(p := v)) x = the ((f (p := Some v)) x)" by simp
lemma the_fun_upd_lemma4: "∃z. f p = Some z ==> (∃z. (f (p := Some v)) x = Some z) = (∃z. f x = Some z) " by simp
(* Used by heap_abs_syntax to simplify signed word updates. *) lemma sword_update: "∧ptr :: ('a :: len) signed word ptr. (λ(x :: 'a word ptr ==> 'a word) p :: 'a word ptr. if ptr_coerce p = ptr then scast (n :: 'a signed word) else x (ptr_coerce p)) = (λ(old :: 'a word ptr ==> 'a word) x :: 'a word ptr. if x = ptr_coerce ptr then scast n else old x)" by force
from i_bound j_bound disj have"ptr_val p + word_of_nat i ≠ ptr_val q + word_of_nat j" by (auto simp add: intvl_def disjnt_def) with eq show False by (simp add: i_def j_def add.commute add.left_commute) qed
named_theorems select_conv and select_conv_independent and valid_conv and valid_array_conv and
gen_update_commute and gen_outer_update_commute and update_commute
locale pointer_array_lense = pointer_lense r w for r:: "'s ==> 'a:: array_outer_max_size ptr ==> 'a" and w:: "'a ptr ==> ('a ==> 'a) ==> 's ==> 's" begin
definition heap_array ::"'s ==> ('a['b::array_max_count]) ptr ==> 'a['b]"where "heap_array s p = FCP (λi. r s (array_ptr_index p False i))"
definition heap_array_map :: "('a['b]) ptr ==> ('a['b::array_max_count] ==> 'a['b])==> 's ==> 's"where "heap_array_map p f s ≡ fold (λi. w (array_ptr_index p False i) (λ_. (f (heap_array s p)).[i])) [0..<CARD('b)] s"
lemma element_heap_eq_heap_array_eq [select_conv]: "r s = r s' ==> heap_array s = heap_array s'" apply (rule ext) apply (simp add: heap_array_def) done
lemma fold_write_independent_field: fixes p::"('a['b::array_max_count]) ptr" assumes field_independent: "(∧p x s. f (w p (λ_. x) s) = f s)" assumes n_bound: "n ≤ CARD('b)" shows"f (fold (λi. w (array_ptr_index p False i) (λ_. g (heap_array s p).[i])) [0..<n] t) = f t" using n_bound proof (induct n arbitrary: t) case0 thenshow ?caseby simp next case (Suc n) thenshow ?caseusing field_independent by simp qed
lemma heap_array_map_independent_field [select_conv_independent]: assumes field_independent: "(∧p x s. f (w p (λ_. x) s) = f s)" shows"f (heap_array_map p g s) = f s" apply (simp add: heap_array_map_def) apply (rule fold_write_independent_field) apply (rule field_independent) apply simp done
lemma fold_write_independent_field_upd_commute: fixes p::"('a['b::array_max_count]) ptr" assumes write_commute: "∧p x s. (f_upd (w p (λ_. x) s)) = w p (λ_. x) (f_upd s)" assumes n_bound: "n ≤ CARD('b)" shows"f_upd (fold (λi. w (array_ptr_index p False i) (λ_. g (heap_array s p).[i])) [0..<n] t) = fold (λi. w (array_ptr_index p False i) (λ_. g (heap_array s p).[i])) [0..<n] (f_upd t)" using n_bound proof (induct n arbitrary: t) case0 thenshow ?caseby simp next case (Suc n) thenshow ?caseusing write_commute by simp qed
lemma heap_array_map_independent_field_commute [gen_update_commute]: assumes read_independent: "∧s. r (f_upd s) = r s" assumes write_independent: "∧p x s. (f_upd (w p (λ_. x) s)) = w p (λ_. x) (f_upd s)" shows"f_upd (heap_array_map p g s) = (heap_array_map p g (f_upd s))" apply (simp add: heap_array_map_def element_heap_eq_heap_array_eq [OF read_independent]) apply (rule fold_write_independent_field_upd_commute) apply (rule write_independent) apply simp done
lemma heap_array_index[simp]: "i < CARD('b) ==> heap_array s (p::('a['b::array_max_count]) ptr).[i] = r s (array_ptr_index p False i)" by (simp add: heap_array_def)
lemma read_write_same_fold_aux: fixes p::"('a['b::array_max_count]) ptr" assumes n_bound: "n ≤ CARD ('b)" assumes i_bound: "i < n" shows"r (fold (λi. w (array_ptr_index p False i) (λ_. f (heap_array s p).[i])) [0..<n] s) (array_ptr_index p False i) = f (heap_array s p).[i]" using n_bound i_bound proof (induct n arbitrary: i s) case0 thenshow ?caseby simp next case (Suc n) from Suc.prems obtain i_bound: "i < Suc n"and Suc_n_bound: "Suc n ≤ CARD ('b)"and
n_bound: "n ≤ CARD('b)"and n_bound': "n < CARD('b)"by auto have size: "CARD('b) * size_of TYPE('a ) < 2 ^ addr_bitsize" using Padding_Equivalence.array_count_size by blast show ?case proof (cases "i=n") case True show ?thesis apply (simp add: True) apply (simp add: read_write_same) done next case False from False i_bound have i_bound': "i < n"by simp have disj: "disjnt (ptr_span (array_ptr_index p False n)) (ptr_span (array_ptr_index p False i))" by (rule ptr_span_array_index_disj [OF n_bound' i_bound']) show ?thesis apply (simp add: False) apply (simp add: read_write_other disj ) apply (rule Suc.hyps [OF n_bound i_bound']) done qed qed
lemma array_read_write_same: "heap_array (heap_array_map p f s) p = f (heap_array s p)" apply (subst cart_eq ) apply clarsimp apply (simp add: heap_array_map_def) apply (rule read_write_same_fold_aux) by simp_all
lemma read_write_other_fold_aux: fixes p::"('a['b::array_max_count]) ptr" fixes p'::"('a['b::array_max_count]) ptr" assumes n_bound: "n ≤ CARD ('b)" assumes i_bound: "i < CARD ('b)" assumes disj:"disjnt (ptr_span p) (ptr_span p')" shows"r (fold (λi. w (array_ptr_index p False i) (λ_. f (heap_array s p).[i])) [0..<n] s) (array_ptr_index p' False i) = r s (array_ptr_index p' False i)" using n_bound i_bound proof (induct n arbitrary: i s) case0 thenshow ?caseby simp next case (Suc n) from Suc.prems obtain Suc_n_bound: "Suc n ≤ CARD ('b)"and
n_bound: "n ≤ CARD('b)"and n_bound': "n < CARD('b)"and
i_bound: "i < CARD('b)"by auto have size: "CARD('b) * size_of TYPE('a ) < 2 ^ addr_bitsize" using Padding_Equivalence.array_count_size by blast
from ptr_span_array_ptr_index_disj [OF n_bound' i_bound disj] show ?case apply (simp add: read_write_other) apply (rule Suc.hyps [OF n_bound i_bound]) done qed
lemma array_read_write_other: fixes p::"('a['b::array_max_count]) ptr" fixes p'::"('a['b::array_max_count]) ptr" assumes disj:"disjnt (ptr_span p) (ptr_span p')" shows"heap_array (heap_array_map p f s) p' = heap_array s p'" apply (subst cart_eq ) apply clarsimp apply (simp add: heap_array_map_def) apply (rule read_write_other_fold_aux [OF _ _ disj]) by simp_all
lemma write_cong_fold_aux: fixes p::"('a['b::array_max_count]) ptr" assumes f_f': "f (heap_array s p) = f' (heap_array s p)" assumes n_bound: "n ≤ CARD('b)" shows"fold (λi. w (array_ptr_index p False i) (λ_. f (heap_array s p).[i])) [0..<n] s = fold (λi. w (array_ptr_index p False i) (λ_. f' (heap_array s p).[i])) [0..<n] s" using n_bound proof (induct n arbitrary:) case0 thenshow ?caseby simp next case (Suc n) have suc_n_bound: "Suc n ≤ CARD('b)"using Suc.prems .
define s' where"s' = (fold (λi. w (array_ptr_index p False i) (λ_. f' (heap_array s p).[i])) [0..<n] s)"
from f_f' suc_n_bound have"(λ_. f (heap_array s p).[n]) = (λ_. f' (heap_array s p).[n])" by auto hence eq: "(λ_. f (heap_array s p).[n]) (r s' (array_ptr_index p False n)) = (λ_. f' (heap_array s p).[n]) (r s' (array_ptr_index p False n))"by metis from Suc show ?caseby (simp add: write_cong [OF eq]) qed
lemma array_write_cong: fixes p::"('a['b::array_max_count]) ptr" assumes eq: "f (heap_array s p) = f' (heap_array s p)" shows"heap_array_map p f s = heap_array_map p f' s" apply (simp add: heap_array_map_def) apply (rule write_cong_fold_aux) apply (rule eq) apply simp done
lemma array_write_same_triv[simp]: fixes p::"('a['b::array_max_count]) ptr" shows"heap_array_map p (λ_. f (heap_array s p)) s = heap_array_map p f s" using array_write_cong by fastforce
lemma array_write_fold_same_aux: fixes p::"('a['b::array_max_count]) ptr" assumes f_id: "f (heap_array s p) = heap_array s p" assumes n_bound: "n ≤ CARD('b)" shows"fold (λi. w (array_ptr_index p False i) (λ_. f (heap_array s p).[i])) [0..<n] s = s" using n_bound proof (induct n) case0 thenshow ?caseby simp next case (Suc n) from Suc.prems f_id have f_n_id: "f (heap_array s p).[n] = r s (array_ptr_index p False n)" by simp from Suc show ?case by (simp add: write_same f_n_id) qed
lemma array_write_same: fixes p::"('a['b::array_max_count]) ptr" assumes f_id: "f (heap_array s p) = heap_array s p" shows"heap_array_map p f s = s" apply (simp add: heap_array_map_def) apply (rule array_write_fold_same_aux) apply (rule f_id) by simp
lemma array_write_triv [simp]: fixes p::"('a['b::array_max_count]) ptr" shows"heap_array_map p (λ_. heap_array s p) s = s"and"heap_array_map p (λx. x) s = s" by (simp_all add: array_write_same)
lemma write_fold_other_commute: fixes p::"nat ==> 'a ptr" and q:: "'a ptr" assumes disj: "∧i. i < n ==> disjnt (ptr_span q) (ptr_span (p i))" shows "w q f (fold (λi. w (p i) (g i)) [0..<n] s) = fold (λi. w (p i) (g i) ) [0..<n] (w q f s)" using disj proof (induct n arbitrary: s) case0 thenshow ?caseby simp next case (Suc n) from Suc.prems obtain
q_n_disj: "disjnt (ptr_span q) (ptr_span (p n))"and
disj': "∧i. i < n ==> disjnt (ptr_span q) (ptr_span (p i))"by auto
lemma write_fold_arr_commute: fixes p::"('a['b::array_max_count]) ptr" and arr:: "'a['b::array_max_count]" assumes n_bound: "n < CARD('b)" shows "w (array_ptr_index p False n) (λ_. arr.[n]) (fold (λi. w (array_ptr_index p False i) (λ_. arr.[i])) [0..<n] s) = fold (λi. w (array_ptr_index p False i) (λ_. arr.[i])) [0..<n] ( w (array_ptr_index p False n) (λ_. arr.[n]) s)" apply (rule write_fold_other_commute) using n_bound by (simp add: ptr_span_array_index_disj)
lemma array_fold_fuse_aux: fixes p::"('a['b::array_max_count]) ptr" fixes f::"'a['b] ==> 'a['b]" fixes g::"'a['b] ==> 'a['b]" assumes n_bound: "n ≤ CARD('b)" shows"fold (λi. w (array_ptr_index p False i) (λ_. f (g (heap_array s p)).[i])) [0..<n] (fold (λi. w (array_ptr_index p False i) (λ_. g (heap_array s p).[i])) [0..<n] t) = fold (λi. w (array_ptr_index p False i) (λ_. f (g (heap_array s p)).[i])) [0..<n] t" using n_bound proof (induct n arbitrary: t) case0 thenshow ?caseby simp next case (Suc n) from Suc.prems have n_bound: "n ≤ CARD('b)"and n_bound': "n < CARD('b)" by auto show ?case apply (simp add: )
lemma array_write_comp: fixes p::"('a['b::array_max_count]) ptr" shows"heap_array_map p f (heap_array_map p g s) = heap_array_map p (f o g) s" proof - from array_read_write_same [of p g s] have g_eq: "heap_array (heap_array_map p g s) p = g (heap_array s p)". show ?thesis apply (subst (13) heap_array_map_def) apply (simp add: g_eq) apply (subst (1) heap_array_map_def) apply (rule array_fold_fuse_aux) by simp qed
lemma fold_fold_other_commute: fixes p::"nat ==> 'a ptr" and q:: "nat ==> 'a ptr" assumes disj: "∧i j. i < n ==> j < m ==> disjnt (ptr_span (p i)) (ptr_span (q j))" shows "fold (λi. w (p i) (f i)) [0..<n] (fold (λi. w (q i) (g i)) [0..<m] s) = fold (λi. w (q i) (g i)) [0..<m] (fold (λi. w (p i) (f i)) [0..<n] s)" using disj proof (induct n arbitrary: m s) case0 thenshow ?caseby simp next case (Suc n) from Suc.prems obtain
disj': "∧i j. i < n ==> j < m ==> disjnt (ptr_span (p i)) (ptr_span (q j))"and
m_disj: "∧j. j < m ==> disjnt (ptr_span (p n)) (ptr_span (q j))"by auto show ?case apply simp apply (subst write_fold_other_commute [OF m_disj, symmetric]) apply assumption apply (subst Suc.hyps [OF disj']) apply assumption apply assumption apply (rule refl) done qed
lemma array_write_other_commute: fixes p::"('a['b::array_max_count]) ptr" fixes q::"('a['b::array_max_count]) ptr" assumes disj: "disjnt (ptr_span p) (ptr_span q)" shows"heap_array_map q g (heap_array_map p f s) = heap_array_map p f (heap_array_map q g s)" proof - from array_read_write_other [OF disj] have g_eq: "g (heap_array (heap_array_map p f s) q) = g (heap_array s q)"by simp
from array_read_write_other disj have f_eq: "f (heap_array (heap_array_map q g s) p) = f (heap_array s p)" by (metis Int_commute disjnt_def)
show ?thesis apply (subst (13) heap_array_map_def) apply (simp add: g_eq f_eq) apply (simp add: heap_array_map_def) apply (rule fold_fold_other_commute) using disj by (metis Int_commute ptr_span_array_ptr_index_disj disjnt_def) qed
locale valid_pointer_array_lense = pointer_array_lense r w +
valid_array_base vgetter +
write_preserves_valid vgetter w for r:: "'s ==> 'a:: array_outer_max_size ptr ==> 'a" and w:: "'a ptr ==> ('a ==> 'a) ==> 's ==> 's" and vgetter:: "('s ==> 'a ptr ==> bool)" begin
lemma setter_fold_keeps_vgetter: fixes p':: "('a['b::array_max_count]) ptr" fixes p:: "'a ptr" assumes n_bound: "n ≤ CARD('b)" shows"vgetter (fold (λi. w (array_ptr_index p' False i) (λ_. f (heap_array s p').[i])) [0..<n] s) p = vgetter s p" using n_bound proof (induct n arbitrary: s) case0 thenshow ?caseby (simp ) next case (Suc n) from Suc.prems obtain
suc_n_bound: "Suc n ≤ CARD('b)"and
n_bound: "n ≤ CARD('b)"by auto show ?case apply simp apply (rule Suc.hyps [OF n_bound]) done qed
lemma heap_array_map_keeps_vgetter: fixes p:: "('a['b::array_max_count]) ptr" fixes p':: "('a['b]) ptr" shows"valid_array (heap_array_map p' f s) p = valid_array s p" by (clarsimp simp add: valid_array_def heap_array_map_def setter_fold_keeps_vgetter)
lemma heap_array_map_keeps_vgetter_element[simp]: fixes p':: "('a['b::array_max_count]) ptr" shows"vgetter (heap_array_map p' f s) = vgetter s" apply (rule ext) by (simp add: heap_array_map_def setter_fold_keeps_vgetter)
lemma getter_keeps_valid_array[simp]: fixes p':: "'a ptr" shows"(valid_array::'s ==> ('a['b::array_max_count]) ptr ==> bool) (w p' f s) = valid_array s" apply (rule ext) by (simp add: valid_array_def)
lemma getter_keeps_valid_array_pointwise[]: fixes p':: "'a ptr" fixes p :: "('a['b::array_max_count]) ptr" shows"(valid_array::'s ==> ('a['b::array_max_count]) ptr ==> bool) (w p' f s) p = valid_array s p" by (simp add: valid_array_def) end
locale valid_pointer_two_dimensional_array_lense = pointer_two_dimensional_array_lense r w +
valid_array_base vgetter +
write_preserves_valid vgetter w for r:: "'s ==> 'a:: array_inner_max_size ptr ==> 'a" and w:: "'a ptr ==> ('a ==> 'a) ==> 's ==> 's" and vgetter:: "('s ==> 'a ptr ==> bool)" begin sublocale inner: valid_pointer_array_lense r w vgetter by (intro_locales)
sublocale outer: valid_pointer_array_lense heap_array heap_array_map valid_array by (intro_locales)
end
locale array_typ_heap_simulation =
lense t_hrs t_hrs_update +
read_simulation st v r t_hrs +
write_simulation t_hrs t_hrs_update st v w +
write_preserves_valid v w +
valid_implies_cguard st v +
valid_only_typ_desc_dependent t_hrs st v +
pointer_array_lense r w +
valid_array_base v for
st:: "'s ==> 't"and
r:: "'t ==> 'a::array_outer_max_size ptr ==> 'a"and
w:: "'a ptr ==> ('a ==> 'a) ==> 't ==> 't"and
v:: "'t ==> 'a ptr ==> bool"and
t_hrs :: "'s ==> heap_raw_state"and
t_hrs_update:: "(heap_raw_state ==> heap_raw_state) ==> 's ==> 's" begin
sublocale typ_heap_simulation by (intro_locales)
sublocale valid_pointer_array_lense r w v by (intro_locales)
locale two_dimensional_array_typ_heap_simulation =
lense t_hrs t_hrs_update +
read_simulation st v r t_hrs +
write_simulation t_hrs t_hrs_update st v w +
write_preserves_valid v w +
valid_implies_cguard st v +
valid_only_typ_desc_dependent t_hrs st v +
pointer_two_dimensional_array_lense r w for
st:: "'s ==> 't"and
r:: "'t ==> 'a::array_inner_max_size ptr ==> 'a"and
w:: "'a ptr ==> ('a ==> 'a) ==> 't ==> 't"and
v:: "'t ==> 'a ptr ==> bool"and
t_hrs :: "'s ==> heap_raw_state"and
t_hrs_update:: "(heap_raw_state ==> heap_raw_state) ==> 's ==> 's" begin
sublocale inner: array_typ_heap_simulation st r w v t_hrs t_hrs_update by (intro_locales)
lemma root_ptr_valid_field_lvalue: fixes p::"'a::mem_type ptr" fixes q:: "'b::mem_type ptr" assumes root_p: "root_ptr_valid d p" assumes root_q: "root_ptr_valid d q" assumes fl: "field_lookup (typ_info_t TYPE('b)) f 0 = Some (t, k)" assumes other: "typ_uinfo_t TYPE('a) ≠ typ_uinfo_t TYPE('b)" shows"ptr_val p = &(q→f) ⟷ False" proof assume p: "ptr_val p = &(q→f)" from field_tag_sub [OF fl] have"{&(q→f)..+size_td t} ⊆ ptr_span q". moreover from root_ptr_valid_cases [OF root_p root_q] other have"ptr_span p ∩ ptr_span q = {}"by blast ultimately show False using p by (metis (mono_tags, lifting) disjoint_iff field_lookup_wf_size_desc_gt fl intvl_inter
intvl_start_inter mem_type_self subset_iff wf_size_desc) qed simp
lemma root_ptr_valid_field_lvalue': fixes q:: "'b::mem_type ptr" assumes root_p: "root_ptr_valid d (PTR ('a::mem_type)(&(q→f)))" assumes root_q: "root_ptr_valid d q" assumes fl: "field_lookup (typ_info_t TYPE('b)) f 0 = Some (t, k)" assumes other: "typ_uinfo_t TYPE('a) ≠ typ_uinfo_t TYPE('b)" shows"False" using root_ptr_valid_field_lvalue [OF root_p root_q fl other] by simp
lemma root_ptr_valid_array_ptr_index_dim1: fixes q:: "('a::array_outer_max_size['c::array_max_count]) ptr" assumes root_p: "root_ptr_valid d (array_ptr_index q False i)" assumes root_q: "root_ptr_valid d q" assumes other: "typ_uinfo_t TYPE('a) ≠ typ_uinfo_t TYPE('a['c])" assumes i_bound: "i < CARD('c)" shows"False" proof - from field_lookup_array [OF i_bound] obtain t k where
fl: "field_lookup (typ_info_t TYPE('a['c])) [replicate i (CHR ''1'')] 0 = Some (t, k)" by blast from root_ptr_valid_field_lvalue [OF root_p root_q fl other] i_bound show ?thesis by (simp add: array_ptr_index_field_lvalue_conv) qed
lemma root_ptr_valid_field_lvalue_array_ptr_index_dim1: fixes q:: "'b::mem_type ptr" assumes root_p: "root_ptr_valid d (array_ptr_index (PTR('a['c]) &(q→f)) False i)" assumes root_q: "root_ptr_valid d q" assumes other: "typ_uinfo_t TYPE('a) ≠ typ_uinfo_t TYPE('b)" assumes i_bound: "i < CARD('c)" assumes fl: "field_lookup (typ_info_t TYPE('b)) f 0 = Some (t, k)" assumes t: "export_uinfo t = typ_uinfo_t (TYPE('a::array_outer_max_size['c::array_max_count]))" shows False proof - from field_lookup_array [OF i_bound] obtain s n where
fl_i: "field_lookup (typ_info_t TYPE('a['c])) [replicate i (CHR ''1'')] k = Some (s, n)" by blast
from fl_i t obtain s' n' where
fl_i': "field_lookup t [replicate i (CHR ''1'')] k = Some (s', n')" by (metis (no_types, lifting) Padding_Equivalence.field_lookup_export_uinfo_Some_rev
field_lookup_export_uinfo_Some fold_typ_uinfo_t)
from field_lookup_prefix_Some''(1)[rule_format, where f="f"and g="[replicate i CHR ''1'']" and m=0, OF fl] have fl_app: "field_lookup (typ_info_t TYPE('b)) (f @ [replicate i CHR ''1'']) 0 = Some (s', n')" by (simp add: fl_update fl_i') have conv: "&(PTR('a['c]) &(q→f)→[replicate i CHR ''1'']) = &(q→f @[replicate i CHR ''1''] )" apply (subst field_lvalue_append) apply simp_all apply (rule field_lookup_field_ti') apply (rule fl) apply (simp add: typ_uinfo_t_def i_bound t) apply (rule field_lookup_field_ti') apply (rule field_lookup_array [OF i_bound]) done
from root_ptr_valid_field_lvalue [OF root_p root_q fl_app other] show False by (simp add: array_ptr_index_field_lvalue_conv i_bound conv) qed
lemma root_ptr_valid_field_lvalue_array_ptr_index_dim1': fixes q:: "'b::mem_type ptr" assumes root_p: "root_ptr_valid d (array_ptr_index (PTR(('a::array_outer_max_size['c::array_max_count])) &(q→f)) False i)" assumes root_q: "root_ptr_valid d q" assumes other: "typ_uinfo_t TYPE('a) ≠ typ_uinfo_t TYPE('b)" assumes i_bound: "i < CARD('c)" assumes fl: "field_lookup (typ_info_t TYPE('b)) f 0 = Some (adjust_ti (typ_info_t (TYPE('a['c]))) acc upd, k)" assumes fg: "fg_cons acc upd" shows"False" using root_ptr_valid_field_lvalue_array_ptr_index_dim1 [OF root_p root_q other i_bound fl] by (simp add: fg)
lemma root_ptr_valid_array_ptr_index_dim2: fixes q:: "(('a::array_inner_max_size['c::array_max_count])['d::array_max_count]) ptr" assumes root_p: "root_ptr_valid d (array_ptr_index (array_ptr_index q False i) False j)" assumes root_q: "root_ptr_valid d q" assumes other: "typ_uinfo_t TYPE('a) ≠ typ_uinfo_t TYPE('a['c]['d])" assumes i_bound: "i < CARD('d)" assumes j_bound: "j < CARD('c)" shows"False" proof - from field_lookup_array [OF i_bound, of 0, where 'a="'a['c]"] have fl_i: "field_lookup (typ_info_t TYPE(('a['c])['d])) [replicate i CHR ''1''] 0 = Some (adjust_ti (typ_info_t TYPE('a['c])) (λx. x.[i]) (λx f. Arrays.update f i x), i * size_of TYPE('a['c]))"by simp from field_lookup_array [OF j_bound, of "i * size_of TYPE('a['c])", where 'a="'a"] have fl_j: "field_lookup (typ_info_t TYPE('a['c])) [replicate j CHR ''1''] (i * size_of TYPE('a['c])) = Some (adjust_ti (typ_info_t TYPE('a)) (λx. x.[j]) (λx f. Arrays.update f j x), i * size_of TYPE('a['c]) + j * size_of TYPE('a))"by simp
have sz_eq: "size_of TYPE('a['c]) = (CARD('c) * size_of TYPE('a))" using size_of_array by blast from field_lookup_prefix_Some''(1)[rule_format, where f="[replicate i CHR ''1'']"and g="[replicate j CHR ''1'']" and t = "(typ_info_t TYPE(('a['c])['d]))"and m=0, OF fl_i] obtain t k where fl: "field_lookup (typ_info_t TYPE('a['c]['d])) [replicate i CHR ''1'', replicate j CHR ''1''] 0 = Some (t, k)" apply (simp add: i_bound) apply (simp add: fl_update sz_eq ) using fl_j [simplified sz_eq] apply simp done show ?thesis using root_ptr_valid_field_lvalue [OF root_p root_q fl other] i_bound j_bound apply (simp add: array_ptr_index_field_lvalue_conv append ) done qed
lemma root_ptr_valid_field_lvalue_array_ptr_index_dim2: fixes q:: "'b::mem_type ptr" assumes root_p: "root_ptr_valid d (array_ptr_index (array_ptr_index (PTR('a['c]['d]) &(q→f)) False i) False j)" assumes root_q: "root_ptr_valid d q" assumes other: "typ_uinfo_t TYPE('a) ≠ typ_uinfo_t TYPE('b)" assumes i_bound: "i < CARD('d)" assumes j_bound: "j < CARD('c)" assumes fl: "field_lookup (typ_info_t TYPE('b)) f 0 = Some (t, k)" assumes t: "export_uinfo t = typ_uinfo_t (TYPE(('a::array_inner_max_size['c::array_max_count])['d::array_max_count]))" shows"False" proof - from field_lookup_array [OF i_bound] obtain s n where
fl_i: "field_lookup (typ_info_t TYPE('a['c]['d])) [replicate i (CHR ''1'')] k = Some (s, n)"and
s: "s = adjust_ti (typ_info_t TYPE('a['c])) (λx. x.[i]) (λx f. Arrays.update f i x)" by blast
from fl_i t s obtain s' n' where
fl_i': "field_lookup t [replicate i (CHR ''1'')] k = Some (s', n')"and
s': "export_uinfo s' = typ_uinfo_t TYPE('a['c])" by (smt (verit, best) Padding_Equivalence.field_lookup_export_uinfo_Some_rev
export_tag_adjust_ti(1) fg_cons_array field_lookup_array fold_typ_uinfo_t i_bound wf_fd field_lookup_typ_uinfo_t_Some)
from field_lookup_prefix_Some''(1)[rule_format, where f="f"and g="[replicate i CHR ''1'']" and m=0, OF fl] have fl_app1: "field_lookup (typ_info_t TYPE('b)) (f @ [replicate i CHR ''1'']) 0 = Some (s', n')" by (simp add: fl_update fl_i')
from field_lookup_array [OF j_bound] obtain s'' n'' where
fl_j: "field_lookup (typ_info_t TYPE('a['c])) [replicate j (CHR ''1'')] n' = Some (s'', n'')" by blast
from fl_j s' obtain s''' n''' where
fl_j': "field_lookup s' [replicate j (CHR ''1'')] n' = Some (s''', n''')" by (metis (no_types, lifting) CTypes.field_lookup_export_uinfo_Some_rev field_lookup_export_uinfo_Some fold_typ_uinfo_t)
from field_lookup_prefix_Some''(1)[rule_format, where f="f @ [replicate i CHR ''1'']"and g="[replicate j CHR ''1'']" and m=0, OF fl_app1] have fl_app2: "field_lookup (typ_info_t TYPE('b)) (f @ [replicate i CHR ''1'', replicate j CHR ''1'']) 0 = Some (s''', n''')" by (simp add: fl_update fl_j')
apply (subst field_lvalue_append) apply (rule field_lookup_field_ti') apply (rule field_lookup_offset_shift') apply (rule fl_app1) apply (simp add: s') apply (rule field_lookup_field_ti') apply (rule field_lookup_offset_shift') apply (rule fl_j) apply simp done from root_ptr_valid_field_lvalue [OF root_p root_q fl_app2 other ] show False by (simp add: array_ptr_index_field_lvalue_conv i_bound j_bound conv) qed
context open_types begin
definition "typ_heap_simulation_of_field (st::'s ==> 't) t_hrs t_hrs_update heap_typing_upd f' r' w' ⟷ (∀d p f. heap_typing_upd d o w' p f = w' p f o heap_typing_upd d) ∧ (∀t u n. field_ti TYPE('a::mem_type) f' = Some t ⟶ field_lookup (typ_uinfo_t TYPE('a)) f' 0 = Some (u, n) ⟶ partial_pointer_lense (merge_ti t) r' w' ∧ (∀(p::'a ptr) s. (∀a∈ptr_span p. root_ptr_valid (hrs_htd (t_hrs s)) (PTR(stack_byte) a)) ⟶ r' (st s) p ZERO('a) = ZERO('a)) ∧ (∀(p::'a ptr) x h. ptr_valid_u u (hrs_htd (t_hrs h)) &(p→f') ⟶ st (t_hrs_update (hrs_mem_update (heap_upd_list (size_td u) &(p→f') (access_ti t x))) h) = w' p x (st h)))"
end
definition
pointer_writer_disjnt :: "('a::c_type ptr ==> 't upd) ==> ('b::c_type ptr ==> 't upd) ==> bool" where "pointer_writer_disjnt f g ⟷ (∀p q. disjnt (ptr_span p) (ptr_span q) ⟶ f p ∘ g q = g q o f p)"
definition
pointer_writer_disjnt_eq :: "('a::c_type ptr ==> 'x ==> 't upd) ==> ('b::c_type ptr ==> 'y ==> 't upd) ==> bool" where "pointer_writer_disjnt_eq f g ⟷ (∀p q x y. disjnt (ptr_span p) (ptr_span q) ∨ ptr_val p = ptr_val q ⟶ f p x ∘ g q y = g q y o f p x)"
named_theorems pointer_writer_disjnt_intros
lemma pointer_writer_disjnt_eq: assumes nm: "∃n1 n2. field_lookup (typ_uinfo_t TYPE('a::mem_type)) f1 0 = Some (typ_uinfo_t TYPE('b::mem_type), n1) ∧ field_lookup (typ_uinfo_t TYPE('a)) f2 0 = Some (typ_uinfo_t TYPE('c::mem_type), n2)" assumes w1_w2: "∧x y. pointer_writer_disjnt (λp. w1 p x) (λq. w2 q y)" shows"disj_fn f1 f2 ⟶ pointer_writer_disjnt_eq (λ(p::'a ptr). w1 (PTR('b) &(p→f1))) (λ(p::'a ptr). w2 (PTR('c) &(p→f2)))" (is"?disj ⟶ ?goal") proof assume ?disj from nm obtain n1 n2 where fl: "field_lookup (typ_uinfo_t TYPE('a::mem_type)) f1 0 = Some (typ_uinfo_t TYPE('b::mem_type), n1)" "field_lookup (typ_uinfo_t TYPE('a)) f2 0 = Some (typ_uinfo_t TYPE('c::mem_type), n2)" by auto from fl[THEN field_tag_sub'] have"ptr_span (PTR('b) &(p→f1)) ⊆ ptr_span p ∧ ptr_span (PTR('c) &(q→f2)) ⊆ ptr_span q" for p q :: "'a ptr" by (auto intro: field_tag_sub' simp: size_of_def del: subsetI) thenhave ne[simp]: "disjnt (ptr_span p) (ptr_span q) ==> disjnt (ptr_span (PTR('b) &(p→f1))) (ptr_span (PTR('c) &(q→f2)))"for p q :: "'a ptr" by (blast intro: disjnt_subset1 disjnt_subset2) moreover from fl obtain u1 u2 where fl_t: "field_lookup (typ_info_t TYPE('a)) f1 0 = Some (u1, n1)" "field_lookup (typ_info_t TYPE('a)) f2 0 = Some (u2, n2)" and export: "export_uinfo u1 = typ_uinfo_t TYPE('b)""export_uinfo u2 = typ_uinfo_t TYPE('c)" by (auto dest!: field_lookup_export_uinfo_Some_rev simp: typ_uinfo_t_def) from fa_fu_lookup_disj_interD[OF fl_t ‹disj_fn f1 f2›] have"disjnt (ptr_span (PTR('b) &(p→f1))) (ptr_span (PTR('c) &(p→f2)))"for p :: "'a ptr" apply (simp add: size_of_fold disjnt_def) apply (simp add: size_of_def field_lvalue_def field_offset_def field_offset_untyped_def fl
intvl_disj_offset
flip: typ_uinfo_size export) done ultimatelyshow ?goal using w1_w2 by (auto simp: pointer_writer_disjnt_def pointer_writer_disjnt_eq_def) qed
lemma pointer_writer_disjnt_sym: "pointer_writer_disjnt f g ==> pointer_writer_disjnt g f" by (auto simp add: pointer_writer_disjnt_def disjnt_sym)
lemma pointer_writer_disjnt_id_left: "pointer_writer_disjnt (λp h. h) w" by (simp add: pointer_writer_disjnt_def fun_eq_iff)
lemma pointer_writer_disjnt_comp_left: "pointer_writer_disjnt w1 w ==> pointer_writer_disjnt w2 w ==> pointer_writer_disjnt (λp h. w1 p (w2 p h)) w" by (simp add: pointer_writer_disjnt_def fun_eq_iff)
lemma pointer_writer_disjnt_comp_left': "pointer_writer_disjnt w1 w ==> pointer_writer_disjnt w2 w ==> pointer_writer_disjnt (λp. w1 p ∘ w2 p) w" by (simp add: pointer_writer_disjnt_def fun_eq_iff)
lemma pointer_writer_disjnt_fold_left: "list_all (λw'. pointer_writer_disjnt (f w') w) ws ==> pointer_writer_disjnt (λp. fold (λw. f w p) ws) w" by (induction ws) (auto intro: pointer_writer_disjnt_comp_left' pointer_writer_disjnt_id_left')
lemma pointer_writer_disjntI: "(∧p q h. w1 p (w2 q h) = w2 q (w1 p h)) ==> pointer_writer_disjnt w1 w2" by (auto simp: pointer_writer_disjnt_def)
lemma pointer_writer_disjntD: "pointer_writer_disjnt w1 w2 ==> disjnt (ptr_span p) (ptr_span q) ==> w1 p (w2 q h) = w2 q (w1 p h)" by (auto simp: pointer_writer_disjnt_def fun_eq_iff)
lemma pointer_writer_disjnt_ptr_corce_signed: fixes w1 :: "'a::len8 word ptr ==> 's upd"and w2 :: "'b::mem_type ptr ==> 's upd" assumes w1_w2: "pointer_writer_disjnt w1 w2" shows"pointer_writer_disjnt (λ(p::'a signed word ptr). w1 (PTR_COERCE('a signed word → 'a word) p)) w2" using w1_w2 by (rule pointer_writer_disjnt_ptr_corce) (simp add: size_of_signed_word)
lemma pointer_writer_disjnt_ptr_corce_signed': fixes w1 :: "'a::len8 word ptr ==> 's upd"and w2 :: "'b::mem_type ptr ==> 's upd" shows"pointer_writer_disjnt w2 w1 ==> pointer_writer_disjnt w2 (λ(p::'a signed word ptr). w1 (PTR_COERCE('a signed word → 'a word) p))" using pointer_writer_disjnt_ptr_corce_signed[of w1 w2] by (simp add: pointer_writer_disjnt_sym)
lemma (in pointer_lense) pointer_writer_disjnt_replace_by_const: "(∧x. pointer_writer_disjnt (λp. w p (λ_. x)) w') ==> pointer_writer_disjnt (λp. w p f) w'" by (auto simp add: pointer_writer_disjnt_def fun_eq_iff)
(metis (no_types, lifting) read_write_same write_cong write_read)
lemma (in pointer_lense) read_commute_of_pointer_writer_disjnt: assumes w': "∧f. pointer_writer_disjnt (λp. w p f) w'" assumes p_q: "disjnt (ptr_span p) (ptr_span q)" shows"r (w' q h) p = r h p" apply (subst write_same[of "λ_. r h p" h p, OF refl, symmetric]) apply (subst pointer_writer_disjntD[OF w' p_q, symmetric]) apply (subst read_write_same) apply (rule refl) done
lemma (in pointer_lense) read_commute_of_pointer_writer_disjnt': assumes w': "∧f. pointer_writer_disjnt w' (λp. w p f)" assumes p_q: "disjnt (ptr_span p) (ptr_span q)" shows"r (w' q h) p = r h p" using read_commute_of_pointer_writer_disjnt[OF w'[THEN pointer_writer_disjnt_sym] p_q] .
lemma (in pointer_lense) read_commute_of_commute: assumes w': "∧p f. w p f o w' = w' o w p f" shows"r (w' h) p = r h p" using read_write_same[of p "λ_. r h p""w' h"] w' by (subst write_same[of "λ_. r h p" h p, OF refl, symmetric]) (simp add: fun_eq_iff)
lemma (in pointer_lense) read_commute_of_commute': assumes w': "∧p f. w' o w p f = w p f o w'" shows"r (w' h) p = r h p" using read_commute_of_commute[OF w'[symmetric]] .
lemma (in lense) get_commute_of_commute: assumes w': "∧f. w' o upd f = upd f o w'" shows"get (w' h) = get h" using get_upd[of "λ_. get h""w' h"] w'[symmetric] by (subst upd_same[of "λ_. get h" h, OF refl, symmetric]) (simp add: fun_eq_iff del: get_upd)
lemma (in pointer_lense) pointer_writer_disjnt_replace_dep_by_const: assumes *: "∧x. pointer_writer_disjnt (λp. w p x) w'" shows"pointer_writer_disjnt (λp s. w p (f (r s p)) s) w'" by (auto simp add: pointer_writer_disjnt_def fun_eq_iff
read_commute_of_pointer_writer_disjnt[OF *]
pointer_writer_disjntD[OF *])
lemma (in pointer_lense) pointer_writer_disjnt_upd[pointer_writer_disjnt_intros]: "pointer_writer_disjnt (λp. w p x) (λp. w p y)" by (simp add: pointer_writer_disjnt_def write_other_commute disjnt_def fun_eq_iff)
lemma (in partial_pointer_lense) read_commute_of_pointer_writer_disjnt: assumes w': "∧f. pointer_writer_disjnt (λp. w p f) w'" assumes p_q: "disjnt (ptr_span p) (ptr_span q)" shows"r (w' q h) p y = r h p y" by (metis m_r p_q pointer_writer_disjntD r_w w' w_r)
lemma pointer_lense_upd_fun_of_lense: fixes get upd assumes"lense get upd" shows"pointer_lense get (λp f. upd (upd_fun p f))" proof - interpret lense get upd by fact show ?thesis proofqed (simp_all add: upd_same upd_fun.upd_same disj_ptr_span_ptr_neq
upd_fun_commute Int_commute disjnt_def) qed
locale typ_heap_simulation_open_types =
typ_heap_simulation st r w v t_hrs t_hrs_update +
open_types_heap_typing_state T heap_typing heap_typing_upd for Tand
st:: "'s ==> 't"and
r:: "'t ==> ('a::{xmem_type, stack_type}) ptr ==> 'a"and
w:: "'a ptr ==> ('a ==> 'a) ==> 't ==> 't"and
v:: "'t ==> 'a ptr ==> bool"and
t_hrs :: "'s ==> heap_raw_state"and
t_hrs_update:: "(heap_raw_state ==> heap_raw_state) ==> 's ==> 's"and
heap_typing :: "'t ==> heap_typ_desc"and
heap_typing_upd :: "(heap_typ_desc ==> heap_typ_desc) ==> 't ==> 't" + assumes heap_typing_commutes[simp]: "heap_typing (st s) = hrs_htd (t_hrs s)" assumes heap_typing_upd_write_commute: "∧p f h d. heap_typing_upd d (w p f h) = w p f (heap_typing_upd d h)" assumes ptr_valid_imp_v: "∧p h. ptr_valid (heap_typing h) p ==> v h p" assumes sim_stack_stack_byte_zero': "∧p s. ∀a∈ptr_span p. root_ptr_valid (hrs_htd (t_hrs s)) (PTR(stack_byte) a) ==> r (st s) p = ZERO('a)" begin
lemma heap_typing_write[simp]: "heap_typing (w p f h) = heap_typing h" apply (subst upd_same[symmetric, of "λ_. heap_typing h", OF refl]) apply (subst heap_typing_upd_write_commute[symmetric]) apply (rule get_upd) done
lemma heap_typing_upd[simp]: "r (heap_typing_upd d h) = r h" apply (rule ext)
subgoal for p apply (subst write_same[symmetric, of "λ_. r h p", OF refl]) apply (subst heap_typing_upd_write_commute) apply (rule read_write_same) done done
lemma unchanged_typing_root_ptr_valid_preserved: "unchanged_typing_on A t1 t2 ==> ptr_span p ⊆ A ==> root_ptr_valid (heap_typing t1) p = root_ptr_valid (heap_typing t2) p" by (simp add: unchanged_typing_on_def equal_on_def intvlI
root_ptr_valid_def size_of_tag subsetD valid_root_footprint_def)
lemma unchanged_typing_ptr_valid_preserved: assumes unch: "unchanged_typing_on UNIV t1 t2" shows"ptr_valid (heap_typing t1) p = ptr_valid (heap_typing t2) p" proof - from unch have"heap_typing t1 = heap_typing t2" by (simp add: fun_eq_iff unchanged_typing_on_def equal_on_def) thus ?thesis by simp qed
lemma unchanged_typing_on_write [unchanged_typing_on_simps]: "unchanged_typing_on A t (w p f t)" using heap_typing_upd_write_commute by (simp add: unchanged_typing_on_def)
lemma heap_typing_fold_upd_write: "heap_typing (fold (λi. w (x i) (g i)) [0..<n] t) = heap_typing t" proof (induct n) case0 thenshow ?caseby (simp add: heap_typing_upd_write_commute) next case (Suc n) thenshow ?caseby (simp add: heap_typing_upd_write_commute) qed
end
lemma distinct_prop_conj: "distinct_prop (λa b. R a b ∧ P a b) xs ⟷ distinct_prop R xs ∧ distinct_prop P xs" by (auto simp: distinct_prop_iff_nth)
lemma distinct_prop_zip_cons: "list_all (λ(c, d). P a b c d) (zip as bs) ==> distinct_prop (λ(a, b) (c, d). P a b c d) (zip as bs) ==> distinct_prop (λ(a, b) (c, d). P a b c d) (zip (a#as) (b#bs))" by (simp add: list_all_iff)
lemma distinct_prop_zip_nil: "distinct_prop (λ(a, b) (c, d). P a b c d) (zip [] [])" by (simp add: list_all_iff)
lemma list_all_zip_cons: "P a b ==> list_all (λ(a, b). P a b) (zip as bs) ==> list_all (λ(a, b). P a b) (zip (a#as) (b#bs))" by simp
lemma list_all_zip_nil: "list_all (λ(a, b). P a b) (zip [] [])" by simp
named_theorems disjnt_heap_fields_comp
context open_types begin
lemma typ_heap_simulationI_part_addressable: fixes R :: "'t ==> 'a::{xmem_type, stack_type} ptr ==> 'a" assumes hrs: "heap_typing_simulation T hrs hrs_upd heap_typing heap_typing_upd l" assumes fs: "map_of T (typ_uinfo_t TYPE('a)) = Some fs" assumes"lense g u" assumes len[simp]: "length rs = length fs""length ws = length fs" assumes *: "list_all (λ(f, r, w). typ_heap_simulation_of_field l hrs hrs_upd heap_typing_upd f r w) (zip fs (zip rs ws))" and **: "distinct_prop (λ(f1, w1) (f2, w2). disj_fn f1 f2 ⟶ pointer_writer_disjnt_eq w1 w2) (zip fs ws)" and ws_u: "list_all (λw. ∀p a f. w p a ∘ u f = u f ∘ w p a) ws" and l_u: "∧(p::'a ptr) (x::'a) (s::'b). PTR_VALID('a) (hrs_htd (hrs s)) p ==> l (hrs_upd (write_dedicated_heap p x) s) = u (upd_fun p (λold. merge_addressable_fields old x)) (l s)" and r_stack: "∧p s. ∀a∈ptr_span p. root_ptr_valid (hrs_htd (hrs s)) (PTR(stack_byte) a) ==> g (l s) p = ZERO(_)" and heap_typing_u: "∧x d h. heap_typing_upd d (u x h) = u x (heap_typing_upd d h)" assumes V: "∧h p. V h p ⟷ PTR_VALID('a) (heap_typing h) p" assumes R: "∧h p. R h p = fold (λr. r h p) rs (g h p)" assumes W: "∧p f h. W p f h = fold (λw. w p (f (R h p))) ws (u (upd_fun p (λold. merge_addressable_fields old (f (R h p)))) h)" shows"typ_heap_simulation_open_types T l R W V hrs hrs_upd heap_typing heap_typing_upd ∧ (pointer_lense g (λp f. u (upd_fun p f))) ∧ (∀w. (∀x. list_all (λw'. pointer_writer_disjnt (λp. w' p x) w) ws) ⟶ (∀x. pointer_writer_disjnt (λp. u (upd_fun p (λ_. x))) w) ⟶ (∀f. pointer_writer_disjnt (λp. W p f) w)) ∧ (∀w p. (∀x. list_all (λw'. w' p x o w = w o w' p x) ws) ⟶ (∀x. u (upd_fun p (λ_. x)) o w = w o u (upd_fun p (λ_. x))) ⟶ (∀f. W p f o w = w o W p f))"
(is"?t1 ∧ ?t3 ∧ (∀w. ?ws w ⟶ ?u w ⟶ (∀f. ?t2 f w)) ∧ (∀w p. ?ws2 w p ⟶ ?u2 w p ⟶ (∀f. ?t4 w p f))") proof (intro conjI allI impI) interpret hrs: heap_typing_simulation T hrs hrs_upd heap_typing heap_typing_upd l by fact interpret lense g u by fact
have [simp]: "length (addressable_fields TYPE('a)) = length fs" by (simp add: addressable_fields_def fs)
have"list_all (λf. ∃u n. field_lookup (typ_uinfo_t TYPE('a)) f 0 = Some (u, n)) (map fst (zip fs (zip rs ws)))" using wf_T[OF fs] by auto thenhave fs_exists: "list_all (λx. ∃u n. field_lookup (typ_uinfo_t TYPE('a)) (fst x) 0 = Some (u, n)) (zip fs (zip rs ws))" by (simp add: list.pred_map comp_def del: len)
have dist: "distinct_prop disj_fn fs" usingT_distinct[OF fs] .
interpret pointer_lense R W apply (rule pointer_lense_of_partials_cover[
of g u "map merge_ti (map snd (addressable_fields TYPE('a)))" rs ws, OF ‹lense g u› _ _ _ _ _ _ R])
subgoal by simp
subgoal by simp
subgoal by fact
subgoal for a b c apply (simp add: distinct_prop_map addressable_fields_def fs) apply (rule distinct_prop_mono[OF _ dist]) using wf_T[OF fs] apply (intro disjnt_scene_merge_ti[THEN disjnt_sceneD,
OF option.collapse[symmetric] option.collapse[symmetric]]) apply (auto simp: list.pred_set field_ti_def disj_fn_def
dest!: field_lookup_uinfo_Some_rev) done
subgoal using ws_u ** dist apply (clarsimp simp add: list_all_iff pointer_writer_disjnt_eq_def[abs_def]) apply (clarsimp simp add: distinct_prop_iff_nth fun_eq_iff distinct_conv_nth
disj_fn_def) apply metis done
subgoal by (simp add: merge_ti_list_def fold_map comp_def)
subgoal by (rule W) done
have"list_all (λ(f, w). ∀t u n h p x. field_ti TYPE('a) f = Some t ⟶ field_lookup (typ_uinfo_t TYPE('a)) f 0 = Some (u, n) ⟶ ptr_valid_u u (hrs_htd (hrs h)) &(p→f) ⟶ l (hrs_upd (hrs_mem_update (heap_upd_list (size_td u) &(p→f) (access_ti t x))) h) = w p x (l h)) (map (λfrw. (fst frw, snd (snd frw))) (zip fs (zip rs ws)))" unfolding list.pred_map using * by (rule list.pred_mono_strong) (auto simp: typ_heap_simulation_of_field_def) alsohave"map (λfrw. (fst frw, snd (snd frw))) (zip fs (zip rs ws)) = zip fs ws" by (simp add: list_eq_iff_nth_eq) finallyhave fs_ws: "list_all2 (λf w. ∀t u n h p x. field_ti TYPE('a) f = Some t ⟶ field_lookup (typ_uinfo_t TYPE('a)) f 0 = Some (u, n) ⟶ ptr_valid_u u (hrs_htd (hrs h)) &(p→f) ⟶ l (hrs_upd (hrs_mem_update (heap_upd_list (size_td u) &(p→f) (access_ti t x))) h) = w p x (l h)) fs ws" by (subst (asm) list_all_zip_iff_list_all2; simp)
have V_l: "∧h p. V (l h) p ⟷ PTR_VALID('a) (hrs_htd (hrs h)) p" by (simp add: V)
interpret write_simulation hrs hrs_upd l V W apply (rule write_simulationI[OF fs hrs, of ws u V _ R]) apply (rule fs_ws) apply (rule l_u) apply assumption apply (rule V_l) apply (rule W) done
show ?t3 by (rule pointer_lense_upd_fun_of_lense) fact theninterpret u: pointer_lense g "λp f. u (upd_fun p f)" .
show"?t2 f w"if *: "?ws w""?u w"for w f by (rule pointer_writer_disjnt_replace_by_const)
(use * in‹auto simp add: W[abs_def]
intro!: pointer_writer_disjnt_comp_left[OF pointer_writer_disjnt_fold_left
u.pointer_writer_disjnt_replace_by_const]›)
show disj: "?t4 w p f"if *: "?u2 w p""?ws2 w p"for p f w proof (standard, unfold comp_def) fix h have w_ws: "w (fold (λw. w p c) ws h) = fold (λw. w p c) ws (w h)"for c h using *[rule_format, of c] by (induction ws arbitrary: h) (auto simp: fun_eq_iff)
have w_u[simp]: "w (u (upd_fun p (λ_. c)) h) = u (upd_fun p (λ_. c)) (w h)"for c h using *(1) by (auto simp: fun_eq_iff)
have g_w[simp]: "g (w h) p = g h p"for h by (subst u.write_same[of "λ_. g h p" h p, OF refl, symmetric])
(simp add: u.read_write_same)
have w_u'[simp]: "w (u (upd_fun p f) h) = u (upd_fun p f) (w h)"for f h by (subst (12) u.write_cong[where f'="λ_. f (g h p)"]) simp_all
have w_W_const: "w (W p (λx. c) h) = W p (λx. c) (w h)"for c h by (simp add: W w_ws)
have R_eq: "R (w h) p = R h p" apply (subst write_same[of "λ_. R h p" h p, OF refl, symmetric]) apply (subst w_W_const) apply (subst read_write_same) apply (rule refl) done
show"W p f (w h) = w (W p f h)" by (simp add: R_eq write_cong[of f _ _ "λ_. f (R h p)"] w_W_const) qed
show ?t1 proof fix h p assume V_p: "V (l h) p" thenshow"c_guard p"by (simp add: ptr_valid.ptr_valid_c_guard V)
have l_h: "l h = W p (λx. h_val (hrs_mem (hrs h)) p) (l h)" apply (subst write_commutes[OF V_p, symmetric]) apply (subst hrs.t_hrs.heap.upd_same) apply (cases "hrs h") apply (simp_all add: hrs_mem_update_def hrs_mem_def xmem_type_class.heap_update_id) done
show"R (l h) p = h_val (hrs_mem (hrs h)) p" apply (subst l_h) apply (subst read_write_same) apply simp done next fix p :: "'a ptr"and s assume p: "∀a∈ptr_span p. root_ptr_valid (hrs_htd (hrs s)) (PTR(stack_byte) a)" moreover
{ fix f w and r :: "'t ==> 'a ptr ==> 'a ==> 'a"and u n assume"typ_heap_simulation_of_field l hrs hrs_upd heap_typing_upd f r w" "field_lookup (typ_uinfo_t TYPE('a)) f 0 = Some (u, n)" with p have"r (l s) p ZERO('a) = ZERO('a)" unfolding typ_heap_simulation_of_field_def by (auto simp: field_ti_def field_lookup_typ_uinfo_t_Some typ_heap_simulation_of_field_def
dest!: field_lookup_uinfo_Some_rev) } note this[simp] from * fs_exists len have"fold (λr. r (l s) p) rs ZERO('a) = ZERO('a)" by (induction fs arbitrary: rs ws)
(auto simp: length_Suc_conv simp del: len) ultimatelyshow"R (l s) p = ZERO('a)" unfolding R by (simp add: r_stack) next
{ fix d p f have"W p f o heap_typing_upd d = heap_typing_upd d o W p f" apply (rule disj)
subgoal using heap_typing_u by (simp add: fun_eq_iff) using * len apply (induction fs arbitrary: ws rs) apply (auto simp add: length_Suc_conv typ_heap_simulation_of_field_def simp del: len) done thenshow"heap_typing_upd d (W p f h) = W p f (heap_typing_upd d h)"for h by (simp add: fun_eq_iff) } note heap_typing_W = this
show"V (W p' f h) p = V h p"for p' f h p unfolding V apply (subst hrs.upd_same[symmetric, of "λ_. heap_typing h", OF refl]) apply (subst heap_typing_W[symmetric]) apply (subst hrs.get_upd)
.. qed (simp_all add: V) qed
lemma typ_heap_simulationI_no_addressable: fixes R :: "'t ==> 'a::{xmem_type, stack_type} ptr ==> 'a" assumes"heap_typing_simulation T hrs hrs_upd heap_typing heap_typing_upd l" assumes R_u: "lense R u" assumes fs: "map_of T (typ_uinfo_t TYPE('a)) = None" and l_u: "∧(p::'a ptr) (x::'a) (s::'b). PTR_VALID('a) (hrs_htd (hrs s)) p ==> l (hrs_upd (write_dedicated_heap p x) s) = u (upd_fun p (λold. merge_addressable_fields old x)) (l s)" and heap_typing_u: "∧x d h. heap_typing_upd d (u x h) = u x (heap_typing_upd d h)" and r_stack: "∧p s. ∀a∈ptr_span p. root_ptr_valid (hrs_htd (hrs s)) (PTR(stack_byte) a) ==> R (l s) p = ZERO(_)" assumes V: "∧h p. V h p ⟷ PTR_VALID('a) (heap_typing h) p" assumes W: "∧p f h. W p f h = u (λh'. h'(p := f (h' p))) h" shows"typ_heap_simulation_open_types T l R W V hrs hrs_upd heap_typing heap_typing_upd" proof - interpret hrs: heap_typing_simulation T hrs hrs_upd heap_typing heap_typing_upd l by fact interpret lense R u by fact
have [simp]: "merge_addressable_fields = (λa b::'a. b)" by (simp add: fun_eq_iff addressable_fields_def fs)
interpret pointer_lense R W using pointer_lense_of_lense_fld[where 'd='a, OF R_u, of "[]"] by (simp add: W[abs_def] upd_fun_def[abs_def])
interpret write_simulation hrs hrs_upd l V W apply (rule hrs.write_simulation_alt)
subgoal by (simp add: V)
subgoal for h p x unfolding W V using l_u[of h p x] by (simp add: write_dedicated_heap_def heap_upd_const upd_fun_def[abs_def]) done
show ?thesis proof fix h p assume V_p: "V (l h) p" thenshow"c_guard p"by (simp add: ptr_valid.ptr_valid_c_guard V)
have l_h: "l h = W p (λx. h_val (hrs_mem (hrs h)) p) (l h)" apply (subst write_commutes[OF V_p, symmetric]) apply (subst hrs.t_hrs.heap.upd_same) apply (cases "hrs h") apply (simp_all add: hrs_mem_update_def hrs_mem_def xmem_type_class.heap_update_id) done
show"R (l h) p = h_val (hrs_mem (hrs h)) p" apply (subst l_h) apply (subst read_write_same) apply simp done next show"V (W p' f h) p = V h p"for p' f h p unfolding W V apply (subst hrs.upd_same[symmetric, of "λ_. heap_typing h", OF refl]) apply (subst heap_typing_u[symmetric]) apply (subst hrs.get_upd)
.. qed (simp_all add: V W heap_typing_u r_stack) qed
lemma typ_heap_simulationI_all_addressable: fixes R :: "'t ==> 'a::{xmem_type, stack_type} ptr ==> 'a" assumes hrs: "heap_typing_simulation T hrs hrs_upd heap_typing heap_typing_upd l" assumes fs: "map_of T (typ_uinfo_t TYPE('a)) = Some fs" assumes len[simp]: "length rs = length fs""length ws = length fs" assumes *: "list_all (λ(f, r, w). typ_heap_simulation_of_field l hrs hrs_upd heap_typing_upd f r w) (zip fs (zip rs ws))" and **: "distinct_prop (λ(f1, w1) (f2, w2). disj_fn f1 f2 ⟶ pointer_writer_disjnt_eq w1 w2) (zip fs ws)" assumes all: "∧a b. fold (λx. merge_ti (the (field_ti TYPE('a) x)) a) fs b = a" assumes V: "∧h p. V h p ⟷ PTR_VALID('a) (heap_typing h) p" assumes R: "∧h p x. R h p = fold (λr. r h p) rs x" assumes W: "∧p f h. W p f h = fold (λw. w p (f (R h p))) ws h" shows"typ_heap_simulation_open_types T l R W V hrs hrs_upd heap_typing heap_typing_upd ∧ (∀w. (∀x. list_all (λw'. pointer_writer_disjnt (λp. w' p x) w) ws) ⟶ (∀f. pointer_writer_disjnt (λp. W p f) w)) ∧ (∀(w::'t ==> 't) p. (∀x. list_all (λw'. w' p x ∘ w = w ∘ w' p x) ws) ⟶ (∀f. W p f ∘ w = w ∘ W p f))"
(is"?t1 ∧ (∀w. ?ws w ⟶ (∀f. ?t2 f w)) ∧ (∀w p. ?ws2 p w ⟶ (∀f. ?t3 p f w))") proof (intro conjI allI impI) interpret hrs: heap_typing_simulation T hrs hrs_upd heap_typing heap_typing_upd l by fact
have [simp]: "length (addressable_fields TYPE('a)) = length fs" by (simp add: addressable_fields_def fs)
have"list_all (λf. ∃u n. field_lookup (typ_uinfo_t TYPE('a)) f 0 = Some (u, n)) (map fst (zip fs (zip rs ws)))" using wf_T[OF fs] by auto thenhave fs_exists: "list_all (λx. ∃u n. field_lookup (typ_uinfo_t TYPE('a)) (fst x) 0 = Some (u, n)) (zip fs (zip rs ws))" by (simp add: list.pred_map comp_def del: len)
have coer_eq[simp]: "merge_addressable_fields = (λa b::'a. a)" by (simp add: merge_ti_list_def addressable_fields_def fold_map fs fun_eq_iff comp_def all)
have dist: "distinct_prop disj_fn fs" usingT_distinct[OF fs] .
interpret pointer_lense R W apply (rule pointer_lense_of_partials[
of "map merge_ti (map snd (addressable_fields TYPE('a)))" rs ws, OF _ _ _ _ _ _ R])
subgoal by simp
subgoal by simp
subgoal apply (simp add: zip_map1 list.pred_map addressable_fields_def fs split_beta' comp_def) using list_all_conj[OF * fs_exists] apply (rule list.pred_mono_strong) apply (auto simp: field_ti_def field_lookup_typ_uinfo_t_Some typ_heap_simulation_of_field_def
dest!: field_lookup_uinfo_Some_rev) done
subgoal for a b c apply (simp add: distinct_prop_map addressable_fields_def fs) apply (rule distinct_prop_mono[OF _ dist]) using wf_T[OF fs] apply (intro disjnt_scene_merge_ti[THEN disjnt_sceneD,
OF option.collapse[symmetric] option.collapse[symmetric]]) apply (auto simp: list.pred_set field_ti_def disj_fn_def
dest!: field_lookup_uinfo_Some_rev) done
subgoal using ** dist apply (clarsimp simp add: distinct_prop_iff_nth fun_eq_iff pointer_writer_disjnt_eq_def[abs_def]
distinct_conv_nth disj_fn_def) apply metis done
subgoal by (simp add: addressable_fields_def fs fold_map comp_def all)
subgoal by (rule W) done
have"list_all (λ(f, w). ∀t u n h p x. field_ti TYPE('a) f = Some t ⟶ field_lookup (typ_uinfo_t TYPE('a)) f 0 = Some (u, n) ⟶ ptr_valid_u u (hrs_htd (hrs h)) &(p→f) ⟶ l (hrs_upd (hrs_mem_update (heap_upd_list (size_td u) &(p→f) (access_ti t x))) h) = w p x (l h)) (map (λfrw. (fst frw, snd (snd frw))) (zip fs (zip rs ws)))" unfolding list.pred_map using * by (rule list.pred_mono_strong) (auto simp: typ_heap_simulation_of_field_def) alsohave"map (λfrw. (fst frw, snd (snd frw))) (zip fs (zip rs ws)) = zip fs ws" by (simp add: list_eq_iff_nth_eq) finallyhave fs_ws: "list_all2 (λf w. ∀t u n h p x. field_ti TYPE('a) f = Some t ⟶ field_lookup (typ_uinfo_t TYPE('a)) f 0 = Some (u, n) ⟶ ptr_valid_u u (hrs_htd (hrs h)) &(p→f) ⟶ l (hrs_upd (hrs_mem_update (heap_upd_list (size_td u) &(p→f) (access_ti t x))) h) = w p x (l h)) fs ws" by (subst (asm) list_all_zip_iff_list_all2; simp)
have V_l: "∧h p. V (l h) p ⟷ PTR_VALID('a) (hrs_htd (hrs h)) p" by (simp add: V)
interpret write_simulation hrs hrs_upd l V W apply (rule write_simulationI[OF fs hrs, of ws "λx y. y" V _ R]) apply (rule fs_ws) apply (simp add: write_dedicated_heap_def heap_upd_id hrs_mem_update_id3 flip: id_def) apply (simp add: id_def) apply (rule V_l) apply (rule W) done
show"?t2 f w"if *: "?ws w"for w f apply (rule pointer_writer_disjnt_replace_by_const) apply (simp add: W[abs_def]) apply (intro pointer_writer_disjnt_fold_left *[rule_format]) done
show disj: "?t3 p f w"if *: "?ws2 p w"for p f w proof (standard, unfold comp_def) fix h have w_W_const: "w (W p (λx. c) h) = W p (λx. c) (w h)"for c h using *[rule_format, of c] apply (simp add: W) apply (induction ws arbitrary: h) apply (auto simp: fun_eq_iff) done have R_eq: "R (w h) p = R h p" apply (subst write_same[of "λ_. R h p" h p, OF refl, symmetric]) apply (subst w_W_const) apply (subst read_write_same) apply (rule refl) done
show"W p f (w h) = w (W p f h)" by (simp add: R_eq write_cong[of f _ _ "λ_. f (R h p)"] w_W_const) qed
show ?t1 proof fix h p assume V_p: "V (l h) p" thenshow"c_guard p"by (simp add: ptr_valid.ptr_valid_c_guard V)
have l_h: "l h = W p (λx. h_val (hrs_mem (hrs h)) p) (l h)" apply (subst write_commutes[OF V_p, symmetric]) apply (subst hrs.t_hrs.heap.upd_same) apply (cases "hrs h") apply (simp_all add: hrs_mem_update_def hrs_mem_def xmem_type_class.heap_update_id) done
show"R (l h) p = h_val (hrs_mem (hrs h)) p" apply (subst l_h) apply (subst read_write_same) apply simp done next fix p :: "'a ptr"and s assume p: "∀a∈ptr_span p. root_ptr_valid (hrs_htd (hrs s)) (PTR(stack_byte) a)" moreover
{ fix f w and r :: "'t ==> 'a ptr ==> 'a ==> 'a"and u n assume"typ_heap_simulation_of_field l hrs hrs_upd heap_typing_upd f r w" "field_lookup (typ_uinfo_t TYPE('a)) f 0 = Some (u, n)" with p have"r (l s) p ZERO('a) = ZERO('a)" unfolding typ_heap_simulation_of_field_def by (auto simp: field_ti_def field_lookup_typ_uinfo_t_Some typ_heap_simulation_of_field_def
dest!: field_lookup_uinfo_Some_rev) } note this[simp] from * fs_exists len have"fold (λr. r (l s) p) rs ZERO('a) = ZERO('a)" by (induction fs arbitrary: rs ws)
(auto simp: length_Suc_conv simp del: len) ultimatelyshow"R (l s) p = ZERO('a)" unfolding R[of _ _ "ZERO('a)"] by simp next
{ fix p f d have"W p f o heap_typing_upd d = heap_typing_upd d o W p f" apply (rule disj) using * len apply (induction fs arbitrary: ws rs) apply (auto simp add: length_Suc_conv typ_heap_simulation_of_field_def simp del: len) done thenshow"heap_typing_upd d (W p f h) = W p f (heap_typing_upd d h)"for h by (simp add: fun_eq_iff) } note heap_typing_W = this
show"V (W p' f h) p = V h p"for p' f h p unfolding V apply (subst hrs.upd_same[symmetric, of "λ_. heap_typing h", OF refl]) apply (subst heap_typing_W[symmetric]) apply (subst hrs.get_upd)
.. qed (simp_all add: V) qed
end
definition
field_with_lense :: "qualified_field_name ==> ('a::c_type ==> 'b::c_type) ==> (('b ==> 'b) ==> 'a ==> 'a) ==> bool" where "field_with_lense f g u ⟷ field_ti TYPE('a) f = Some (adjust_ti (typ_info_t TYPE('b)) g (u o (λx _. x))) ∧ lense g u"
lemma field_with_lense_Nil: "field_with_lense [] (λx. x) (λf x. f x)" by (simp add: field_with_lense_def lense_def comp_def adjust_ti_def update_desc_id map_td_id(1))
lemma field_with_lense_Cons: fixes g :: "'a::mem_type ==> 'b::mem_type"and gs :: "'b ==> 'c::mem_type" assumes fs: "field_with_lense fs gs us" assumes f: "field_ti TYPE('a) [f] = Some (adjust_ti (typ_info_t TYPE('b)) g (u o (λx _. x)))" assumes g_u: "fg_cons g (u o (λx _. x))" assumes u: "∧f x. u f x = u (λ_. f (g x)) x" shows"field_with_lense (f # fs) (λx. gs (g x)) (λf. u (us f))" unfolding field_with_lense_def proof from fs obtain n where fs: "field_lookup (typ_info_t TYPE('b)) fs 0 = Some (adjust_ti (typ_info_t TYPE('c)) gs (us o (λx _. x)), n)" and gs_us: "lense gs us" by (auto simp add: field_with_lense_def field_ti_def split: option.splits)
have g_u: "lense g u" using g_u apply (rule lense_of_fg_cons') apply (rule u) done theninterpret lense g u . show"lense (λx. gs (g x)) (λf. u (us f))" using g_u gs_us by (rule lense_compose)
have"(λx. gs (g x)) = gs ∘ g" "(λv x. u (λ_. us (λ_. v) (g x)) x) = (λf. u (us f)) ∘ (λx _. x)" by (simp_all add: fun_eq_iff cong: upd_cong) with field_ti_append_field_lookup[OF f, of fs 0] show"field_ti TYPE('a) (f # fs) = Some (adjust_ti (typ_info_t TYPE('c)) (λx. gs (g x)) ((λf. u (us f)) ∘ (λx _. x)))" unfolding field_lookup_adjust_ti2[OF fs] by (simp add: adjust_ti_adjust_ti) qed
lemma (in typ_heap_simulation_open_types) typ_heap_simulation_of_field: assumes f: "field_with_lense f g u" assumes v: "∧h p. PTR_VALID('a) (hrs_htd (t_hrs h)) p ==> v (st h) p" assumes g_zero: "g ZERO('x::mem_type) = ZERO('a)" shows"typ_heap_simulation_of_field st t_hrs t_hrs_update heap_typing_upd f (λh p. u (λ_. r h (PTR('a) &(p→f)))) (λp x. w (PTR('a) &(p→f)) (λ_. g x))" proof - have g_u: "lense g u"using f by (simp add: field_with_lense_def) theninterpret lense g u .
have [simp]: "fg_cons g (u ∘ (λx _. x))" by (rule fg_cons) obtain n where [simp]: "field_lookup (typ_uinfo_t TYPE('x)) f 0 = Some (typ_uinfo_t TYPE('a), n)" using f by (auto simp: field_ti_def field_lookup_typ_uinfo_t_Some field_with_lense_def
split: option.splits) have sz: "size_td (typ_info_t TYPE('a)) = size_of TYPE('a)" by (simp add: size_of_def)
have p_f_eq: "&(p→f) = ptr_val (PTR('c) &(p→f))"for p :: "'x ptr" by simp
have ptr_span_subset: "ptr_span (PTR('a) &(p→f)) ⊆ ptr_span p"for p :: "'x ptr" using field_tag_sub'[where 'a='x, of "f" _ _ p] by (simp add: size_of_def)
have u_zero: "u (λ_. ZERO('a)) ZERO('x) = ZERO('x)" by (simp add: upd_same g_zero)
show ?thesis using f apply (clarsimp simp: typ_heap_simulation_of_field_def field_with_lense_def, intro conjI allI impI)
subgoal by (simp add: heap_typing_upd_write_commute fun_eq_iff)
subgoal apply (rule partial_pointer_lenseI[OF g_u]) apply (rule pointer_lense_field_lvalue) apply assumption apply (simp add: size_of_def) done
subgoal for p using ptr_span_subset[of p] by (subst sim_stack_stack_byte_zero') (auto simp: u_zero)
subgoal apply (subst sz) apply (subst p_f_eq) apply (subst heap_update_eq_heap_upd_list[symmetric]) apply (rule write_commutes) apply (simp add: v ptr_valid_def) done done qed
lemma pointer_writer_disjnt_heap_array_map_right[pointer_writer_disjnt_intros]: "(∧x. pointer_writer_disjnt w' (λp. w p x)) ==> pointer_writer_disjnt w' (λp. heap_array_map p x)" by (metis pointer_writer_disjnt_heap_array_map pointer_writer_disjnt_sym)
lemma disjnt_comp_heap_array_map[disjnt_heap_fields_comp]: assumes w': "∧q x. w q x ∘ w' = w' ∘ w q x" shows"heap_array_map p x ∘ w' = w' ∘ heap_array_map p x" proof - have"heap_array_map p (λ_. c) ∘ w' = w' ∘ heap_array_map p (λ_. c)"for c apply (rule comp_commute_of_fold) apply (subst heap_array_map_def[abs_def], rule refl) apply (simp add: w' list_all_iff) done thenhave *: "w' (heap_array_map p (λ_. c) h) = heap_array_map p (λ_. c) (w' h)"for c h by (simp add: fun_eq_iff)
have [simp]: "heap_array (w' h) p = heap_array h p"for h apply (subst array.write_same[symmetric, of "λ_. heap_array h p", OF refl]) apply (subst *) apply (subst array.read_write_same) apply (rule refl) done show ?thesis apply (rule ext)
subgoal for h apply (clarsimp simp add: fun_eq_iff) apply (subst (12) array.write_cong[where f'="λ_. x (heap_array h p)"]) apply (simp_all flip: *) done done qed
end
lemma (in open_types) valid_array_of_ptr_valid_arrayI: fixes r :: "'t ==> 'a::{xmem_type, array_outer_max_size} ptr ==> 'a" fixes p :: "('a['n::{finite, array_max_count}]) ptr" assumes f: "map_of T (typ_uinfo_t TYPE('a['n])) = Some (array_fields CARD('n))" assumes p: "PTR_VALID('a['n]) h' p" assumes v: "∧p. PTR_VALID('a) h' p ==> v h p" shows"valid_array_base.valid_array v h p" unfolding valid_array_base.valid_array_def proof (intro allI impI v) fix n assume n: "n < CARD('n)" note fl_array = field_lookup_array[OF n, THEN field_lookup_typ_uinfo_t_Some]
have"[replicate n CHR ''1''] ∈ set (array_fields CARD('n))" using n by (auto simp: array_fields_def)
note * = ptr_valid_u_step[OF f this fl_array p[unfolded ptr_valid_def]] have"field_offset_untyped (typ_uinfo_t TYPE('a['n])) [replicate n CHR ''1''] = n * size_of TYPE('a)" by (simp add: field_offset_untyped_def fl_array) with * show"PTR_VALID('a) h' (array_ptr_index p False n)" by (simp add: n array_ptr_index_def ptr_add_def ptr_valid_def typ_uinfo_t_def) qed
lemma (in open_types) valid_array_of_ptr_valid_array1[simp]: fixes r :: "'t ==> 'a::{xmem_type, array_outer_max_size} ptr ==> 'a" fixes p :: "('a['n::{finite, array_max_count}]) ptr" assumes f: "map_of T (typ_uinfo_t TYPE('a['n])) = Some (array_fields CARD('n))" assumes p: "PTR_VALID('a['n]) (heap_typing h) p" shows"valid_array_base.valid_array (λh. PTR_VALID('a) (heap_typing h)) h p" by (rule valid_array_of_ptr_valid_arrayI[of "heap_typing h", OF f p])
lemma (in open_types) valid_array_of_ptr_valid_array2[simp]: fixes r :: "'t ==> 'a::{xmem_type, array_inner_max_size} ptr ==> 'a" fixes p :: "('a['n::{finite, array_max_count}]['m::{finite, array_max_count}]) ptr" assumes f2: "map_of T (typ_uinfo_t TYPE('a['n]['m])) = Some (array_fields CARD('m))" assumes f1: "map_of T (typ_uinfo_t TYPE('a['n])) = Some (array_fields CARD('n))" assumes p: "PTR_VALID('a['n]['m]) (heap_typing h) p" shows"valid_array_base.valid_array (valid_array_base.valid_array (λh. PTR_VALID('a) (heap_typing h))) h p" apply (rule valid_array_of_ptr_valid_arrayI[of "heap_typing h", OF f2 p]) apply (rule valid_array_of_ptr_valid_array1[OF f1]) apply assumption done
lemma (in open_types) ptr_valid_unsigned[simp]: "PTR_VALID('a::len8 signed word) h p ⟷ PTR_VALID('a::len8 word) h (PTR_COERCE('a signed word → 'a word) p)" by (simp add: typ_uinfo_t_signed_word_word_conv ptr_valid_def)
definition signed_heap:: "('s ==> 'a::len word ptr ==> 'a word) ==> ('s ==> 'a signed word ptr ==> 'a signed word)"where "signed_heap h s = UCAST ('a::len → 'a signed) o (h s) o PTR_COERCE('a signed word → 'a word)"
lemma signed_heap_apply[simp]: "signed_heap h s p = UCAST ('a::len → 'a signed) (h s (PTR_COERCE('a signed word → 'a word) p))" by (simp add: signed_heap_def)
lemma signed_typ_heap_simulation_of_typ_heap_simulation: fixes r :: "_ ==> _ ==> 'a::len8 word" assumes r: "typ_heap_simulation_open_types T st r w v t_hrs t_hrs_update heap_typing heap_typing_upd" shows"typ_heap_simulation_open_types T st (signed_heap r) (λp m. w (PTR_COERCE('a signed word → 'a word) p) (λw. UCAST('a signed → 'a) (m (UCAST('a → 'a signed) w)))) (λh p. v h (PTR_COERCE('a signed word → 'a word) p)) t_hrs t_hrs_update heap_typing heap_typing_upd" proof - interpret typ_heap_simulation_open_types T st r w v t_hrs t_hrs_update heap_typing heap_typing_upd by fact interpret cast: pointer_lense "signed_heap r" "λp m. w (PTR_COERCE('a signed word → 'a word) p) (λw. UCAST('a signed → 'a) (m (UCAST('a → 'a signed) w)))" unfolding signed_heap_def comp_def by (rule pointer_lense_ucast_signed) unfold_locales have [simp]: "c_guard p ⟷ c_guard (PTR_COERCE('a signed word → 'a word) p)"for p apply (intro c_guard_ptr_coerce[symmetric]) apply (simp_all add: size_of_signed_word align_of_signed_word) done note scast_ucast_norm[simp del] note ucast_ucast_id[simp] show ?thesis apply unfold_locales apply (simp_all add: ptr_valid_unsigned ptr_valid_imp_v
read_commutes h_val_signed_word write_padding_commutes heap_typing_upd_write_commute) apply (subst heap_update_padding_signed_word(2)[symmetric]) apply (subst write_padding_commutes) apply (simp_all add: size_of_signed_word scast_ucast_down_same valid_implies_c_guard) apply (rule valid_same_typ_desc, simp) apply (simp add: sim_stack_stack_byte_zero') apply (simp add: ucast_zero_word) done qed
lemma signed_typ_heap_simulation_of_typ_heap_simulation': fixes r :: "_ ==> _ ==> 'a::len8 word" assumes r : "typ_heap_simulation_open_types T st r w v t_hrs t_hrs_update heap_typing heap_typing_upd" shows"typ_heap_simulation_open_types T st (λs p. ucast (r s (ptr_coerce p)) :: 'a signed word) (λp m. w (PTR_COERCE('a signed word → 'a word) p) (λw. UCAST('a signed → 'a) (m (UCAST('a → 'a signed) w)))) (λh p. v h (PTR_COERCE('a signed word → 'a word) p)) t_hrs t_hrs_update heap_typing heap_typing_upd" apply (rule signed_typ_heap_simulation_of_typ_heap_simulation [unfolded signed_heap_def comp_def]) apply (rule r) done
text"The next lemma is intended to convert pointers to signed words to pointers to unsigned words. We only have dedicated heaps for unsigned words pointers to signed words are retrieved from the unsigned heap inserting the necessary coercision." lemma ptr_coerce_typ_heap_simulation_open_types: assumes r: "typ_heap_simulation_open_types T st (r :: 's ==> ('a::c_type) ptr ptr ==> 'a ptr) w v t_hrs t_hrs_update heap_typing heap_typing_upd" assumes same_name: "typ_name_itself TYPE('a) = typ_name_itself TYPE('b)" ― ‹signed words and unsigned words
have the same name, this also propagates to pointers to words, and pointers to pointers to words, and so on.› shows"typ_heap_simulation_open_types T st (λs p. ptr_coerce (r s (ptr_coerce p)) :: ('b::c_type) ptr) (λp f. (w (ptr_coerce p) ((λx. ptr_coerce (f (ptr_coerce x)))))) (λs p. v s (ptr_coerce p)) t_hrs t_hrs_update heap_typing heap_typing_upd" proof - interpret typ_heap_simulation_open_types T st r w v t_hrs t_hrs_update heap_typing heap_typing_upd by fact show ?thesis apply (rule typ_heap_simulation_open_types.intro)
subgoal apply (rule typ_heap_simulation_ptr_coerce) using r by (simp add: typ_heap_simulation_open_types_def)
subgoal using r by (simp add: typ_heap_simulation_open_types_def)
subgoal apply (unfold_locales)
subgoal by (simp)
subgoal by (simp add: heap_typing_upd_write_commute)
subgoal using ptr_valid_ptr_coerce_conv [OF same_name] ptr_valid_imp_v by fastforce
subgoal
using sim_stack_stack_byte_zero'
ptr_coerce_zero by fastforce done done qed
lemma array_typ_heap_simulation_of_typ_heap_simulation: fixes r :: "_ ==> _ ==> 'a::{stack_type, xmem_type, array_outer_max_size}" assumes"typ_heap_simulation_open_types T st r w v t_hrs t_hrs_update heap_typing heap_typing_upd" assumes f: "map_of T (typ_uinfo_t TYPE('a['n::{finite, array_max_count}])) = Some (array_fields CARD('n))" shows "typ_heap_simulation_open_types T st (pointer_array_lense.heap_array r :: _ ==> ('a['n]) ptr ==> _) (pointer_array_lense.heap_array_map r w) (valid_array_base.valid_array v) t_hrs t_hrs_update heap_typing heap_typing_upd" proof - interpret sim: typ_heap_simulation_open_types T st r w v t_hrs t_hrs_update by fact interpret array_typ_heap_simulation st r w v t_hrs t_hrs_update .. show ?thesis proof fix p :: "('a['n]) ptr"and d f have"heap_array_map p f o heap_typing_upd d = heap_typing_upd d o heap_array_map p f" by (intro disjnt_comp_heap_array_map)
(simp add: fun_eq_iff sim.heap_typing_upd_write_commute) thenshow"heap_typing_upd d (heap_array_map p f h) = heap_array_map p f (heap_typing_upd d h)"for h by (simp add: fun_eq_iff) show"heap_array (st s) p = ZERO(_)" if p: "∀a∈ptr_span p. root_ptr_valid (hrs_htd (t_hrs s)) (PTR(stack_byte) a)"for s apply (intro array_ext) apply (simp add: array_index_zero) apply (intro sim.sim_stack_stack_byte_zero')
subgoal for i using ptr_span_array_ptr_index_subset_ptr_span[of i p False] p apply auto done done show"sim.ptr_valid (heap_typing h) p ==> valid_array h p"for h by (rule sim.valid_array_of_ptr_valid_arrayI[OF f, of "heap_typing h"])
(simp_all add: sim.ptr_valid_imp_v) qed simp qed
lemma (in typ_heap_simulation_open_types) stack_simulation_heap_typingI: assumes hrs: "heap_typing_simulation T t_hrs t_hrs_update heap_typing heap_typing_upd st" assumes sim_stack_alloc_heap_typing: "∧p d s n. (p, d) ∈ stack_allocs n S TYPE('a) (hrs_htd (t_hrs s)) ==> st (t_hrs_update (hrs_mem_update (fold (λi. heap_update (p +p int i) c_type_class.zero) [0..<n]) ∘ hrs_htd_update (λ_. d)) s) = (heap_typing_upd (λ_. d) (st s))" assumes sim_stack_release_heap_typing: "∧(p::'a ptr) s n. (∧i. i < n ==> root_ptr_valid (hrs_htd (t_hrs s)) (p +p int i)) ==> st (t_hrs_update (hrs_htd_update (stack_releases n p)) s) = heap_typing_upd (stack_releases n p) (st (t_hrs_update (hrs_mem_update (fold (λi. heap_update (p +p int i) c_type_class.zero) [0..<n])) s))" shows"stack_simulation_heap_typing st r w t_hrs t_hrs_update heap_typing heap_typing_upd ST" proof - interpret hrs: heap_typing_simulation T t_hrs t_hrs_update heap_typing heap_typing_upd st by fact interpret write_simulation t_hrs t_hrs_update st "λt p. open_types.ptr_valid T (heap_typing t) p" w apply (rule hrs.write_simulation_alt) apply simp apply (simp_all add: ptr_valid.ptr_valid_c_guard ptr_valid_imp_v write_commutes read_commutes) done interpret typ_heap_simulation
st r w "λt p. open_types.ptr_valid T (heap_typing t) p" t_hrs t_hrs_update by unfold_locales
(simp_all add: ptr_valid.ptr_valid_c_guard ptr_valid_imp_v write_commutes read_commutes) show ?thesis proof qed (simp_all add: sim_stack_stack_byte_zero' sim_stack_alloc_heap_typing sim_stack_release_heap_typing) qed
end
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.267Bemerkung:
(vorverarbeitet am 2026-06-10)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.