Theory Guards
subsection ‹Consistency›
text ‹In this file, we define several notions and prove many lemmas about guard states, which are useful
to prove that the rules of the logic are sound.›
theory Guards
imports StateModel CommCSL AbstractCommutativity
begin
text ‹A state is "consistent" iff:
1. All its permissions are full
2. Has unique guards iff has shared guard
3. The values in the fractional heaps are "reachable" wrt to the sequence and multiset of actions
4. Has exactly guards for the names in "scope"›
definition reachable :: "('i, 'a, 'v) single_context ⇒ 'v ⇒ ('i, 'a) heap ⇒ bool" where
"reachable scont v0 h ⟷ (∀sargs uargs. get_gs h = Some (pwrite, sargs) ∧ (∀k. get_gu h k = Some (uargs k))
⟶ reachable_value (saction scont) (uaction scont) v0 sargs uargs (view scont (normalize (get_fh h))))"
lemma reachableI:
assumes "⋀sargs uargs. get_gs h = Some (pwrite, sargs) ∧ (∀k. get_gu h k = Some (uargs k))
⟹ reachable_value (saction scont) (uaction scont) v0 sargs uargs (view scont (normalize (get_fh h)))"
shows "reachable scont v0 h"
by (metis assms reachable_def)
lemma reachableE:
assumes "reachable scont v0 h"
and "get_gs h = Some (pwrite, sargs)"
and "⋀k. get_gu h k = Some (uargs k)"
shows "reachable_value (saction scont) (uaction scont) v0 sargs uargs (view scont (normalize (get_fh h)))"
by (meson assms reachable_def)
definition all_guards :: "('i, 'a) heap ⇒ bool" where
"all_guards h ⟷ (∃v. get_gs h = Some (pwrite, v)) ∧ (∀k. get_gu h k ≠ None)"
lemma no_guardI:
assumes "get_gs h = None"
and "⋀k. get_gu h k = None"
shows "no_guard h"
using assms(1) assms(2) no_guard_def by blast
definition semi_consistent :: "('i, 'a, 'v) single_context ⇒ 'v ⇒ ('i, 'a) heap ⇒ bool" where
"semi_consistent Γ v0 h ⟷ all_guards h ∧ reachable Γ v0 h"
lemma semi_consistentE:
assumes "semi_consistent Γ v0 h"
shows "∃sargs uargs. get_gs h = Some (pwrite, sargs) ∧ (∀k. get_gu h k = Some (uargs k))
∧ reachable_value (saction Γ) (uaction Γ) v0 sargs uargs (view Γ (normalize (get_fh h)))"
proof -
let ?uargs = "λk. (SOME x. get_gu h k = Some x)"
have "⋀k. get_gu h k = Some (?uargs k)"
proof -
fix k have "∃x. get_gu h k = Some x"
by (meson all_guards_def assms option.exhaust_sel semi_consistent_def)
then show "get_gu h k = Some (?uargs k)"
by fastforce
qed
moreover obtain sargs where "get_gs h = Some (pwrite, sargs)"
by (meson all_guards_def assms semi_consistent_def)
ultimately have "reachable_value (saction Γ) (uaction Γ) v0 sargs ?uargs (view Γ (normalize (get_fh h)))"
by (meson assms reachableE semi_consistent_def)
then show ?thesis
using ‹⋀k. get_gu h k = Some (SOME x. get_gu h k = Some x)› ‹get_gs h = Some (pwrite, sargs)› by fastforce
qed
lemma semi_consistentI:
assumes "all_guards h"
and "reachable Γ v0 h"
shows "semi_consistent Γ v0 h"
by (simp add: assms(1) assms(2) semi_consistent_def)
lemma no_guard_then_smaller_same:
assumes "Some h = Some a ⊕ Some b"
and "no_guard h"
shows "no_guard a"
proof (rule no_guardI)
show "get_gs a = None"
by (metis add_gs.elims assms(1) assms(2) no_guard_def option.simps(3) plus_extract(2))
fix k
have "get_gu h k = None"
by (meson assms(2) no_guard_def)
then show "get_gu a k = None"
by (metis assms(1) full_uguard_sum_same option.exhaust)
qed
lemma all_guardsI:
assumes "⋀k. get_gu h k ≠ None"
and "∃v. get_gs h = Some (pwrite, v)"
shows "all_guards h"
using all_guards_def assms(1) assms(2) by blast
lemma all_guards_same:
assumes "all_guards a"
and "Some h = Some a ⊕ Some b"
shows "all_guards h"
proof (rule all_guardsI)
show "∃v. get_gs h = Some (pwrite, v)"
using all_guards_def assms(1) assms(2) full_sguard_sum_same by blast
fix k have "get_gu a k ≠ None"
by (meson all_guards_def assms(1))
then show "get_gu h k ≠ None"
apply (cases "get_gu b k")
apply (metis assms(2) full_uguard_sum_same not_Some_eq)
by (metis assms(2) full_uguard_sum_same option.discI plus_comm)
qed
definition empty_unique where
"empty_unique _ = None"
definition remove_guards :: "('i, 'a) heap ⇒ ('i, 'a) heap" where
"remove_guards h = (get_fh h, None, empty_unique)"
lemma remove_guards_smaller:
"h ≽ remove_guards h"
proof -
have "remove_guards h ## (Map.empty, get_gs h, get_gu h)"
proof (rule compatibleI)
show "compatible_fract_heaps (get_fh (remove_guards h)) (get_fh (Map.empty, get_gs h, get_gu h))"
using compatible_fract_heapsI by force
show "⋀k. get_gu (remove_guards h) k = None ∨ get_gu (Map.empty, get_gs h, get_gu h) k = None"
by (simp add: empty_unique_def remove_guards_def)
show "⋀p p'. get_gs (remove_guards h) = Some p ∧ get_gs (Map.empty, get_gs h, get_gu h) = Some p' ⟹ pgte pwrite (padd (fst p) (fst p'))"
by (simp add: remove_guards_def)
qed
then obtain x where "Some x = Some (remove_guards h) ⊕ Some (Map.empty, get_gs h, get_gu h)"
by auto
moreover have "x = h"
proof (rule heap_ext)
show "get_fh x = get_fh h"
by (metis add_fh_map_empty add_get_fh calculation fst_conv get_fh.elims remove_guards_def)
show "get_gs x = get_gs h"
by (metis calculation fst_eqD get_gs.elims plus_comm remove_guards_def snd_eqD sum_gs_one_none)
show "get_gu x = get_gu h"
proof (rule ext)
fix k
have "get_gu (remove_guards h) k = None"
by (simp add: empty_unique_def remove_guards_def)
then show "get_gu x k = get_gu h k"
by (metis (mono_tags, lifting) add_gu_def add_gu_single.simps(1) calculation get_gu.elims plus_extract(3) snd_eqD)
qed
qed
ultimately show ?thesis
using larger_def by blast
qed
lemma no_guard_remove:
assumes "Some a = Some b ⊕ Some c"
and "no_guard c"
shows "get_gs a = get_gs b"
and "get_gu a = get_gu b"
using assms(1) assms(2) no_guard_def sum_gs_one_none apply blast
proof (rule ext)
fix k
have "get_gu c k = None"
by (meson assms(2) no_guard_def)
then show "get_gu a k = get_gu b k"
by (metis (no_types, lifting) add_gu_def add_gu_single.simps(1) assms(1) plus_comm plus_extract(3))
qed
lemma full_guard_comp_then_no:
assumes "a ## b"
and "all_guards a"
shows "no_guard b"
proof (rule no_guardI)
show "⋀k. get_gu b k = None"
by (meson all_guards_def assms(1) assms(2) compatible_def)
show "get_gs b = None"
proof (rule ccontr)
assume "get_gs b ≠ None"
then obtain gb where "get_gs b = Some gb"
by blast
moreover obtain v where "get_gs a = Some (pwrite, v)"
by (meson all_guards_def assms(2))
moreover have "pgt (padd pwrite (fst gb)) pwrite"
using sum_larger by auto
ultimately show False
by (metis assms(1) compatible_def fst_eqD not_pgte_charact)
qed
qed
lemma sum_of_no_guards:
assumes "no_guard a"
and "no_guard b"
and "Some x = Some a ⊕ Some b"
shows "no_guard x"
by (metis assms(1) assms(2) assms(3) no_guard_def no_guard_remove(1) no_guard_remove(2))
lemma no_guard_remove_guards:
"no_guard (remove_guards h)"
by (simp add: empty_unique_def no_guard_def remove_guards_def)
lemma get_fh_remove_guards:
"get_fh (remove_guards h) = get_fh h"
by (simp add: remove_guards_def)
definition pair_sat :: "(store × ('i, 'a) heap) set ⇒ (store × ('i, 'a) heap) set ⇒ ('i, 'a, nat) assertion ⇒ bool" where
"pair_sat S S' Q ⟷ (∀σ σ'. σ ∈ S ∧ σ' ∈ S' ⟶ σ, σ' ⊨ Q)"
lemma pair_satI:
assumes "⋀s h s' h'. (s, h) ∈ S ∧ (s', h') ∈ S' ⟹ (s, h), (s', h') ⊨ Q"
shows "pair_sat S S' Q"
by (simp add: assms pair_sat_def)
lemma pair_sat_smallerI:
assumes "⋀σ σ'. σ ∈ S ∧ σ' ∈ S' ⟹ σ, σ' ⊨ Q"
shows "pair_sat S S' Q"
by (simp add: assms pair_sat_def)
lemma pair_satE:
assumes "pair_sat S S' Q"
and "(s, h) ∈ S ∧ (s', h') ∈ S'"
shows "(s, h), (s', h') ⊨ Q"
using assms(1) assms(2) pair_sat_def by blast
definition add_states :: "(store × ('i, 'a) heap) set ⇒ (store × ('i, 'a) heap) set ⇒ (store × ('i, 'a) heap) set" where
"add_states S1 S2 = {(s, H) |s H h1 h2. Some H = Some h1 ⊕ Some h2 ∧ (s, h1) ∈ S1 ∧ (s, h2) ∈ S2}"
lemma add_states_sat_star:
assumes "pair_sat SA SA' A"
and "pair_sat SB SB' B"
shows "pair_sat (add_states SA SB) (add_states SA' SB') (Star A B)"
proof (rule pair_satI)
fix s h s' h'
assume asm0: "(s, h) ∈ add_states SA SB ∧ (s', h') ∈ add_states SA' SB'"
then obtain ha hb ha' hb' where "(s, ha) ∈ SA" "(s, hb) ∈ SB" "(s', ha') ∈ SA'" "(s', hb') ∈ SB'"
"Some h = Some ha ⊕ Some hb" "Some h' = Some ha' ⊕ Some hb'"
using add_states_def[of SA SB] add_states_def[of SA' SB'] fst_eqD mem_Collect_eq snd_conv
by auto
then show "(s, h), (s', h') ⊨ Star A B"
by (meson assms(1) assms(2) hyper_sat.simps(4) pair_sat_def)
qed
lemma add_states_subset:
assumes "S1 ⊆ S1'"
shows "add_states S1 S2 ⊆ add_states S1' S2"
proof
fix x assume "x ∈ add_states S1 S2"
then show "x ∈ add_states S1' S2"
using add_states_def[of S1 S2] add_states_def[of S1' S2] assms mem_Collect_eq[of x] subsetD[of S1 S1']
by blast
qed
lemma add_states_comm:
"add_states S1 S2 = add_states S2 S1"
proof -
have "⋀S1 S2. add_states S1 S2 ⊆ add_states S2 S1"
proof -
fix S1 S2
show "add_states S1 S2 ⊆ add_states S2 S1"
proof
fix x assume "x ∈ add_states S1 S2"
then obtain h1 h2 where "Some (snd x) = Some h1 ⊕ Some h2" "(fst x, h1) ∈ S1" "(fst x, h2) ∈ S2"
using add_states_def[of S1 S2] fst_conv mem_Collect_eq[of x] snd_eqD
by auto
moreover have "Some (snd x) = Some h2 ⊕ Some h1"
by (simp add: calculation(1) plus_comm)
ultimately show "x ∈ add_states S2 S1"
using add_states_def[of S2 S1] mem_Collect_eq[of x] surjective_pairing[of x] by blast
qed
qed
then show ?thesis by blast
qed
text ‹The following lemma is the reason why we require many assertions to be precise in the logic.›
lemma magic_lemma:
assumes "Some x1 = Some a1 ⊕ Some j1"
and "Some x2 = Some a2 ⊕ Some j2"
and "(s1, x1), (s2, x2) ⊨ Star A J"
and "(s1, j1), (s2, j2) ⊨ J"
and "precise J"
shows "(s1, a1), (s2, a2) ⊨ A"
proof -
obtain a1' a2' j1' j2' where "Some x1 = Some a1' ⊕ Some j1'"
"Some x2 = Some a2' ⊕ Some j2'" "(s1, j1'), (s2, j2') ⊨ J" "(s1, a1'), (s2, a2') ⊨ A"
using assms(3) hyper_sat.simps(4) by blast
have "j1 = j1' ∧ j2 = j2'"
using assms(5)
proof (rule preciseE)
show "x1 ≽ j1' ∧ x1 ≽ j1 ∧ x2 ≽ j2' ∧ x2 ≽ j2"
by (metis ‹Some x1 = Some a1' ⊕ Some j1'› ‹Some x2 = Some a2' ⊕ Some j2'› assms(1) assms(2) larger_def plus_comm)
show "(s1, j1'), (s2, j2') ⊨ J ∧ (s1, j1), (s2, j2) ⊨ J"
by (simp add: ‹(s1, j1'), (s2, j2') ⊨ J› assms(4))
qed
then have "a1 = a1' ∧ a2 = a2'"
using ‹Some x1 = Some a1' ⊕ Some j1'› ‹Some x2 = Some a2' ⊕ Some j2'› addition_cancellative assms(1) assms(2) by blast
then show ?thesis
using ‹(s1, a1'), (s2, a2') ⊨ A› by blast
qed
lemma full_no_guard_same_normalize:
assumes "full_ownership (get_fh h) ∧ no_guard h"
and "full_ownership (get_fh h') ∧ no_guard h'"
and "normalize (get_fh h) = normalize (get_fh h')"
shows "h = h'"
proof (rule heap_ext)
show "get_gu h = get_gu h'"
apply (rule ext)
by (metis assms(1) assms(2) no_guard_def)
show "get_gs h = get_gs h'"
by (metis assms(1) assms(2) no_guard_def)
show "get_fh h = get_fh h'"
proof (rule ext)
fix l show "get_fh h l = get_fh h' l"
apply (cases "get_fh h l")
apply (metis FractionalHeap.normalize_eq(1) assms(3))
apply (cases "get_fh h' l")
apply (metis FractionalHeap.normalize_eq(1) assms(3))
by (metis FractionalHeap.normalize_def apply_opt.simps(2) assms(1) assms(2) assms(3) full_ownership_def prod.collapse)
qed
qed
lemma get_fh_same_then_remove_guards_same:
assumes "get_fh a = get_fh b"
shows "remove_guards a = remove_guards b"
by (metis assms remove_guards_def)
lemma remove_guards_sum:
assumes "Some x = Some a ⊕ Some b"
shows "Some (remove_guards x) = Some (remove_guards a) ⊕ Some (remove_guards b)"
proof -
have "remove_guards a ## remove_guards b"
by (metis (no_types, lifting) assms compatible_def compatible_eq get_fh_remove_guards no_guard_def no_guard_remove_guards option.distinct(1))
then obtain y where "Some y = Some (remove_guards a) ⊕ Some (remove_guards b)"
by auto
moreover have "remove_guards x = y"
by (metis (no_types, lifting) ‹remove_guards a ## remove_guards b› add_get_fh assms calculation get_fh_remove_guards get_gu.simps no_guard_def no_guard_remove(1) no_guard_remove(2) no_guard_remove_guards option.inject plus.simps(3) plus_extract(2) remove_guards_def snd_eqD)
ultimately show ?thesis by blast
qed
lemma no_guard_smaller:
assumes "a ≽ b"
shows "remove_guards a ≽ remove_guards b"
using assms larger_def remove_guards_sum by blast
definition add_empty_guards :: "('i, 'a) heap ⇒ ('i, 'a) heap" where
"add_empty_guards h = (get_fh h, Some (pwrite, {#}), (λ_. Some []))"
lemma no_guard_map_empty_compatible:
assumes "no_guard a"
and "get_fh b = Map.empty"
shows "a ## b"
by (metis (no_types, lifting) assms(1) assms(2) compatible_def compatible_fract_heapsI no_guard_def option.simps(3))
lemma no_guard_add_empty_is_add:
assumes "no_guard h"
shows "Some (add_empty_guards h) = Some h ⊕ Some (Map.empty, Some (pwrite, {#}), (λ_. Some []))"
proof -
obtain x where "Some x = Some h ⊕ Some (Map.empty, Some (pwrite, {#}), (λ_. Some []))"
by (simp add: assms no_guard_map_empty_compatible)
moreover have "add_empty_guards h = x"
proof (rule heap_ext)
show "get_fh (add_empty_guards h) = get_fh x"
by (metis add_empty_guards_def add_fh_map_empty add_get_fh calculation fst_conv get_fh.elims)
show "get_gs (add_empty_guards h) = get_gs x"
by (metis add_empty_guards_def assms calculation get_gs.elims no_guard_remove(1) plus_comm snd_eqD)
show "get_gu (add_empty_guards h) = get_gu x"
by (metis add_empty_guards_def assms calculation get_gu.elims no_guard_remove(2) plus_comm snd_eqD)
qed
ultimately show ?thesis by blast
qed
lemma no_guard_and_sat_p_empty_guards:
assumes "(s, h), (s', h') ⊨ A"
and "no_guard h ∧ no_guard h'"
shows "(s, add_empty_guards h), (s', add_empty_guards h') ⊨ Star A EmptyFullGuards"
proof -
have "(s, (Map.empty, Some (pwrite, {#}), (λ_. Some []))), (s', (Map.empty, Some (pwrite, {#}), (λ_. Some []))) ⊨ EmptyFullGuards"
by simp
then show ?thesis
using assms(1) assms(2) hyper_sat.simps(4) no_guard_add_empty_is_add by blast
qed
lemma no_guard_add_empty_guards_sum:
assumes "no_guard x"
and "Some x = Some a ⊕ Some b"
shows "Some (add_empty_guards x) = Some (add_empty_guards a) ⊕ Some b"
using assms(1) assms(2) no_guard_add_empty_is_add[of a] no_guard_add_empty_is_add[of x]
no_guard_then_smaller_same[of x a b] plus_asso plus_comm
by (metis (no_types, lifting))
lemma semi_consistent_empty_no_guard_initial_value:
assumes "no_guard h"
shows "semi_consistent Γ (view Γ (FractionalHeap.normalize (get_fh h))) (add_empty_guards h)"
proof (rule semi_consistentI)
show "all_guards (add_empty_guards h)"
by (simp add: add_empty_guards_def all_guards_def)
show "reachable Γ (view Γ (FractionalHeap.normalize (get_fh h))) (add_empty_guards h)"
proof (rule reachableI)
fix sargs uargs
assume asm0: "get_gs (add_empty_guards h) = Some (pwrite, sargs) ∧ (∀k. get_gu (add_empty_guards h) k = Some (uargs k))"
then have "sargs = {#} ∧ uargs = (λk. [])"
by (metis add_empty_guards_def fst_conv get_gs.simps get_gu.simps option.sel snd_conv)
then show "reachable_value (saction Γ) (uaction Γ) (view Γ (FractionalHeap.normalize (get_fh h))) sargs uargs
(view Γ (FractionalHeap.normalize (get_fh (add_empty_guards h))))"
by (simp add: Self add_empty_guards_def)
qed
qed
lemma no_guards_remove_same:
assumes "no_guard h"
shows "h = remove_guards (add_empty_guards h)"
by (metis add_empty_guards_def addition_cancellative assms fst_conv get_fh.elims get_fh_remove_guards no_guard_add_empty_is_add no_guard_remove_guards)
lemma no_guards_remove:
"no_guard h ⟷ h = remove_guards h"
by (metis get_fh_remove_guards no_guard_remove_guards no_guards_remove_same remove_guards_def)
definition add_sguard_to_no_guard :: "('i, 'a) heap ⇒ prat ⇒ 'a multiset ⇒ ('i, 'a) heap" where
"add_sguard_to_no_guard h π ms = (get_fh h, Some (π, ms), (λ_. None))"
lemma get_fh_add_sguard:
"get_fh (add_sguard_to_no_guard h π ms) = get_fh h"
by (simp add: add_sguard_to_no_guard_def)
lemma add_sguard_as_sum:
assumes "no_guard h"
shows "Some (add_sguard_to_no_guard h π ms) = Some h ⊕ Some (Map.empty, Some (π, ms), (λ_. None))"
proof -
obtain x where "Some x = Some h ⊕ Some (Map.empty, Some (π, ms), (λ_. None))"
by (simp add: assms no_guard_map_empty_compatible)
moreover have "x = add_sguard_to_no_guard h π ms"
proof (rule heap_ext)
show "get_fh x = get_fh (add_sguard_to_no_guard h π ms)"
by (metis add_fh_map_empty add_get_fh calculation fst_conv get_fh.elims get_fh_add_sguard)
show "get_gs x = get_gs (add_sguard_to_no_guard h π ms)"
by (metis add_sguard_to_no_guard_def assms calculation get_gs.elims no_guard_def plus_comm snd_eqD sum_gs_one_none)
show "get_gu x = get_gu (add_sguard_to_no_guard h π ms)"
by (metis add_sguard_to_no_guard_def assms calculation get_gu.simps no_guard_remove(2) plus_comm snd_conv)
qed
ultimately show ?thesis by blast
qed
definition add_uguard_to_no_guard :: "'i ⇒ ('i, 'a) heap ⇒ 'a list ⇒ ('i, 'a) heap" where
"add_uguard_to_no_guard k h l = (get_fh h, None, (λ_. None)(k := Some l))"
lemma get_fh_add_uguard:
"get_fh (add_uguard_to_no_guard k h l) = get_fh h"
by (simp add: add_uguard_to_no_guard_def)
lemma prove_sum:
assumes "a ## b"
and "⋀x. Some x = Some a ⊕ Some b ⟹ x = y"
shows "Some y = Some a ⊕ Some b"
using assms(1) assms(2) by fastforce
lemma add_uguard_as_sum:
assumes "no_guard h"
shows "Some (add_uguard_to_no_guard k h l) = Some h ⊕ Some (Map.empty, None, (λ_. None)(k := Some l))"
proof (rule prove_sum)
show "h ## (Map.empty, None, [k ↦ l])"
by (simp add: assms no_guard_map_empty_compatible)
fix x assume asm0: "Some x = Some h ⊕ Some (Map.empty, None, [k ↦ l])"
show "x = add_uguard_to_no_guard k h l"
proof (rule heap_ext)
show "get_fh x = get_fh (add_uguard_to_no_guard k h l)"
by (metis add_fh_map_empty add_get_fh asm0 fst_conv get_fh.elims get_fh_add_uguard)
show "get_gs x = get_gs (add_uguard_to_no_guard k h l)"
by (metis add_uguard_to_no_guard_def asm0 assms get_gs.elims no_guard_def plus_comm snd_eqD sum_gs_one_none)
show "get_gu x = get_gu (add_uguard_to_no_guard k h l)"
by (metis add_uguard_to_no_guard_def asm0 assms get_gu.elims no_guard_remove(2) plus_comm snd_eqD)
qed
qed
lemma no_guard_and_no_heap:
assumes "Some h = Some p ⊕ Some g"
and "no_guard p"
and "get_fh g = Map.empty"
shows "remove_guards h = p"
proof (rule heap_ext)
show "get_fh (remove_guards h) = get_fh p"
proof -
have "get_fh (remove_guards h) = get_fh h"
using get_fh_remove_guards by blast
moreover have "get_fh h = add_fh (get_fh p) (get_fh g)"
using add_get_fh assms(1) by blast
ultimately show ?thesis
by (metis assms(1) assms(3) ext get_fh.simps sum_second_none_get_fh)
qed
show "get_gs (remove_guards h) = get_gs p"
by (metis assms(2) no_guard_def no_guard_remove_guards)
show "get_gu (remove_guards h) = get_gu p"
by (metis ‹get_fh (remove_guards h) = get_fh p› assms(2) get_fh_remove_guards no_guards_remove remove_guards_def)
qed
lemma decompose_guard_remove_easy:
"Some h = Some (remove_guards h) ⊕ Some (Map.empty, get_gs h, get_gu h)"
proof (rule prove_sum)
show "remove_guards h ## (Map.empty, get_gs h, get_gu h)"
by (simp add: no_guard_map_empty_compatible no_guard_remove_guards)
fix x assume asm0: "Some x = Some (remove_guards h) ⊕ Some (Map.empty, get_gs h, get_gu h)"
show "x = h"
proof (rule heap_ext)
show "get_fh x = get_fh h"
by (metis add_fh_map_empty add_get_fh asm0 fst_conv get_fh.elims get_fh_remove_guards)
show "get_gs x = get_gs h"
by (metis asm0 fst_conv get_gs.simps no_guard_remove(1) no_guard_remove_guards plus_comm snd_conv)
show "get_gu x = get_gu h"
by (metis asm0 get_gu.elims no_guard_remove(2) no_guard_remove_guards plus_comm snd_eqD)
qed
qed
lemma all_guards_no_guard_propagates:
assumes "all_guards x"
and "Some x = Some a ⊕ Some b"
and "no_guard a"
shows "all_guards b"
by (metis all_guards_def assms(1) assms(2) assms(3) no_guard_def no_guard_remove(2) plus_comm sum_gs_one_none)
lemma all_guards_exists_uargs:
assumes "all_guards x"
shows "∃uargs. ∀k. get_gu x k = Some (uargs k)"
proof -
let ?uargs = "λk. the (get_gu x k)"
have "⋀k. get_gu x k = Some (?uargs k)"
by (metis all_guards_def assms option.collapse)
then show ?thesis
by fastforce
qed
lemma all_guards_sum_known_one:
assumes "Some x = Some a ⊕ Some b"
and "all_guards x"
and "⋀k. get_gu a k = None"
and "get_gs a = Some (π, ms)"
shows "∃π' msf uargs. (∀k. get_gu b k = Some (uargs k)) ∧
((π = pwrite ∧ get_gs b = None ∧ msf = {#}) ∨ (pwrite = padd π π' ∧ get_gs b = Some (π', msf)))"
proof (cases "π = pwrite")
case True
then have "get_gs b = None"
using add_gs.simps(2)[of "(π, ms)"] add_gs_cancellative add_gs_comm assms(1) assms(4) full_sguard_sum_same
plus_extract(2)[of x a b]
by metis
moreover obtain uargs where "⋀k. get_gu x k = Some (uargs k)"
using all_guards_exists_uargs assms(2) by blast
moreover have "⋀k. get_gu b k = Some (uargs k)"
proof -
fix k
have "get_gu a k = None"
using assms(3) by auto
then show "get_gu b k = Some (uargs k)"
by (metis (no_types, opaque_lifting) add_gu_def add_gu_single.simps(1) assms(1) calculation(2) plus_extract(3))
qed
ultimately show ?thesis
using True by blast
next
case False
then obtain π' msf where "get_gs b = Some (π', msf)"
by (metis all_guards_def assms(1) assms(2) assms(4) fst_conv option.exhaust_sel option.sel prod.exhaust_sel sum_gs_one_none)
moreover obtain v where "get_gs x = Some (pwrite, v)"
by (meson all_guards_def assms(2))
ultimately have "pwrite = padd π π'"
by (metis Pair_inject assms(1) assms(4) option.inject sum_gs_one_some)
then show ?thesis
by (metis (mono_tags, opaque_lifting) ‹get_gs b = Some (π', msf)› add_gu_def add_gu_single.simps(1) all_guards_exists_uargs assms(1) assms(2) assms(3) plus_extract(3))
qed
fun add_pwrite_option where
"add_pwrite_option None = None"
| "add_pwrite_option (Some x) = Some (pwrite, x)"
definition denormalize :: "normal_heap ⇒ ('i, 'a) heap" where
"denormalize H = ((λl. add_pwrite_option (H l)), None, (λ_. None))"
lemma denormalize_properties:
shows "no_guard (denormalize H)"
and "full_ownership (get_fh (denormalize H))"
and "normalize (get_fh (denormalize H)) = H"
and "full_ownership (get_fh h) ∧ no_guard h ⟹ denormalize (normalize (get_fh h)) = h"
and "full_ownership (get_fh h) ⟹ denormalize (normalize (get_fh h)) = remove_guards h"
apply (simp add: denormalize_def no_guardI)
using full_ownershipI[of "get_fh (denormalize H)"] add_pwrite_option.elims denormalize_def fst_conv get_fh.elims option.distinct(1) option.sel apply metis
proof -
show "normalize (get_fh (denormalize H)) = H"
proof (rule ext)
fix l show "normalize (get_fh (denormalize H)) l = H l"
by (metis FractionalHeap.normalize_eq(1) FractionalHeap.normalize_eq(2) add_pwrite_option.elims denormalize_def fst_conv get_fh.elims)
qed
show "full_ownership (get_fh h) ∧ no_guard h ⟹ denormalize (FractionalHeap.normalize (get_fh h)) = h"
proof -
assume asm0: "full_ownership (get_fh h) ∧ no_guard h"
show "denormalize (FractionalHeap.normalize (get_fh h)) = h"
proof (rule heap_ext)
show "get_fh (denormalize (FractionalHeap.normalize (get_fh h))) = get_fh h"
proof (rule ext)
fix x show "get_fh (denormalize (FractionalHeap.normalize (get_fh h))) x = get_fh h x"
proof (cases "get_fh h x")
case None
then show ?thesis
by (metis FractionalHeap.normalize_eq(1) add_pwrite_option.simps(1) denormalize_def fst_conv get_fh.elims)
next
case (Some p)
then have "fst p = pwrite"
by (meson asm0 full_ownership_def)
then show ?thesis
by (metis FractionalHeap.normalize_eq(2) Some add_pwrite_option.simps(2) denormalize_def fst_conv get_fh.elims prod.collapse)
qed
qed
show "get_gs (denormalize (FractionalHeap.normalize (get_fh h))) = get_gs h"
by (metis asm0 denormalize_def fst_conv get_gs.elims no_guard_def snd_eqD)
show "get_gu (denormalize (FractionalHeap.normalize (get_fh h))) = get_gu h"
by (metis ‹get_fh (denormalize (FractionalHeap.normalize (get_fh h))) = get_fh h› ‹get_gs (denormalize (FractionalHeap.normalize (get_fh h))) = get_gs h› asm0 denormalize_def full_no_guard_same_normalize get_gu.simps no_guard_def snd_conv)
qed
qed
assume asm0: "full_ownership (get_fh h)"
show "denormalize (FractionalHeap.normalize (get_fh h)) = remove_guards h"
proof (rule heap_ext)
show "get_fh (denormalize (FractionalHeap.normalize (get_fh h))) = get_fh (remove_guards h)"
proof (rule ext)
fix x show "get_fh (denormalize (FractionalHeap.normalize (get_fh h))) x = get_fh (remove_guards h) x"
proof (cases "get_fh h x")
case None
then show ?thesis
by (metis FractionalHeap.normalize_eq(1) add_pwrite_option.simps(1) denormalize_def fst_eqD get_fh.elims get_fh_remove_guards)
next
case (Some p)
then have "fst p = pwrite"
by (meson asm0 full_ownership_def)
then show ?thesis
by (metis FractionalHeap.normalize_eq(2) Some add_pwrite_option.simps(2) denormalize_def fst_conv get_fh.elims get_fh_remove_guards prod.collapse)
qed
qed
show "get_gs (denormalize (FractionalHeap.normalize (get_fh h))) = get_gs (remove_guards h)"
by (simp add: denormalize_def remove_guards_def)
show "get_gu (denormalize (FractionalHeap.normalize (get_fh h))) = get_gu (remove_guards h)"
by (metis ‹get_fh (denormalize (FractionalHeap.normalize (get_fh h))) = get_fh (remove_guards h)› ‹get_gs (denormalize (FractionalHeap.normalize (get_fh h))) = get_gs (remove_guards h)› asm0 denormalize_def full_no_guard_same_normalize get_fh_remove_guards get_gu.simps no_guard_def no_guard_remove_guards snd_conv)
qed
qed
lemma no_guard_then_sat_star_uguard:
assumes "no_guard h ∧ no_guard h'"
and "(s, h), (s', h') ⊨ Q"
shows "(s, add_uguard_to_no_guard k h (e s)), (s', add_uguard_to_no_guard k h' (e s')) ⊨ Star Q (UniqueGuard k e)"
proof -
obtain "Some (add_uguard_to_no_guard k h (e s)) = Some h ⊕ Some (Map.empty, None, [k ↦ e s])"
"Some (add_uguard_to_no_guard k h' (e s')) = Some h' ⊕ Some (Map.empty, None, [k ↦ e s'])"
by (simp add: add_uguard_as_sum assms(1))
moreover have "(s, (Map.empty, None, [k ↦ e s])), (s', (Map.empty, None, [k ↦ e s'])) ⊨ UniqueGuard k e"
by simp
ultimately show ?thesis using assms(2) by fastforce
qed
lemma no_guard_then_sat_star:
assumes "no_guard h ∧ no_guard h'"
and "(s, h), (s', h') ⊨ Q"
shows "(s, add_sguard_to_no_guard h π (ms s)), (s', add_sguard_to_no_guard h' π (ms s')) ⊨ Star Q (SharedGuard π ms)"
proof -
obtain "Some (add_sguard_to_no_guard h π (ms s)) = Some h ⊕ Some (Map.empty, Some (π, ms s), (λ_. None))"
"Some (add_sguard_to_no_guard h' π (ms s')) = Some h' ⊕ Some (Map.empty, Some (π, ms s'), (λ_. None))"
using add_sguard_as_sum assms(1) by blast
moreover have "(s, (Map.empty, Some (π, ms s), (λ_. None))), (s', (Map.empty, Some (π, ms s'), (λ_. None))) ⊨ SharedGuard π ms"
by simp
ultimately show ?thesis using assms(2) by fastforce
qed
end