diff --git a/thys/Combinable_Wands/CombinableWands.thy b/thys/Combinable_Wands/CombinableWands.thy --- a/thys/Combinable_Wands/CombinableWands.thy +++ b/thys/Combinable_Wands/CombinableWands.thy @@ -1,884 +1,885 @@ section \Combinable Magic Wands\ text \Note that, in this theory, assertions are represented as semantic assertions, i.e., as the set of states in which they hold.\ theory CombinableWands imports PartialHeapSA begin subsection \Definitions\ type_synonym sem_assertion = "state set" fun multiply :: "prat \ state \ state" where "multiply p \ = Abs_state (multiply_mask p (get_m \), get_h \)" text \Because we work in an intuitionistic setting, a fraction of an assertion is defined using the upper-closure operator.\ fun multiply_sem_assertion :: "prat \ sem_assertion \ sem_assertion" where "multiply_sem_assertion p P = PartialSA.upper_closure (multiply p ` P)" definition combinable :: "sem_assertion \ bool" where "combinable P \ (\\ \. ppos \ \ ppos \ \ pgte pwrite (padd \ \) \ (multiply_sem_assertion \ P) \ (multiply_sem_assertion \ P) \ multiply_sem_assertion (padd \ \) P)" definition scaled where "scaled \ = { multiply p \ |p. ppos p \ pgte pwrite p }" definition comp_min_mask :: "mask \ (mask \ mask)" where "comp_min_mask b a hl = pmin (a hl) (comp_one (b hl))" definition scalable where "scalable w a \ (\\ \ scaled w. \ a |#| \)" definition R where "R a w = (if scalable w a then w else Abs_state (comp_min_mask (get_m a) (get_m w), get_h w))" definition cwand where "cwand A B = { w |w. \a x. a \ A \ Some x = R a w \ a \ x \ B }" definition wand :: "sem_assertion \ sem_assertion \ sem_assertion" where "wand A B = { w |w. \a x. a \ A \ Some x = w \ a \ x \ B }" definition intuitionistic where "intuitionistic A \ (\a b. a \ b \ b \ A \ a \ A)" definition binary_mask :: "mask \ mask" where "binary_mask \ l = (if \ l = pwrite then pwrite else pnone)" definition binary :: "sem_assertion \ bool" where "binary A \ (\\ \ A. Abs_state (binary_mask (get_m \), get_h \) \ A)" subsection Lemmas lemma wand_equiv_def: "wand A B = { \ |\. A \ {\} \ B }" proof show "wand A B \ {\ |\. A \ {\} \ B}" proof fix w assume "w \ wand A B" have "A \ {w} \ B" proof fix x assume "x \ A \ {w}" then show "x \ B" using PartialSA.add_set_elem \w \ wand A B\ commutative wand_def by auto qed then show "w \ {\ |\. A \ {\} \ B}" by simp qed show "{\ |\. A \ {\} \ B} \ wand A B" proof fix w assume "w \ {\ |\. A \ {\} \ B}" have "\a x. a \ A \ Some x = w \ a \ x \ B" proof - fix a x assume "a \ A \ Some x = w \ a" then have "x \ A \ {w}" using PartialSA.add_set_elem PartialSA.commutative by auto then show "x \ B" using \w \ {\ |\. A \ {\} \ B}\ by blast qed then show "w \ wand A B" using wand_def by force qed qed lemma w_in_scaled: "w \ scaled w" proof - have "multiply pwrite w = w" by (simp add: Rep_state_inverse mult_write_mask) then show ?thesis by (metis (mono_tags, lifting) half_between_0_1 half_plus_half mem_Collect_eq not_pgte_charact pgt_implies_pgte ppos_add scaled_def) qed lemma non_scalable_instantiate: assumes "\ scalable w a" shows "\p. ppos p \ pgte pwrite p \ a |#| multiply p w" using assms scalable_def scaled_def by auto lemma compatible_same_mask: assumes "valid_mask (add_masks a w)" shows "w = comp_min_mask a w" proof (rule ext) fix x have "pgte pwrite (padd (a x) (w x))" by (metis add_masks.simps assms valid_mask.elims(1)) moreover have "padd (a x) (comp_one (a x)) = pwrite" by (meson assms padd_comp_one upper_valid_aux valid_mask.elims(1)) then have "pgte (comp_one (a x)) (w x)" by (metis add_le_cancel_left calculation padd.rep_eq pgte.rep_eq) then show "w x = comp_min_mask a w x" by (metis comp_min_mask_def pmin_comm pmin_is) qed lemma R_smaller: "w \ R a w" proof (cases "scalable w a") case True then show ?thesis by (simp add: PartialSA.succ_refl R_def) next case False then have "R a w = Abs_state (comp_min_mask (get_m a) (get_m w), get_h w)" by (meson R_def) moreover have "greater_mask (get_m w) (comp_min_mask (get_m a) (get_m w))" proof (rule greater_maskI) fix hl show "pgte (get_m w hl) (comp_min_mask (get_m a) (get_m w) hl)" by (simp add: comp_min_mask_def pmin_greater) qed ultimately show ?thesis by (metis Abs_state_cases larger_heap_refl Rep_state_cases Rep_state_inverse fst_conv get_h_m greaterI greater_mask_def mem_Collect_eq snd_conv valid_state_decompose) qed lemma R_compatible_same: assumes "a |#| w" shows "R a w = w" proof - have "\ scalable w a" using assms scalable_def w_in_scaled by blast then have "R a w = Abs_state (comp_min_mask (get_m a) (get_m w), get_h w)" using R_def by auto then show ?thesis by (metis PartialSA.defined_def Rep_state_inverse assms compatible_same_mask get_h.simps get_m.simps plus_ab_defined prod.collapse) qed lemma in_cwand: assumes "\a x. a \ A \ Some x = R a w \ a \ x \ B" shows "w \ cwand A B" using assms cwand_def by force lemma wandI: assumes "\a x. a \ A \ Some x = a \ w \ x \ B" shows "w \ wand A B" proof - have "A \ {w} \ B" proof (rule subsetI) fix x assume "x \ A \ {w}" then obtain a where "Some x = a \ w" "a \ A" using PartialSA.add_set_elem by auto then show "x \ B" using assms by blast qed then show ?thesis using wand_equiv_def by force qed lemma non_scalable_R_charact: assumes "\ scalable w a" shows "get_m (R a w) = comp_min_mask (get_m a) (get_m w) \ get_h (R a w) = get_h w" proof - have "R a w = Abs_state (comp_min_mask (get_m a) (get_m w), get_h w)" using R_def assms by auto moreover have "valid_state (comp_min_mask (get_m a) (get_m w), get_h w)" proof (rule valid_stateI) show "valid_mask (comp_min_mask (get_m a) (get_m w))" proof (rule valid_maskI) show "\f. comp_min_mask (get_m a) (get_m w) (null, f) = pnone" by (metis (no_types, opaque_lifting) PartialSA.unit_neutral add_masks.simps comp_min_mask_def option.distinct(1) p_greater_exists padd_zero plus_ab_defined pmin_greater valid_mask.simps) fix hl show "pgte pwrite (comp_min_mask (get_m a) (get_m w) hl)" by (metis PartialSA.unit_neutral comp_min_mask_def greater_mask_def greater_mask_equiv_def option.distinct(1) plus_ab_defined pmin_greater upper_valid_aux valid_mask.simps) qed fix hl assume "ppos (comp_min_mask (get_m a) (get_m w) hl)" show "get_h w hl \ None" by (metis Rep_state \ppos (comp_min_mask (get_m a) (get_m w) hl)\ comp_min_mask_def get_h.simps get_pre(2) mem_Collect_eq p_greater_exists pmin_greater ppos_add prod.collapse valid_heap_def valid_state.simps) qed ultimately show ?thesis by (metis Rep_state_cases Rep_state_inverse fst_conv get_h.simps get_m.simps mem_Collect_eq snd_conv) qed lemma valid_bin: "valid_state (binary_mask (get_m a), get_h a)" proof (rule valid_stateI) show "valid_mask (binary_mask (get_m a))" by (metis PartialSA.unit_neutral binary_mask_def minus_empty option.discI plus_ab_defined unit_charact(2) valid_mask.elims(2) valid_mask.elims(3)) show "\hl. ppos (binary_mask (get_m a) hl) \ get_h a hl \ None" by (metis Rep_prat Rep_state binary_mask_def get_h.simps get_pre(2) leD mem_Collect_eq pnone.rep_eq ppos.rep_eq prod.collapse valid_heap_def valid_state.simps) qed lemma in_multiply_sem: assumes "x \ multiply_sem_assertion p A" shows "\a \ A. x \ multiply p a" using PartialSA.sep_algebra_axioms assms greater_def sep_algebra.upper_closure_def by fastforce lemma get_h_multiply: assumes "pgte pwrite p" shows "get_h (multiply p x) = get_h x" using Abs_state_inverse assms multiply_valid by auto lemma in_multiply_refl: assumes "x \ A" shows "multiply p x \ multiply_sem_assertion p A" using PartialSA.succ_refl PartialSA.upper_closure_def assms by fastforce lemma get_m_smaller: assumes "pgte pwrite p" shows "get_m (multiply p a) hl = pmult p (get_m a hl)" using Abs_state_inverse assms multiply_mask_def multiply_valid by auto lemma get_m_smaller_mask: assumes "pgte pwrite p" shows "get_m (multiply p a) = multiply_mask p (get_m a)" using Abs_state_inverse assms multiply_mask_def multiply_valid by auto lemma multiply_order: assumes "pgte pwrite p" and "a \ b" shows "multiply p a \ multiply p b" proof (rule greaterI) show "larger_heap (get_h (multiply p a)) (get_h (multiply p b))" using assms(1) assms(2) get_h_multiply larger_implies_larger_heap by presburger show "greater_mask (get_m (multiply p a)) (get_m (multiply p b))" by (metis assms(1) assms(2) get_m_smaller_mask greater_maskI larger_implies_greater_mask_hl mult_greater) qed lemma multiply_twice: assumes "pgte pwrite a \ pgte pwrite b" shows "multiply a (multiply b x) = multiply (pmult a b) x" proof - have "get_h (multiply (pmult a b) x) = get_h x" by (metis assms get_h_multiply p_greater_exists padd_asso pmult_order pmult_special(1)) moreover have "get_h (multiply a (multiply b x)) = get_h x" using assms get_h_multiply by presburger moreover have "get_m (multiply a (multiply b x)) = get_m (multiply (pmult a b) x)" proof (rule ext) fix l have "pgte pwrite (pmult a b)" using multiply_smaller_pwrite assms by simp then have "get_m (multiply (pmult a b) x) l = pmult (pmult a b) (get_m x l)" using get_m_smaller by blast then show "get_m (multiply a (multiply b x)) l = get_m (multiply (pmult a b) x) l" by (metis Rep_prat_inverse assms get_m_smaller mult.assoc pmult.rep_eq) qed ultimately show ?thesis using state_ext by presburger qed lemma valid_mask_add_comp_min: assumes "valid_mask a" and "valid_mask b" shows "valid_mask (add_masks (comp_min_mask b a) b)" proof (rule valid_maskI) show "\f. add_masks (comp_min_mask b a) b (null, f) = pnone" proof - fix f have "comp_min_mask b a (null, f) = pnone" by (metis assms(1) comp_min_mask_def p_greater_exists padd_zero pmin_greater valid_mask.simps) then show "add_masks (comp_min_mask b a) b (null, f) = pnone" by (metis add_masks.simps assms(2) padd_zero valid_mask.simps) qed fix hl show "pgte pwrite (add_masks (comp_min_mask b a) b hl)" proof (cases "pgte (a hl) (comp_one (b hl))") case True then have "add_masks (comp_min_mask b a) b hl = padd (comp_one (b hl)) (b hl)" by (simp add: comp_min_mask_def pmin_is) then have "add_masks (comp_min_mask b a) b hl = pwrite" by (metis assms(2) padd_comm padd_comp_one valid_mask.simps) then show ?thesis by (simp add: pgte.rep_eq) next case False then have "comp_min_mask b a hl = a hl" by (metis comp_min_mask_def not_pgte_charact pgt_implies_pgte pmin_comm pmin_is) then have "add_masks (comp_min_mask b a) b hl = padd (a hl) (b hl)" by auto moreover have "pgte (padd (comp_one (b hl)) (b hl)) (padd (a hl) (b hl))" using False padd.rep_eq pgte.rep_eq by force moreover have "padd (comp_one (b hl)) (b hl) = pwrite" by (metis assms(2) padd_comm padd_comp_one valid_mask.simps) ultimately show ?thesis by simp qed qed subsection \The combinable wand is stronger than the original wand\ lemma cwand_stronger: "cwand A B \ wand A B" proof fix w assume asm0: "w \ cwand A B" then have r: "\a x. a \ A \ Some x = R a w \ a \ x \ B" using cwand_def by blast show "w \ wand A B" proof (rule wandI) fix a x assume asm1: "a \ A \ Some x = a \ w" then have "R a w = w" by (metis PartialSA.defined_def R_compatible_same option.distinct(1)) then show "x \ B" by (metis PartialSA.commutative asm1 r) qed qed subsection \The combinable wand is the same as the original wand when the left-hand side is binary\ lemma binary_same: assumes "binary A" and "intuitionistic B" shows "wand A B \ cwand A B" proof (rule subsetI) fix w assume "w \ wand A B" then have asm0: "A \ {w} \ B" by (simp add: wand_equiv_def) show "w \ cwand A B" proof (rule in_cwand) - fix a x assume "a \ A \ Some x = R a w \ a" + fix a x assume asm1: "a \ A \ Some x = R a w \ a" show "x \ B" proof (cases "scalable w a") case True then show ?thesis - by (metis PartialSA.commutative PartialSA.defined_def R_def \a \ A \ Some x = R a w \ a\ option.distinct(1) scalable_def w_in_scaled) + by (metis PartialSA.commutative PartialSA.defined_def R_def asm1 option.distinct(1) scalable_def w_in_scaled) next case False - then have "get_m (R a w) = comp_min_mask (get_m a) (get_m w) \ get_h (R a w) = get_h w" + then have r0: "get_m (R a w) = comp_min_mask (get_m a) (get_m w) \ get_h (R a w) = get_h w" using non_scalable_R_charact by blast moreover have "Abs_state (binary_mask (get_m a), get_h a) \ A" - using \a \ A \ Some x = R a w \ a\ assms(1) binary_def by blast + using asm1 assms(1) binary_def by blast moreover have "greater_mask (add_masks (comp_min_mask (get_m a) (get_m w)) (get_m a)) (add_masks (binary_mask (get_m a)) (get_m w))" proof (rule greater_maskI) fix hl show "pgte (add_masks (comp_min_mask (get_m a) (get_m w)) (get_m a) hl) (add_masks (binary_mask (get_m a)) (get_m w) hl)" proof (cases "get_m a hl = pwrite") case True obtain \ where "\ \ scaled w" "a |#| \" using False scalable_def[of w a] by blast then obtain p where "ppos p" "pgte pwrite p" "multiply p w |#| a" using PartialSA.commutative PartialSA.defined_def mem_Collect_eq scaled_def by auto have "get_m w hl = pnone" proof (rule ccontr) assume "get_m w hl \ pnone" then have "ppos (get_m w hl)" by (metis less_add_same_cancel1 not_pgte_charact p_greater_exists padd.rep_eq padd_zero pgt.rep_eq ppos.rep_eq) moreover have "get_m (multiply p \) = multiply_mask p (get_m \)" using multiply_valid[of p \] multiply.simps[of p \] by (metis Rep_state_cases Rep_state_inverse \pgte pwrite p\ fst_conv get_pre(2) mem_Collect_eq) then have "ppos (get_m (multiply p w) hl)" using pmult_ppos by (metis Rep_state_cases Rep_state_inverse \pgte pwrite p\ \ppos p\ calculation fst_conv get_pre(2) mem_Collect_eq multiply.simps multiply_mask_def multiply_valid) then have "pgt (padd (get_m (multiply p w) hl) (get_m a hl)) pwrite" by (metis True add_le_same_cancel2 leD not_pgte_charact padd.rep_eq pgte.rep_eq ppos.rep_eq) then have "\ valid_mask (add_masks (get_m (multiply p w)) (get_m a))" by (metis add_masks.elims not_pgte_charact valid_mask.elims(1)) then show False using PartialSA.defined_def \multiply p w |#| a\ plus_ab_defined by blast qed then show ?thesis by (metis Rep_prat_inverse add.right_neutral add_masks.simps binary_mask_def p_greater_exists padd.rep_eq padd_comm pnone.rep_eq) next case False then have "add_masks (binary_mask (get_m a)) (get_m w) hl = get_m w hl" by (metis Rep_prat_inject add.right_neutral add_masks.simps binary_mask_def padd.rep_eq padd_comm pnone.rep_eq) then show ?thesis proof (cases "pgte (get_m w hl) (comp_one (get_m a hl))") case True then have "comp_min_mask (get_m a) (get_m w) hl = comp_one (get_m a hl)" using comp_min_mask_def pmin_is by presburger then have "add_masks (comp_min_mask (get_m a) (get_m w)) (get_m a) hl = pwrite" by (metis PartialSA.unit_neutral add_masks.simps add_masks_comm minus_empty option.distinct(1) padd_comp_one plus_ab_defined unit_charact(2) valid_mask.simps) then show ?thesis by (metis PartialSA.unit_neutral \add_masks (binary_mask (get_m a)) (get_m w) hl = get_m w hl\ minus_empty option.distinct(1) plus_ab_defined unit_charact(2) valid_mask.simps) next case False then have "comp_min_mask (get_m a) (get_m w) hl = get_m w hl" by (metis comp_min_mask_def not_pgte_charact pgt_implies_pgte pmin_comm pmin_is) then show ?thesis using \add_masks (binary_mask (get_m a)) (get_m w) hl = get_m w hl\ p_greater_exists by auto qed qed qed then have "valid_mask (add_masks (binary_mask (get_m a)) (get_m w))" - by (metis \a \ A \ Some x = R a w \ a\ calculation(1) greater_mask_def option.distinct(1) plus_ab_defined upper_valid_aux) + by (metis asm1 calculation(1) greater_mask_def option.distinct(1) plus_ab_defined upper_valid_aux) moreover have "compatible_heaps (get_h a) (get_h w)" - by (metis PartialSA.commutative \a \ A \ Some x = R a w \ a\ \get_m (R a w) = comp_min_mask (get_m a) (get_m w) \ get_h (R a w) = get_h w\ option.simps(3) plus_ab_defined) + by (metis PartialSA.commutative asm1 r0 option.simps(3) plus_ab_defined) then obtain xx where "Some xx = Abs_state (binary_mask (get_m a), get_h a) \ w" using Abs_state_inverse calculation compatible_def fst_conv plus_def valid_bin by auto then have "xx \ B" using asm0 by (meson PartialSA.add_set_elem \Abs_state (binary_mask (get_m a), get_h a) \ A\ singletonI subset_iff) moreover have "x \ xx" proof (rule greaterI) show "greater_mask (get_m x) (get_m xx)" - using Abs_state_inverse \Some xx = Abs_state (binary_mask (get_m a), get_h a) \ w\ \a \ A \ Some x = R a w \ a\ \greater_mask (add_masks (comp_min_mask (get_m a) (get_m w)) (get_m a)) (add_masks (binary_mask (get_m a)) (get_m w))\ calculation(1) plus_charact(1) valid_bin by auto + using Abs_state_inverse \Some xx = Abs_state (binary_mask (get_m a), get_h a) \ w\ asm1 \greater_mask (add_masks (comp_min_mask (get_m a) (get_m w)) (get_m a)) (add_masks (binary_mask (get_m a)) (get_m w))\ calculation(1) plus_charact(1) valid_bin by auto show "larger_heap (get_h x) (get_h xx)" proof (rule larger_heapI) fix hl xa assume "get_h xx hl = Some xa" then show "get_h x hl = Some xa" - by (metis PartialSA.commutative Rep_state_cases Rep_state_inverse \Some xx = Abs_state (binary_mask (get_m a), get_h a) \ w\ \a \ A \ Some x = R a w \ a\ calculation(1) get_h.simps mem_Collect_eq plus_charact(2) snd_conv valid_bin) + by (metis PartialSA.commutative Rep_state_cases Rep_state_inverse \Some xx = Abs_state (binary_mask (get_m a), get_h a) \ w\ asm1 calculation(1) get_h.simps mem_Collect_eq plus_charact(2) snd_conv valid_bin) qed qed ultimately show ?thesis using assms(2) intuitionistic_def by blast qed qed qed subsection \The combinable wand is combinable\ lemma combinableI: assumes "\a b. ppos a \ ppos b \ padd a b = pwrite \ (multiply_sem_assertion a (cwand A B)) \ (multiply_sem_assertion b (cwand A B)) \ cwand A B" shows "combinable (cwand A B)" proof - have "\a b. ppos a \ ppos b \ pgte pwrite (padd a b) \ (multiply_sem_assertion a (cwand A B)) \ (multiply_sem_assertion b (cwand A B)) \ multiply_sem_assertion (padd a b) (cwand A B)" proof - fix a b assume asm0: "ppos a \ ppos b \ pgte pwrite (padd a b)" then have "pgte pwrite a \ pgte pwrite b" using padd.rep_eq pgte.rep_eq ppos.rep_eq by auto show "(multiply_sem_assertion a (cwand A B)) \ (multiply_sem_assertion b (cwand A B)) \ multiply_sem_assertion (padd a b) (cwand A B)" proof fix x assume "x \ multiply_sem_assertion a (cwand A B) \ multiply_sem_assertion b (cwand A B)" then obtain xa xb where "Some x = xa \ xb" "xa \ multiply_sem_assertion a (cwand A B)" "xb \ multiply_sem_assertion b (cwand A B)" by (meson PartialSA.add_set_elem) then obtain wa wb where "wa \ cwand A B" "wb \ cwand A B" "xa \ multiply a wa" "xb \ multiply b wb" by (meson in_multiply_sem) let ?a = "pdiv a (padd a b)" let ?b = "pdiv b (padd a b)" - have "pgte pwrite ?a \ pgte pwrite ?b" + have r0: "pgte pwrite ?a \ pgte pwrite ?b" using asm0 p_greater_exists padd_comm pdiv_smaller ppos_add by blast have "multiply ?a wa |#| multiply ?b wb" proof (rule compatibleI) show "compatible_heaps (get_h (multiply (pdiv a (padd a b)) wa)) (get_h (multiply (pdiv b (padd a b)) wb))" proof - have "compatible_heaps (get_h (multiply a wa)) (get_h (multiply b wb))" by (metis PartialSA.asso2 PartialSA.asso3 PartialSA.greater_equiv PartialSA.minus_some \Some x = xa \ xb\ \xa \ multiply a wa\ \xb \ multiply b wb\ option.simps(3) plus_ab_defined) moreover have "get_h (multiply (pdiv a (padd a b)) wa) = get_h (multiply a wa) \ get_h (multiply (pdiv b (padd a b)) wb) = get_h (multiply b wb)" proof - have "pgte pwrite a \ pgte pwrite b" by (metis asm0 p_greater_exists padd_asso padd_comm) moreover have "pgte pwrite ?a \ pgte pwrite ?b" using asm0 p_greater_exists padd_comm pdiv_smaller ppos_add by blast ultimately show ?thesis using get_h_multiply by presburger qed then show ?thesis using calculation by presburger qed show "valid_mask (add_masks (get_m (multiply (pdiv a (padd a b)) wa)) (get_m (multiply (pdiv b (padd a b)) wb)))" proof (rule valid_maskI) show "\f. add_masks (get_m (multiply (pdiv a (padd a b)) wa)) (get_m (multiply (pdiv b (padd a b)) wb)) (null, f) = pnone" by (metis PartialSA.unit_neutral add_masks_equiv_valid_null option.distinct(1) plus_ab_defined valid_mask.simps valid_null_def) fix hl have "add_masks (get_m (multiply (pdiv a (padd a b)) wa)) (get_m (multiply (pdiv b (padd a b)) wb)) hl = padd (pmult ?a (get_m wa hl)) (pmult ?b (get_m wb hl))" proof - have "get_m (multiply ?a wa) hl = pmult ?a (get_m wa hl)" - using Abs_state_inverse \pgte pwrite (pdiv a (padd a b)) \ pgte pwrite (pdiv b (padd a b))\ multiply_mask_def multiply_valid by auto + using Abs_state_inverse r0 multiply_mask_def multiply_valid by auto moreover have "get_m (multiply ?b wb) hl = pmult ?b (get_m wb hl)" - using Abs_state_inverse \pgte pwrite (pdiv a (padd a b)) \ pgte pwrite (pdiv b (padd a b))\ multiply_mask_def multiply_valid by auto + using Abs_state_inverse r0 multiply_mask_def multiply_valid by auto ultimately show ?thesis by simp qed moreover have "pgte pwrite (padd (pmult ?a (get_m wa hl)) (pmult ?b (get_m wb hl)))" proof (rule padd_one_ineq_sum) show "pgte pwrite (get_m wa hl)" by (metis PartialSA.unit_neutral option.discI plus_ab_defined upper_valid_aux valid_mask.simps) show "pgte pwrite (get_m wb hl)" by (metis PartialSA.unit_neutral option.discI plus_ab_defined upper_valid_aux valid_mask.simps) show "padd (pdiv a (padd a b)) (pdiv b (padd a b)) = pwrite" using asm0 sum_coeff by blast qed ultimately show "pgte pwrite (add_masks (get_m (multiply (pdiv a (padd a b)) wa)) (get_m (multiply (pdiv b (padd a b)) wb)) hl)" by presburger qed qed - then obtain xx where "Some xx = multiply ?a wa \ multiply ?b wb" + then obtain xx where xx_def: "Some xx = multiply ?a wa \ multiply ?b wb" using PartialSA.defined_def by auto - moreover have "(multiply_sem_assertion ?a (cwand A B)) \ (multiply_sem_assertion ?b (cwand A B)) \ cwand A B" + moreover have inclusion: "(multiply_sem_assertion ?a (cwand A B)) \ (multiply_sem_assertion ?b (cwand A B)) \ cwand A B" proof (rule assms) show "ppos (pdiv a (padd a b)) \ ppos (pdiv b (padd a b)) \ padd (pdiv a (padd a b)) (pdiv b (padd a b)) = pwrite" using asm0 padd.rep_eq pdiv.rep_eq ppos.rep_eq sum_coeff by auto qed ultimately have "xx \ cwand A B" proof - have "multiply ?a wa \ multiply_sem_assertion ?a (cwand A B)" using \wa \ cwand A B\ in_multiply_refl by presburger moreover have "multiply ?b wb \ multiply_sem_assertion ?b (cwand A B)" by (meson \wb \ cwand A B\ in_multiply_refl) ultimately show ?thesis - using PartialSA.add_set_def \Some xx = multiply (pdiv a (padd a b)) wa \ multiply (pdiv b (padd a b)) wb\ \multiply_sem_assertion (pdiv a (padd a b)) (cwand A B) \ multiply_sem_assertion (pdiv b (padd a b)) (cwand A B) \ cwand A B\ by fastforce + using PartialSA.add_set_def xx_def inclusion by fastforce qed moreover have "x \ multiply (padd a b) xx" proof (rule greaterI) have "valid_state (multiply_mask (padd a b) (get_m xx), get_h xx)" using asm0 multiply_valid by blast show "larger_heap (get_h x) (get_h (multiply (padd a b) xx))" proof - have "get_h (multiply (padd a b) xx) = get_h xx" using asm0 get_h_multiply by blast moreover have "get_h xx = get_h wa ++ get_h wb" - by (metis \Some xx = multiply (pdiv a (padd a b)) wa \ multiply (pdiv b (padd a b)) wb\ asm0 get_h_multiply p_greater_exists padd_comm plus_charact(2) sum_coeff) + by (metis xx_def asm0 get_h_multiply p_greater_exists padd_comm plus_charact(2) sum_coeff) moreover have "get_h x = get_h xa ++ get_h xb" using \Some x = xa \ xb\ plus_charact(2) by presburger moreover have "get_h wa = get_h (multiply a wa) \ get_h wb = get_h (multiply b wb)" by (metis asm0 get_h_multiply order_trans p_greater_exists padd_comm pgte.rep_eq) moreover have "larger_heap (get_h xa) (get_h wa) \ larger_heap (get_h xb) (get_h wb)" using \xa \ multiply a wa\ \xb \ multiply b wb\ calculation(4) larger_implies_larger_heap by presburger ultimately show ?thesis by (metis \Some x = xa \ xb\ larger_heaps_sum_ineq option.simps(3) plus_ab_defined) qed show "greater_mask (get_m x) (get_m (multiply (padd a b) xx))" proof (rule greater_maskI) fix hl have "pgte (get_m x hl) (padd (get_m xa hl) (get_m xb hl))" using \Some x = xa \ xb\ pgte.rep_eq plus_charact(1) by auto moreover have "pgte (get_m xa hl) (get_m (multiply a wa) hl) \ pgte (get_m xb hl) (get_m (multiply b wb) hl)" using \xa \ multiply a wa\ \xb \ multiply b wb\ larger_implies_greater_mask_hl by blast moreover have "get_m (multiply (padd a b) xx) hl = pmult (padd a b) (get_m xx hl)" by (metis Rep_state_cases Rep_state_inverse \valid_state (multiply_mask (padd a b) (get_m xx), get_h xx)\ fst_conv get_pre(2) mem_Collect_eq multiply.simps multiply_mask_def) moreover have "... = padd (pmult (pmult (padd a b) ?a) (get_m wa hl)) (pmult (pmult (padd a b) ?b) (get_m wb hl))" proof - have "get_m (multiply ?a wa) hl = pmult ?a (get_m wa hl)" by (metis Abs_state_inverse asm0 fst_conv get_pre(2) mem_Collect_eq multiply.simps multiply_mask_def multiply_valid p_greater_exists sum_coeff) moreover have "get_m (multiply ?b wb) hl = pmult ?b (get_m wb hl)" by (metis Abs_state_inverse asm0 fst_conv get_pre(2) mem_Collect_eq multiply.simps multiply_mask_def multiply_valid p_greater_exists padd_comm pdiv_smaller ppos_add) ultimately have "get_m xx hl = padd (pmult ?a (get_m wa hl)) (pmult ?b (get_m wb hl))" - using \Some xx = multiply (pdiv a (padd a b)) wa \ multiply (pdiv b (padd a b)) wb\ plus_charact(1) by fastforce + using xx_def plus_charact(1) by fastforce then show ?thesis by (simp add: pmult_padd) qed moreover have "... = padd (pmult a (get_m wa hl)) (pmult b (get_m wb hl))" using asm0 pmult_pdiv_cancel ppos_add by presburger moreover have "get_m (multiply a wa) hl = pmult a (get_m wa hl) \ get_m (multiply b wb) hl = pmult b (get_m wb hl)" proof - have "valid_mask (multiply_mask a (get_m wa))" using asm0 mult_add_states multiply_valid upper_valid_aux valid_state.simps by blast moreover have "valid_mask (multiply_mask b (get_m wb))" using asm0 mult_add_states multiply_valid upper_valid valid_state.simps by blast ultimately show ?thesis by (metis (no_types, lifting) Abs_state_inverse asm0 fst_conv get_pre(2) mem_Collect_eq multiply.simps multiply_mask_def multiply_valid order_trans p_greater_exists padd_comm pgte.rep_eq) qed ultimately show "pgte (get_m x hl) (get_m (multiply (padd a b) xx) hl)" by (simp add: padd.rep_eq pgte.rep_eq) qed qed ultimately show "x \ multiply_sem_assertion (padd a b) (cwand A B)" by (metis PartialSA.up_closed_def PartialSA.upper_closure_up_closed in_multiply_refl multiply_sem_assertion.simps) qed qed then show ?thesis using combinable_def by presburger qed lemma combinable_cwand: assumes "combinable B" and "intuitionistic B" shows "combinable (cwand A B)" proof (rule combinableI) fix \ \ assume asm0: "ppos \ \ ppos \ \ padd \ \ = pwrite" then have "pgte pwrite \ \ pgte pwrite \" by (metis p_greater_exists padd_comm) show "multiply_sem_assertion \ (cwand A B) \ multiply_sem_assertion \ (cwand A B) \ cwand A B" proof - fix w assume "w \ multiply_sem_assertion \ (cwand A B) \ multiply_sem_assertion \ (cwand A B)" + fix w assume asm: "w \ multiply_sem_assertion \ (cwand A B) \ multiply_sem_assertion \ (cwand A B)" then obtain xa xb where "Some w = xa \ xb" "xa \ multiply_sem_assertion \ (cwand A B)" "xb \ multiply_sem_assertion \ (cwand A B)" by (meson PartialSA.add_set_elem) then obtain wa wb where "wa \ cwand A B" "wb \ cwand A B" "xa \ multiply \ wa" "xb \ multiply \ wb" by (meson in_multiply_sem) then obtain r: "\a x. a \ A \ Some x = R a wa \ a \ x \ B" "\a x. a \ A \ Some x = R a wb \ a \ x \ B" using cwand_def by blast show "w \ cwand A B" proof (rule in_cwand) fix a x assume asm1: "a \ A \ Some x = R a w \ a" have "\ scalable w a" proof (rule ccontr) assume "\ \ scalable w a" then have "R a w = w \ \ a |#| R a w" by (simp add: R_def scalable_def w_in_scaled) then show False using PartialSA.commutative PartialSA.defined_def asm1 by auto qed - then have "get_h (R a w) = get_h w \ get_m (R a w) = comp_min_mask (get_m a) (get_m w)" + then have r3: "get_h (R a w) = get_h w \ get_m (R a w) = comp_min_mask (get_m a) (get_m w)" using non_scalable_R_charact by blast moreover obtain p where "a |#| multiply p w" "ppos p \ pgte pwrite p" using \\ scalable w a\ non_scalable_instantiate by blast moreover have "\ scalable wa a" proof - have "a |#| multiply (pmult \ p) wa" proof - have "w \ xa" using \Some w = xa \ xb\ using PartialSA.greater_def by blast then have "multiply p w \ multiply p xa" using calculation(3) multiply_order by blast then have "multiply p w \ multiply (pmult \ p) wa" proof - have "multiply p w \ multiply p (multiply \ wa)" using PartialSA.succ_trans \w \ xa\ \xa \ multiply \ wa\ calculation(3) multiply_order by blast then show ?thesis using \pgte pwrite \ \ pgte pwrite \\ calculation(3) multiply_twice pmult_comm by auto qed then show ?thesis using PartialSA.asso3 PartialSA.defined_def PartialSA.minus_some calculation(2) by fastforce qed moreover have "ppos (pmult \ p) \ pgte pwrite (pmult \ p)" by (metis Rep_prat_inverse \ppos p \ pgte pwrite p\ add.right_neutral asm0 dual_order.strict_iff_order padd.rep_eq pgte.rep_eq pmult_comm pmult_ppos pmult_special(2) pnone.rep_eq ppos.rep_eq ppos_eq_pnone padd_one_ineq_sum) ultimately show ?thesis using scalable_def scaled_def by auto qed - then have "get_h (R a wa) = get_h wa \ get_m (R a wa) = comp_min_mask (get_m a) (get_m wa)" + then have r1: "get_h (R a wa) = get_h wa \ get_m (R a wa) = comp_min_mask (get_m a) (get_m wa)" using non_scalable_R_charact by blast moreover have "R a wa |#| a" proof (rule compatibleI) have "larger_heap (get_h w) (get_h xa) \ larger_heap (get_h xa) (get_h wa)" by (metis PartialSA.commutative PartialSA.greater_equiv \Some w = xa \ xb\ \pgte pwrite \ \ pgte pwrite \\ \xa \ multiply \ wa\ get_h_multiply larger_implies_larger_heap) then show "compatible_heaps (get_h (R a wa)) (get_h a)" by (metis asm1 calculation(1) calculation(4) larger_heap_comp option.distinct(1) plus_ab_defined) show "valid_mask (add_masks (get_m (R a wa)) (get_m a))" by (metis PartialSA.unit_neutral calculation(4) minus_empty option.distinct(1) plus_ab_defined unit_charact(2) valid_mask_add_comp_min) qed then obtain ba where "Some ba = R a wa \ a" using PartialSA.defined_def by auto moreover have "\ scalable wb a" proof - have "a |#| multiply (pmult \ p) wb" proof - have "w \ xb" using \Some w = xa \ xb\ using PartialSA.greater_equiv by blast then have "multiply p w \ multiply p xb" using calculation(3) multiply_order by blast then have "multiply p w \ multiply (pmult \ p) wb" proof - have "multiply p w \ multiply p (multiply \ wb)" using PartialSA.succ_trans \w \ xb\ \xb \ multiply \ wb\ calculation(3) multiply_order by blast then show ?thesis using \pgte pwrite \ \ pgte pwrite \\ calculation(3) multiply_twice pmult_comm by auto qed then show ?thesis using PartialSA.asso3 PartialSA.defined_def PartialSA.minus_some calculation(2) by fastforce qed moreover have "ppos (pmult \ p) \ pgte pwrite (pmult \ p)" by (simp add: \pgte pwrite \ \ pgte pwrite \\ \ppos p \ pgte pwrite p\ asm0 multiply_smaller_pwrite pmult_ppos) ultimately show ?thesis using scalable_def scaled_def by auto qed - then have "get_h (R a wb) = get_h wb \ get_m (R a wb) = comp_min_mask (get_m a) (get_m wb)" + then have r2: "get_h (R a wb) = get_h wb \ get_m (R a wb) = comp_min_mask (get_m a) (get_m wb)" using non_scalable_R_charact by blast moreover have "R a wb |#| a" proof (rule compatibleI) have "larger_heap (get_h w) (get_h xb) \ larger_heap (get_h xb) (get_h wb)" using \Some w = xa \ xb\ \pgte pwrite \ \ pgte pwrite \\ \xb \ multiply \ wb\ get_h_multiply larger_heap_def larger_implies_larger_heap plus_charact(2) by fastforce then show "compatible_heaps (get_h (R a wb)) (get_h a)" by (metis asm1 calculation(1) calculation(6) larger_heap_comp option.simps(3) plus_ab_defined) show "valid_mask (add_masks (get_m (R a wb)) (get_m a))" by (metis PartialSA.unit_neutral calculation(6) minus_empty option.distinct(1) plus_ab_defined unit_charact(2) valid_mask_add_comp_min) qed then obtain bb where "Some bb = R a wb \ a" using PartialSA.defined_def by auto moreover obtain ya where "Some ya = R a wa \ a" using calculation(5) by auto then have "ya \ B" using asm1 r(1) by blast then have "multiply \ ya \ multiply_sem_assertion \ B" using in_multiply_refl by blast moreover obtain yb where "Some yb = R a wb \ a" using calculation(7) by auto then have "yb \ B" using asm1 r(2) by blast then have "multiply \ yb \ multiply_sem_assertion \ B" using in_multiply_refl by blast moreover have "(multiply \ ya) |#| (multiply \ yb)" proof (rule compatibleI) have "get_h ya = get_h wa ++ get_h a" - using \Some ya = R a wa \ a\ \get_h (R a wa) = get_h wa \ get_m (R a wa) = comp_min_mask (get_m a) (get_m wa)\ plus_charact(2) by presburger + using \Some ya = R a wa \ a\ r1 plus_charact(2) by presburger then have "get_h (multiply \ ya) = get_h wa ++ get_h a" using \pgte pwrite \ \ pgte pwrite \\ get_h_multiply by presburger moreover have "get_h yb = get_h wb ++ get_h a" - using \Some yb = R a wb \ a\ \get_h (R a wb) = get_h wb \ get_m (R a wb) = comp_min_mask (get_m a) (get_m wb)\ plus_charact(2) by presburger + using \Some yb = R a wb \ a\ r2 plus_charact(2) by presburger then have "get_h (multiply \ yb) = get_h wb ++ get_h a" using \pgte pwrite \ \ pgte pwrite \\ get_h_multiply by presburger moreover have "compatible_heaps (get_h wa) (get_h wb)" proof (rule compatible_heapsI) fix hl a b assume "get_h wa hl = Some a" "get_h wb hl = Some b" then have "get_h xa hl = Some a" "get_h xb hl = Some b" apply (metis (full_types) \pgte pwrite \ \ pgte pwrite \\ \xa \ multiply \ wa\ get_h_multiply larger_heap_def larger_implies_larger_heap) by (metis \get_h wb hl = Some b\ \pgte pwrite \ \ pgte pwrite \\ \xb \ multiply \ wb\ get_h_multiply larger_heap_def larger_implies_larger_heap) moreover have "compatible_heaps (get_h xa) (get_h xb)" by (metis \Some w = xa \ xb\ option.simps(3) plus_ab_defined) ultimately show "a = b" by (metis compatible_heaps_def compatible_options.simps(1)) qed ultimately show "compatible_heaps (get_h (multiply \ ya)) (get_h (multiply \ yb))" - by (metis PartialSA.commutative PartialSA.core_is_smaller \Some ya = R a wa \ a\ \Some yb = R a wb \ a\ \get_h (R a wa) = get_h wa \ get_m (R a wa) = comp_min_mask (get_m a) (get_m wa)\ \get_h (R a wb) = get_h wb \ get_m (R a wb) = comp_min_mask (get_m a) (get_m wb)\ compatible_heaps_sum core_defined(1) core_defined(2) option.distinct(1) plus_ab_defined) + by (metis PartialSA.commutative PartialSA.core_is_smaller \Some ya = R a wa \ a\ \Some yb = R a wb \ a\ + r1 r2 compatible_heaps_sum core_defined(1) core_defined(2) option.distinct(1) plus_ab_defined) show "valid_mask (add_masks (get_m (multiply \ ya)) (get_m (multiply \ yb)))" proof (rule valid_maskI) show "\f. add_masks (get_m (multiply \ ya)) (get_m (multiply \ yb)) (null, f) = pnone" by (metis (no_types, opaque_lifting) PartialSA.core_is_smaller add_masks.simps core_defined(2) minus_empty not_None_eq plus_ab_defined valid_mask.simps) fix hl have "add_masks (get_m (multiply \ ya)) (get_m (multiply \ yb)) hl = padd (pmult \ (get_m ya hl)) (pmult \ (get_m yb hl))" using \pgte pwrite \ \ pgte pwrite \\ get_m_smaller by auto moreover have "get_m ya hl = padd (get_m (R a wa) hl) (get_m a hl) \ get_m yb hl = padd (get_m (R a wb) hl) (get_m a hl)" using \Some ya = R a wa \ a\ \Some yb = R a wb \ a\ plus_charact(1) by auto ultimately show "pgte pwrite (add_masks (get_m (multiply \ ya)) (get_m (multiply \ yb)) hl)" by (metis PartialSA.unit_neutral asm0 option.distinct(1) padd_one_ineq_sum plus_ab_defined plus_charact(1) valid_mask.simps) qed qed then obtain y where "Some y = multiply \ ya \ multiply \ yb" using PartialSA.defined_def by auto moreover have "x \ y" proof (rule greaterI) have "get_h y = get_h ya ++ get_h yb" using \pgte pwrite \ \ pgte pwrite \\ calculation(10) get_h_multiply plus_charact(2) by presburger moreover have "get_h ya = get_h wa ++ get_h a" - using \Some ya = R a wa \ a\ \get_h (R a wa) = get_h wa \ get_m (R a wa) = comp_min_mask (get_m a) (get_m wa)\ plus_charact(2) by presburger + using \Some ya = R a wa \ a\ r1 plus_charact(2) by presburger moreover have "get_h yb = get_h wb ++ get_h a" - using \Some yb = R a wb \ a\ \get_h (R a wb) = get_h wb \ get_m (R a wb) = comp_min_mask (get_m a) (get_m wb)\ plus_charact(2) by presburger + using \Some yb = R a wb \ a\ r2 plus_charact(2) by presburger moreover have "larger_heap (get_h x) (get_h wa)" proof - have "larger_heap (get_h x) (get_h xa)" - by (metis PartialSA.greater_def \Some w = xa \ xb\ \get_h (R a w) = get_h w \ get_m (R a w) = comp_min_mask (get_m a) (get_m w)\ asm1 larger_heap_trans larger_implies_larger_heap) + by (metis PartialSA.greater_def \Some w = xa \ xb\ r3 asm1 larger_heap_trans larger_implies_larger_heap) moreover have "larger_heap (get_h xa) (get_h wa)" by (metis \pgte pwrite \ \ pgte pwrite \\ \xa \ multiply \ wa\ get_h_multiply larger_implies_larger_heap) ultimately show ?thesis using larger_heap_trans by blast qed moreover have "larger_heap (get_h x) (get_h wb)" proof - have "larger_heap (get_h x) (get_h xb)" - by (metis PartialSA.greater_def PartialSA.greater_equiv \Some w = xa \ xb\ \get_h (R a w) = get_h w \ get_m (R a w) = comp_min_mask (get_m a) (get_m w)\ asm1 larger_heap_trans larger_implies_larger_heap) + by (metis PartialSA.greater_def PartialSA.greater_equiv \Some w = xa \ xb\ r3 asm1 larger_heap_trans larger_implies_larger_heap) moreover have "larger_heap (get_h xb) (get_h wb)" by (metis \pgte pwrite \ \ pgte pwrite \\ \xb \ multiply \ wb\ get_h_multiply larger_implies_larger_heap) ultimately show ?thesis using larger_heap_trans by blast qed moreover have "larger_heap (get_h x) (get_h a)" using PartialSA.greater_equiv asm1 larger_implies_larger_heap by blast ultimately show "larger_heap (get_h x) (get_h y)" by (simp add: larger_heap_plus) show "greater_mask (get_m x) (get_m y)" proof (rule greater_maskI) fix hl have "get_m x hl = padd (get_m (R a w) hl) (get_m a hl)" using asm1 plus_charact(1) by auto moreover have "get_m y hl = padd (pmult \ (padd (get_m (R a wa) hl) (get_m a hl))) (pmult \ (padd (get_m (R a wb) hl) (get_m a hl)))" by (metis \Some y = multiply \ ya \ multiply \ yb\ \Some ya = R a wa \ a\ \Some yb = R a wb \ a\ \pgte pwrite \ \ pgte pwrite \\ add_masks.simps get_m_smaller plus_charact(1)) - moreover have "padd (pmult \ (padd (get_m (R a wa) hl) (get_m a hl))) (pmult \ (padd (get_m (R a wb) hl) (get_m a hl))) + moreover have equ: "padd (pmult \ (padd (get_m (R a wa) hl) (get_m a hl))) (pmult \ (padd (get_m (R a wb) hl) (get_m a hl))) = padd (padd (pmult \ (get_m a hl)) (pmult \ (get_m a hl))) (padd (pmult \ (get_m (R a wa) hl)) (pmult \ (get_m (R a wb) hl)))" using padd_asso padd_comm pmult_distr by force have "pgte (get_m (R a w) hl) (padd (pmult \ (get_m (R a wa) hl)) (pmult \ (get_m (R a wb) hl)))" proof (cases "pgte (get_m w hl) (comp_one (get_m a hl))") case True then have "get_m (R a w) hl = (comp_one (get_m a hl))" - using \get_h (R a w) = get_h w \ get_m (R a w) = comp_min_mask (get_m a) (get_m w)\ comp_min_mask_def pmin_is by presburger + using r3 comp_min_mask_def pmin_is by presburger moreover have "pgte (comp_one (get_m a hl)) (get_m (R a wa) hl)" - by (metis \get_h (R a wa) = get_h wa \ get_m (R a wa) = comp_min_mask (get_m a) (get_m wa)\ comp_min_mask_def pmin_comm pmin_greater) + by (metis r1 comp_min_mask_def pmin_comm pmin_greater) then have "pgte (pmult \ (comp_one (get_m a hl))) (pmult \ (get_m (R a wa) hl))" by (metis pmult_comm pmult_order) moreover have "pgte (comp_one (get_m a hl)) (get_m (R a wb) hl)" - by (metis \get_h (R a wb) = get_h wb \ get_m (R a wb) = comp_min_mask (get_m a) (get_m wb)\ comp_min_mask_def pmin_comm pmin_greater) + by (metis r2 comp_min_mask_def pmin_comm pmin_greater) then have "pgte (pmult \ (comp_one (get_m a hl))) (pmult \ (get_m (R a wb) hl))" by (metis pmult_comm pmult_order) ultimately show ?thesis using \pgte (comp_one (get_m a hl)) (get_m (R a wa) hl)\ \pgte (comp_one (get_m a hl)) (get_m (R a wb) hl)\ asm0 padd_one_ineq_sum by presburger next case False then have "get_m (R a w) hl = get_m w hl" - by (metis \get_h (R a w) = get_h w \ get_m (R a w) = comp_min_mask (get_m a) (get_m w)\ comp_min_mask_def not_pgte_charact pgt_implies_pgte pmin_comm pmin_is) + by (metis r3 comp_min_mask_def not_pgte_charact pgt_implies_pgte pmin_comm pmin_is) moreover have "pgte (get_m w hl) (padd (pmult \ (get_m wa hl)) (pmult \ (get_m wb hl)))" proof - have "pgte (get_m w hl) (padd (get_m xa hl) (get_m xb hl))" using \Some w = xa \ xb\ not_pgte_charact pgt_implies_pgte plus_charact(1) by auto moreover have "pgte (get_m xa hl) (pmult \ (get_m wa hl))" by (metis \pgte pwrite \ \ pgte pwrite \\ \xa \ multiply \ wa\ get_m_smaller larger_implies_greater_mask_hl) moreover have "pgte (get_m xb hl) (pmult \ (get_m wb hl))" by (metis \pgte pwrite \ \ pgte pwrite \\ \xb \ multiply \ wb\ get_m_smaller larger_implies_greater_mask_hl) ultimately show ?thesis by (simp add: padd.rep_eq pgte.rep_eq) qed moreover have "pgte (pmult \ (get_m wa hl)) (pmult \ (get_m (R a wa) hl))" by (metis R_smaller larger_implies_greater_mask_hl pmult_comm pmult_order) moreover have "pgte (pmult \ (get_m wb hl)) (pmult \ (get_m (R a wb) hl))" by (metis R_smaller larger_implies_greater_mask_hl pmult_comm pmult_order) ultimately show ?thesis using padd.rep_eq pgte.rep_eq by force qed moreover have "get_m x hl = padd (get_m (R a w) hl) (get_m a hl)" using calculation(1) by auto moreover have "get_m y hl = padd (pmult \ (get_m ya hl)) (pmult \ (get_m yb hl))" using \Some y = multiply \ ya \ multiply \ yb\ \pgte pwrite \ \ pgte pwrite \\ get_m_smaller plus_charact(1) by auto moreover have "padd (pmult \ (get_m ya hl)) (pmult \ (get_m yb hl)) = padd (pmult \ (padd (get_m (R a wa) hl) (get_m a hl))) (pmult \ (padd (get_m (R a wb) hl) (get_m a hl)))" using calculation(2) calculation(5) by presburger moreover have "... = padd (pmult (padd \ \) (get_m a hl)) (padd (pmult \ (get_m (R a wa) hl)) (pmult \ (get_m (R a wb) hl)))" - by (metis \padd (pmult \ (padd (get_m (R a wa) hl) (get_m a hl))) (pmult \ (padd (get_m (R a wb) hl) (get_m a hl))) = padd (padd (pmult \ (get_m a hl)) (pmult \ (get_m a hl))) (padd (pmult \ (get_m (R a wa) hl)) (pmult \ (get_m (R a wb) hl)))\ pmult_comm pmult_distr) + by (metis equ pmult_comm pmult_distr) ultimately show "pgte (get_m x hl) (get_m y hl)" using asm0 p_greater_exists padd_asso padd_comm pmult_special(1) by force qed qed ultimately have "y \ multiply_sem_assertion \ B \ multiply_sem_assertion \ B" using PartialSA.add_set_elem by blast then have "y \ multiply_sem_assertion pwrite B" by (metis asm0 assms(1) combinable_def not_pgte_charact pgt_implies_pgte subsetD) then obtain b where "y \ multiply pwrite b" "b \ B" using in_multiply_sem by blast then have "multiply pwrite b = b" by (metis Rep_state_inverse get_h_m mult_write_mask multiply.simps) then have "y \ B" by (metis \b \ B\ \y \ multiply pwrite b\ assms(2) intuitionistic_def) show "x \ B" using \x \ y\ \y \ B\ assms(2) intuitionistic_def by blast qed qed qed subsection Theorems text \The following theorem is crucial to use the package logic~\cite{Dardinier22} to automatically compute footprints of combinable wands.\ theorem R_mono_transformer: "PartialSA.mono_transformer (R a)" proof - have "R a unit = unit" by (simp add: PartialSA.succ_antisym PartialSA.unit_smaller R_smaller) moreover have "\\ \'. \' \ \ \ R a \' \ R a \" proof - fix \ \' assume "\' \ \" show "R a \' \ R a \" proof (cases "scalable \' a") case True then show ?thesis by (metis PartialSA.succ_trans R_def R_smaller \\' \ \\) next case False then obtain p where "ppos p" "pgte pwrite p" "multiply p \' |#| a" by (metis PartialSA.commutative PartialSA.defined_def non_scalable_instantiate) then have "multiply p \ |#| a" using PartialSA.smaller_compatible \\' \ \\ multiply_order by blast then have "\ scalable \ a" using PartialSA.commutative PartialSA.defined_def \pgte pwrite p\ \ppos p\ scalable_def scaled_def by auto moreover have "greater_mask (comp_min_mask (get_m a) (get_m \')) (comp_min_mask (get_m a) (get_m \))" proof (rule greater_maskI) fix hl show "pgte (comp_min_mask (get_m a) (get_m \') hl) (comp_min_mask (get_m a) (get_m \) hl)" proof (cases "pgte (get_m \' hl) (comp_one (get_m a hl))") case True then show ?thesis by (metis comp_min_mask_def pmin_comm pmin_greater pmin_is) next case False then show ?thesis by (metis PartialSA.succ_trans R_smaller \\' \ \\ calculation comp_min_mask_def larger_implies_greater_mask_hl non_scalable_R_charact not_pgte_charact pgt_implies_pgte pmin_comm pmin_is) qed qed ultimately show ?thesis using False \\' \ \\ greaterI larger_implies_larger_heap non_scalable_R_charact by presburger qed qed ultimately show ?thesis by (simp add: PartialSA.mono_transformer_def) qed theorem properties_of_combinable_wands: assumes "intuitionistic B" shows "combinable B \ combinable (cwand A B)" and "cwand A B \ wand A B" and "binary A \ cwand A B = wand A B" by (simp_all add: assms combinable_cwand cwand_stronger binary_same dual_order.eq_iff) end diff --git a/thys/Combinable_Wands/Mask.thy b/thys/Combinable_Wands/Mask.thy --- a/thys/Combinable_Wands/Mask.thy +++ b/thys/Combinable_Wands/Mask.thy @@ -1,499 +1,499 @@ subsection \Permission masks: Maps from heap locations to permission amounts\ theory Mask imports PosRat begin subsubsection \Definitions\ type_synonym field = string type_synonym address = nat type_synonym heap_loc = "address \ field" type_synonym mask = "heap_loc \ prat" type_synonym bmask = "heap_loc \ bool" definition null where "null = 0" definition full_mask :: "mask" where "full_mask hl = (if fst hl = null then pnone else pwrite)" definition multiply_mask :: "prat \ mask \ mask" where "multiply_mask p \ hl = pmult p (\ hl)" fun empty_mask where "empty_mask hl = pnone" fun empty_bmask where "empty_bmask hl = False" fun add_acc where "add_acc \ hl p = \(hl := padd (\ hl) p)" inductive rm_acc where "\ hl = padd p r \ rm_acc \ hl p (\(hl := r))" fun add_masks where "add_masks \' \ hl = padd (\' hl) (\ hl)" definition greater_mask where "greater_mask \' \ \ (\r. \' = add_masks \ r)" fun uni_mask where "uni_mask hl p = empty_mask(hl := p)" fun valid_mask :: "mask \ bool" where "valid_mask \ \ (\hl. pgte pwrite (\ hl)) \ (\f. \ (null, f) = pnone)" definition valid_null :: "mask \ bool" where "valid_null \ \ (\f. \ (null, f) = pnone)" definition equal_on_mask where "equal_on_mask \ h h' \ (\hl. ppos (\ hl) \ h hl = h' hl)" definition equal_on_bmask where "equal_on_bmask \ h h' \ (\hl. \ hl \ h hl = h' hl)" definition big_add_masks where "big_add_masks \ \' h = add_masks (\ h) (\' h)" definition big_greater_mask where "big_greater_mask \ \' \ (\h. greater_mask (\ h) (\' h))" definition greater_bmask where "greater_bmask H H' \ (\h. H' h \ H h)" definition update_dm where "update_dm dm \ \' hl \ (dm hl \ pgt (\ hl) (\' hl))" fun pre_get_m where "pre_get_m \ = fst \" fun pre_get_h where "pre_get_h \ = snd \" fun srm_acc where "srm_acc \ hl p = (rm_acc (pre_get_m \) hl p, pre_get_h \)" datatype val = Bool (the_bool: bool) | Address (the_address: address) | Rat (the_rat: prat) definition upper_bounded :: "mask \ prat \ bool" where "upper_bounded \ p \ (\hl. pgte p (\ hl))" subsubsection \Lemmas\ lemma ssubsetI: assumes "\\ h. (\, h) \ A \ (\, h) \ B" shows "A \ B" using assms by auto lemma double_inclusion: assumes "A \ B" and "B \ A" shows "A = B" using assms by blast lemma add_masks_comm: "add_masks a b = add_masks b a" proof (rule ext) fix x show "add_masks a b x = add_masks b a x" by (metis Rep_prat_inverse add.commute add_masks.simps padd.rep_eq) qed lemma add_masks_asso: "add_masks (add_masks a b) c = add_masks a (add_masks b c)" proof (rule ext) fix x show "add_masks (add_masks a b) c x = add_masks a (add_masks b c) x" by (metis Rep_prat_inverse add.assoc add_masks.simps padd.rep_eq) qed lemma minus_empty: "\ = add_masks \ empty_mask" proof (rule ext) fix x show "\ x = add_masks \ empty_mask x" by (metis Rep_prat_inverse add.right_neutral add_masks.simps empty_mask.simps padd.rep_eq pnone.rep_eq) qed lemma add_acc_uni_mask: "add_acc \ hl p = add_masks \ (uni_mask hl p)" proof (rule ext) fix x show "add_acc \ hl p x = add_masks \ (uni_mask hl p) x" by (metis (no_types, opaque_lifting) add_acc.simps add_masks.simps fun_upd_apply minus_empty uni_mask.simps) qed lemma add_masks_equiv_valid_null: "valid_null (add_masks a b) \ valid_null a \ valid_null b" by (metis (mono_tags, lifting) add_masks.simps padd_zero valid_null_def) lemma valid_maskI: assumes "\hl. pgte pwrite (\ hl)" and "\f. \ (null, f) = pnone" shows "valid_mask \" by (simp add: assms(1) assms(2)) lemma greater_mask_equiv_def: "greater_mask \' \ \ (\hl. pgte (\' hl) (\ hl))" (is "?A \ ?B") proof (rule iffI) show "?A \ ?B" proof (clarify) fix hl assume "greater_mask \' \" then obtain r where "\' = add_masks \ r" using greater_mask_def by blast then show "pgte (\' hl) (\ hl)" using Rep_prat padd.rep_eq pgte.rep_eq by auto qed show "?B \ ?A" proof - assume ?B let ?r = "\hl. (SOME p. \' hl = padd (\ hl) p)" have "\' = add_masks \ ?r" proof (rule ext) fix hl have "\' hl = padd (\ hl) (?r hl)" by (meson \\hl. pgte (\' hl) (\ hl)\ p_greater_exists someI_ex) then show "\' hl = add_masks \ ?r hl" by auto qed then show ?A using greater_mask_def by blast qed qed lemma greater_maskI: assumes "\hl. pgte (\' hl) (\ hl)" shows "greater_mask \' \" by (simp add: assms greater_mask_equiv_def) lemma greater_mask_properties: "greater_mask \ \" "greater_mask a b \ greater_mask b c \ greater_mask a c" "greater_mask \' \ \ greater_mask \ \' \ \ = \'" apply (simp add: greater_maskI pgte.rep_eq) apply (metis add_masks_asso greater_mask_def) proof (rule ext) fix x assume "greater_mask \' \ \ greater_mask \ \'" - show "\ x = \' x" - by (meson \greater_mask \' \ \ greater_mask \ \'\ greater_mask_equiv_def pgte_antisym) + then show "\ x = \' x" + by (meson greater_mask_equiv_def pgte_antisym) qed lemma greater_mask_decomp: assumes "greater_mask a (add_masks b c)" shows "\a1 a2. a = add_masks a1 a2 \ greater_mask a1 b \ greater_mask a2 c" by (metis add_masks_asso assms greater_mask_def greater_mask_properties(1)) lemma valid_empty: "valid_mask empty_mask" by (metis empty_mask.simps le_add_same_cancel1 p_greater_exists padd.rep_eq pgte.rep_eq pnone.rep_eq valid_mask.simps) lemma upper_valid_aux: assumes "valid_mask a" and "a = add_masks b c" shows "valid_mask b" proof (rule valid_maskI) show "\hl. pgte pwrite (b hl)" using assms(1) assms(2) p_greater_exists padd_asso by fastforce fix f show " b (null, f) = pnone" by (metis add_masks_comm assms(1) assms(2) empty_mask.simps greater_mask_def greater_mask_equiv_def minus_empty pgte_antisym valid_mask.simps) qed lemma upper_valid: assumes "valid_mask a" and "a = add_masks b c" shows "valid_mask b \ valid_mask c" using add_masks_comm assms(1) assms(2) upper_valid_aux by blast lemma equal_on_bmaskI: assumes "\hl. \ hl \ h hl = h' hl" shows "equal_on_bmask \ h h'" using assms equal_on_bmask_def by blast lemma big_add_greater: "big_greater_mask (big_add_masks A B) B" by (metis add_masks_comm big_add_masks_def big_greater_mask_def greater_mask_def) lemma big_greater_iff: "big_greater_mask A B \ (\C. A = big_add_masks B C)" proof - assume "big_greater_mask A B" let ?C = "\h. SOME r. A h = add_masks (B h) r" have "A = big_add_masks B ?C" proof (rule ext) fix x have "A x = add_masks (B x) (?C x)" proof (rule ext) fix xa have "A x = add_masks (B x) (SOME r. A x = add_masks (B x) r)" by (metis (mono_tags, lifting) \big_greater_mask A B\ big_greater_mask_def greater_mask_def someI_ex) then show "A x xa = add_masks (B x) (SOME r. A x = add_masks (B x) r) xa" by auto qed then show "A x = big_add_masks B (\h. SOME r. A h = add_masks (B h) r) x" by (metis (no_types, lifting) big_add_masks_def) qed then show "\C. A = big_add_masks B C" by fast qed lemma big_add_masks_asso: "big_add_masks A (big_add_masks B C) = big_add_masks (big_add_masks A B) C" proof (rule ext) fix x show "big_add_masks A (big_add_masks B C) x = big_add_masks (big_add_masks A B) C x" by (simp add: add_masks_asso big_add_masks_def) qed lemma big_add_mask_neutral: "big_add_masks \ (\_. empty_mask) = \" proof (rule ext) fix x show "big_add_masks \ (\_. empty_mask) x = \ x" by (metis big_add_masks_def minus_empty) qed lemma sym_equal_on_mask: "equal_on_mask \ a b \ equal_on_mask \ b a" proof - have "\a b. equal_on_mask \ a b \ equal_on_mask \ b a" by (simp add: equal_on_mask_def) then show ?thesis by blast qed lemma greater_mask_uni_equiv: "greater_mask \ (uni_mask hl r) \ pgte (\ hl) r" by (metis add_masks_comm fun_upd_apply greater_mask_def greater_mask_equiv_def minus_empty uni_mask.simps) lemma greater_mask_uniI: assumes "pgte (\ hl) r" shows "greater_mask \ (uni_mask hl r)" using greater_mask_uni_equiv assms by metis lemma greater_bmask_refl: "greater_bmask H H" by (simp add: greater_bmask_def) lemma greater_bmask_trans: assumes "greater_bmask A B" and "greater_bmask B C" shows "greater_bmask A C" by (metis assms(1) assms(2) greater_bmask_def) lemma update_dm_same: "update_dm dm \ \ = dm" proof (rule ext) fix x show "update_dm dm \ \ x = dm x" by (simp add: pgt.rep_eq update_dm_def) qed lemma update_trans: assumes "greater_mask \ \'" and "greater_mask \' \''" shows "update_dm (update_dm dm \ \') \' \'' = update_dm dm \ \''" proof (rule ext) fix hl show "update_dm (update_dm dm \ \') \' \'' hl = update_dm dm \ \'' hl" proof - have "update_dm (update_dm dm \ \') \' \'' hl \ (update_dm dm \ \') hl \ pgt (\' hl) (\'' hl)" using update_dm_def by metis also have "... \ dm hl \ pgt (\ hl) (\' hl) \ pgt (\' hl) (\'' hl)" using update_dm_def by metis moreover have "update_dm dm \ \'' hl \ dm hl \ pgt (\ hl) (\'' hl)" using update_dm_def by metis moreover have "pgt (\ hl) (\' hl) \ pgt (\' hl) (\'' hl) \ pgt (\ hl) (\'' hl)" proof show "pgt (\ hl) (\' hl) \ pgt (\' hl) (\'' hl) \ pgt (\ hl) (\'' hl)" by (metis assms(1) assms(2) greater_mask_equiv_def greater_mask_properties(2) not_pgte_charact pgte_antisym) show "pgt (\ hl) (\'' hl) \ pgt (\ hl) (\' hl) \ pgt (\' hl) (\'' hl)" by (metis assms(1) greater_mask_equiv_def not_pgte_charact pgte_antisym) qed ultimately show ?thesis by blast qed qed lemma equal_on_bmask_greater: assumes "equal_on_bmask \' h h'" and "greater_bmask \' \" shows "equal_on_bmask \ h h'" by (metis (mono_tags, lifting) assms(1) assms(2) equal_on_bmask_def greater_bmask_def) lemma update_dm_equal_bmask: assumes "\ = add_masks \' m" shows "equal_on_bmask (update_dm dm \ \') h' h \ equal_on_mask m h h' \ equal_on_bmask dm h h'" proof - have "equal_on_bmask (update_dm dm \ \') h' h \ (\hl. update_dm dm \ \' hl \ h' hl = h hl)" by (simp add: equal_on_bmask_def) moreover have "\hl. update_dm dm \ \' hl \ dm hl \ pgt (\ hl) (\' hl)" by (simp add: update_dm_def) moreover have "(\hl. update_dm dm \ \' hl \ h' hl = h hl) \ equal_on_mask m h h' \ equal_on_bmask dm h h'" proof show "\hl. update_dm dm \ \' hl \ h' hl = h hl \ equal_on_mask m h h' \ equal_on_bmask dm h h'" by (simp add: assms equal_on_bmask_def equal_on_mask_def padd.rep_eq pgt.rep_eq ppos.rep_eq update_dm_def) assume "equal_on_mask m h h' \ equal_on_bmask dm h h'" then have "\hl. update_dm dm \ \' hl \ h' hl = h hl" by (metis (full_types) add.right_neutral add_masks.simps assms dual_order.strict_iff_order equal_on_bmask_def equal_on_mask_def padd.rep_eq pgt.rep_eq pnone.rep_eq ppos_eq_pnone update_dm_def) then show "\hl. update_dm dm \ \' hl \ h' hl = h hl" by simp qed then show ?thesis by (simp add: calculation) qed lemma const_sum_mask_greater: assumes "add_masks a b = add_masks c d" and "greater_mask a c" shows "greater_mask d b" proof (rule ccontr) assume "\ greater_mask d b" then obtain hl where "\ pgte (d hl) (b hl)" using greater_mask_equiv_def by blast then have "pgt (b hl) (d hl)" using not_pgte_charact by auto then have "pgt (padd (a hl) (b hl)) (padd (c hl) (d hl))" by (metis assms(2) greater_mask_equiv_def padd_comm pgte_pgt) then show "False" by (metis add_masks.simps assms(1) not_pgte_charact order_refl pgte.rep_eq) qed lemma add_masks_cancellative: assumes "add_masks b c = add_masks b d" shows "c = d" proof (rule ext) fix x show "c x = d x" by (metis assms(1) const_sum_mask_greater greater_mask_properties(1) greater_mask_properties(3)) qed lemma equal_on_maskI: assumes "\hl. ppos (\ hl) \ h hl = h' hl" shows "equal_on_mask \ h h'" by (simp add: assms equal_on_mask_def) lemma greater_equal_on_mask: assumes "equal_on_mask \' h h'" and "greater_mask \' \" shows "equal_on_mask \ h h'" proof (rule equal_on_maskI) fix hl assume asm: "ppos (\ hl)" then show "h hl = h' hl" by (metis assms(1) assms(2) equal_on_mask_def greater_mask_equiv_def less_le_trans pgte.rep_eq ppos.rep_eq) qed lemma equal_on_mask_sum: "equal_on_mask \1 h h' \ equal_on_mask \2 h h' \ equal_on_mask (add_masks \1 \2) h h'" proof show "equal_on_mask (add_masks \1 \2) h h' \ equal_on_mask \1 h h' \ equal_on_mask \2 h h'" using add_masks_comm greater_equal_on_mask greater_mask_def by blast - assume "equal_on_mask \1 h h' \ equal_on_mask \2 h h'" + assume asm0: "equal_on_mask \1 h h' \ equal_on_mask \2 h h'" show "equal_on_mask (add_masks \1 \2) h h'" proof (rule equal_on_maskI) fix hl assume "ppos (add_masks \1 \2 hl)" then show "h hl = h' hl" proof (cases "ppos (\1 hl)") case True then show ?thesis - by (meson \equal_on_mask \1 h h' \ equal_on_mask \2 h h'\ equal_on_mask_def) + by (meson asm0 equal_on_mask_def) next case False then show ?thesis - by (metis \equal_on_mask \1 h h' \ equal_on_mask \2 h h'\ \ppos (add_masks \1 \2 hl)\ add_masks.simps equal_on_mask_def padd_zero ppos_eq_pnone) + by (metis asm0 \ppos (add_masks \1 \2 hl)\ add_masks.simps equal_on_mask_def padd_zero ppos_eq_pnone) qed qed qed lemma valid_larger_mask: "valid_mask \ \ greater_mask full_mask \ " by (metis fst_eqD full_mask_def greater_maskI greater_mask_def not_one_le_zero not_pgte_charact pgt_implies_pgte pgte.rep_eq pnone.rep_eq pwrite.rep_eq surjective_pairing upper_valid_aux valid_mask.elims(1)) lemma valid_mask_full_mask: "valid_mask full_mask" using greater_mask_properties(1) valid_larger_mask by blast lemma mult_greater: assumes "greater_mask a b" shows "greater_mask (multiply_mask p a) (multiply_mask p b)" by (metis (full_types) assms greater_mask_equiv_def multiply_mask_def p_greater_exists pmult_distr) lemma mult_write_mask: "multiply_mask pwrite \ = \" proof (rule ext) fix x show "multiply_mask pwrite \ x = \ x" by (simp add: multiply_mask_def pmult_special(1)) qed lemma mult_distr_masks: "multiply_mask a (add_masks b c) = add_masks (multiply_mask a b) (multiply_mask a c)" proof (rule ext) fix x show "multiply_mask a (add_masks b c) x = add_masks (multiply_mask a b) (multiply_mask a c) x" by (simp add: multiply_mask_def pmult_distr) qed lemma mult_add_states: "multiply_mask (padd a b) \ = add_masks (multiply_mask a \) (multiply_mask b \)" proof (rule ext) fix x show "multiply_mask (padd a b) \ x = add_masks (multiply_mask a \) (multiply_mask b \) x" by (simp add: multiply_mask_def pmult_comm pmult_distr) qed lemma upper_boundedI: assumes "\hl. pgte p (\ hl)" shows "upper_bounded \ p" by (simp add: assms upper_bounded_def) lemma upper_bounded_smaller: assumes "upper_bounded \ a" shows "upper_bounded (multiply_mask p \) (pmult p a)" by (metis assms multiply_mask_def p_greater_exists pmult_distr upper_bounded_def) lemma upper_bounded_bigger: assumes "upper_bounded \ a" and "pgte b a" shows "upper_bounded \ b" by (meson assms(1) assms(2) order_trans pgte.rep_eq upper_bounded_def) lemma valid_mult: assumes "valid_mask \" and "pgte pwrite p" shows "valid_mask (multiply_mask p \)" proof (rule valid_maskI) have "upper_bounded \ pwrite" using assms(1) upper_bounded_def by auto then have "upper_bounded (multiply_mask p \) (pmult p pwrite)" by (simp add: upper_bounded_smaller) then show "\hl. pgte pwrite (multiply_mask p \ hl)" by (metis assms(2) pmult_comm pmult_special(1) upper_bounded_bigger upper_bounded_def) show "\f. multiply_mask p \ (null, f) = pnone" by (metis Rep_prat_inverse add_0_left assms(1) multiply_mask_def padd.rep_eq padd_cancellative pmult_distr pnone.rep_eq valid_mask.elims(1)) qed lemma valid_sum: assumes "valid_mask a" and "valid_mask b" and "upper_bounded a ma" and "upper_bounded b mb" and "pgte pwrite (padd ma mb)" shows "valid_mask (add_masks a b)" and "upper_bounded (add_masks a b) (padd ma mb)" proof (rule valid_maskI) show "\hl. pgte pwrite (add_masks a b hl)" proof - fix hl have "pgte (padd ma mb) (add_masks a b hl)" by (metis (mono_tags, lifting) add_masks.simps add_mono_thms_linordered_semiring(1) assms(3) assms(4) padd.rep_eq pgte.rep_eq upper_bounded_def) then show "pgte pwrite (add_masks a b hl)" by (meson assms(5) dual_order.trans pgte.rep_eq) qed show "\f. add_masks a b (null, f) = pnone" by (metis Rep_prat_inverse add_0_left add_masks.simps assms(1) assms(2) padd.rep_eq pnone.rep_eq valid_mask.simps) show "upper_bounded (add_masks a b) (padd ma mb)" using add_mono_thms_linordered_semiring(1) assms(3) assms(4) padd.rep_eq pgte.rep_eq upper_bounded_def by fastforce qed lemma valid_multiply: assumes "valid_mask a" and "upper_bounded a ma" and "pgte pwrite (pmult ma p)" shows "valid_mask (multiply_mask p a)" by (metis (no_types, opaque_lifting) assms(1) assms(2) assms(3) multiply_mask_def pmult_comm pmult_special(2) upper_bounded_bigger upper_bounded_def upper_bounded_smaller valid_mask.elims(1)) lemma greater_mult: assumes "greater_mask a b" shows "greater_mask (multiply_mask p a) (multiply_mask p b)" by (metis Rep_prat assms greater_mask_equiv_def mem_Collect_eq mult_left_mono multiply_mask_def pgte.rep_eq pmult.rep_eq) -end +end \ No newline at end of file diff --git a/thys/Combinable_Wands/PartialHeapSA.thy b/thys/Combinable_Wands/PartialHeapSA.thy --- a/thys/Combinable_Wands/PartialHeapSA.thy +++ b/thys/Combinable_Wands/PartialHeapSA.thy @@ -1,604 +1,604 @@ subsection \Partial heaps: Partial maps from heap location to values\ theory PartialHeapSA imports Mask "Package_logic.PackageLogic" begin subsubsection \Definitions\ type_synonym heap = "heap_loc \ val" type_synonym pre_state = "mask \ heap" definition valid_heap :: "mask \ heap \ bool" where "valid_heap \ h \ (\hl. ppos (\ hl) \ h hl \ None)" fun valid_state :: "pre_state \ bool" where "valid_state (\, h) \ valid_mask \ \ valid_heap \ h" lemma valid_stateI: assumes "valid_mask \" and "\hl. ppos (\ hl) \ h hl \ None" shows "valid_state (\, h)" using assms(1) assms(2) valid_heap_def valid_state.simps by blast definition empty_heap where "empty_heap hl = None" lemma valid_pre_unit: "valid_state (empty_mask, empty_heap)" using pnone.rep_eq ppos.rep_eq valid_empty valid_stateI by fastforce typedef state = "{ \ |\. valid_state \ }" using valid_pre_unit by blast fun get_m :: "state \ mask" where "get_m a = fst (Rep_state a)" fun get_h :: "state \ heap" where "get_h a = snd (Rep_state a)" fun compatible_options where "compatible_options (Some a) (Some b) \ a = b" | "compatible_options _ _ \ True" definition compatible_heaps :: "heap \ heap \ bool" where "compatible_heaps h h' \ (\hl. compatible_options (h hl) (h' hl))" definition compatible :: "pre_state \ pre_state \ bool" where "compatible \ \' \ compatible_heaps (snd \) (snd \') \ valid_mask (add_masks (fst \) (fst \'))" fun add_states :: "pre_state \ pre_state \ pre_state" where "add_states (\, h) (\', h') = (add_masks \ \', h ++ h')" definition larger_heap where "larger_heap h' h \ (\hl x. h hl = Some x \ h' hl = Some x)" definition unit :: "state" where "unit = Abs_state (empty_mask, empty_heap)" definition plus :: "state \ state \ state" (infixl "\" 63) where "a \ b = (if compatible (Rep_state a) (Rep_state b) then Some (Abs_state (add_states (Rep_state a) (Rep_state b))) else None)" definition core :: "state \ state" (" |_| ") where "core \ = Abs_state (empty_mask, get_h \)" definition stable :: "state \ bool" where "stable \ \ (\hl. ppos (get_m \ hl) \ get_h \ hl \ None)" subsubsection Lemmas lemma valid_heapI: assumes "\hl. ppos (\ hl) \ h hl \ None" shows "valid_heap \ h" using assms valid_heap_def by presburger lemma valid_state_decompose: assumes "valid_state (add_masks a b, h)" shows "valid_state (a, h)" proof (rule valid_stateI) show "valid_mask a" using assms upper_valid_aux valid_state.simps by blast fix hl assume "ppos (a hl)" then show "h hl \ None" by (metis add_masks.simps assms ppos_add valid_heap_def valid_state.simps) qed lemma compatible_heapsI: assumes "\hl a b. h hl = Some a \ h' hl = Some b \ a = b" shows "compatible_heaps h h'" by (metis assms compatible_heaps_def compatible_options.elims(3)) lemma compatibleI_old: assumes "\hl x y. snd \ hl = Some x \ snd \' hl = Some y \ x = y" and "valid_mask (add_masks (fst \) (fst \'))" shows "compatible \ \'" using assms(1) assms(2) compatible_def compatible_heapsI by presburger lemma larger_heap_anti: assumes "larger_heap a b" and "larger_heap b a" shows "a = b" proof (rule ext) fix x show "a x = b x" proof (cases "a x") case None then show ?thesis by (metis assms(1) larger_heap_def not_None_eq) next case (Some a) then show ?thesis by (metis assms(2) larger_heap_def) qed qed lemma larger_heapI: assumes "\hl x. h hl = Some x \ h' hl = Some x" shows "larger_heap h' h" by (simp add: assms larger_heap_def) lemma larger_heap_refl: "larger_heap h h" using larger_heap_def by blast lemma compatible_heaps_comm: assumes "compatible_heaps a b" shows "a ++ b = b ++ a" proof (rule ext) fix x show "(a ++ b) x = (b ++ a) x" proof (cases "a x") case None then show ?thesis by (simp add: domIff map_add_dom_app_simps(2) map_add_dom_app_simps(3)) next case (Some a) then show ?thesis by (metis (no_types, lifting) assms compatible_heaps_def compatible_options.elims(2) map_add_None map_add_dom_app_simps(1) map_add_dom_app_simps(3)) qed qed lemma larger_heaps_sum_ineq: assumes "larger_heap a' a" and "larger_heap b' b" and "compatible_heaps a' b'" shows "larger_heap (a' ++ b') (a ++ b)" proof (rule larger_heapI) fix hl x assume "(a ++ b) hl = Some x" show "(a' ++ b') hl = Some x" proof (cases "a hl") case None then show ?thesis by (metis \(a ++ b) hl = Some x\ assms(2) larger_heap_def map_add_SomeD map_add_find_right) next case (Some aa) then show ?thesis by (metis (mono_tags, lifting) \(a ++ b) hl = Some x\ assms(1) assms(2) assms(3) compatible_heaps_comm larger_heap_def map_add_Some_iff) qed qed lemma larger_heap_trans: assumes "larger_heap a b" and "larger_heap b c" shows "larger_heap a c" by (metis (no_types, opaque_lifting) assms(1) assms(2) larger_heap_def) lemma larger_heap_comp: assumes "larger_heap a b" and "compatible_heaps a c" shows "compatible_heaps b c" proof (rule compatible_heapsI) fix hl a ba assume "b hl = Some a" "c hl = Some ba" then show "a = ba" by (metis assms(1) assms(2) compatible_heaps_def compatible_options.simps(1) larger_heap_def) qed lemma larger_heap_plus: assumes "larger_heap a b" and "larger_heap a c" shows "larger_heap a (b ++ c)" proof (rule larger_heapI) fix hl x assume "(b ++ c) hl = Some x" then show "a hl = Some x" proof (cases "b hl") case None then show ?thesis by (metis \(b ++ c) hl = Some x\ assms(2) larger_heap_def map_add_SomeD) next case (Some bb) then show ?thesis by (metis \(b ++ c) hl = Some x\ assms(1) assms(2) larger_heap_def map_add_SomeD) qed qed lemma compatible_heaps_sum: assumes "compatible_heaps a b" and "compatible_heaps a c" shows "compatible_heaps a (b ++ c)" by (metis (no_types, opaque_lifting) assms(1) assms(2) compatible_heaps_def map_add_dom_app_simps(1) map_add_dom_app_simps(3)) lemma larger_compatible_sum_heaps: assumes "larger_heap a x" and "larger_heap b y" and "compatible_heaps a b" shows "compatible_heaps x y" proof (rule compatible_heapsI) fix hl a b assume "x hl = Some a" "y hl = Some b" then show "a = b" by (metis assms(1) assms(2) assms(3) compatible_heaps_def compatible_options.simps(1) larger_heap_def) qed lemma get_h_m: "Rep_state x = (get_m x, get_h x)" by simp lemma get_pre: "get_h x = snd (Rep_state x)" "get_m x = fst (Rep_state x)" by simp_all lemma plus_ab_defined: "\ \ \' \ None \ compatible_heaps (get_h \) (get_h \') \ valid_mask (add_masks (get_m \) (get_m \'))" (is "?A \ ?B") proof show "?A \ ?B" by (metis compatible_def get_pre(1) get_pre(2) plus_def) show "?B \ ?A" using compatible_def plus_def by auto qed lemma plus_charact: assumes "a \ b = Some x" shows "get_m x = add_masks (get_m a) (get_m b)" and "get_h x = (get_h a) ++ (get_h b)" proof - have "x = (Abs_state (add_states (Rep_state a) (Rep_state b)))" by (metis assms option.discI option.inject plus_def) moreover have "compatible (Rep_state a) (Rep_state b)" using assms(1) plus_def by (metis option.discI) moreover have "valid_state (add_states (Rep_state a) (Rep_state b))" proof - have "valid_state (add_masks (get_m a) (get_m b), (get_h a) ++ (get_h b))" proof (rule valid_stateI) show "valid_mask (add_masks (get_m a) (get_m b))" using calculation(2) compatible_def by fastforce fix hl assume "ppos (add_masks (get_m a) (get_m b) hl)" then show "(get_h a ++ get_h b) hl \ None" proof (cases "ppos (get_m a hl)") case True then show ?thesis by (metis Rep_state get_h_m map_add_None mem_Collect_eq valid_heap_def valid_state.simps) next case False then have "ppos (get_m b hl)" using \ppos (add_masks (get_m a) (get_m b) hl)\ padd.rep_eq ppos.rep_eq by auto then show ?thesis by (metis Rep_state get_h_m map_add_None mem_Collect_eq valid_heap_def valid_state.simps) qed qed then show ?thesis using add_states.simps get_h_m by presburger qed ultimately show "get_m x = add_masks (get_m a) (get_m b)" by (metis Abs_state_inverse add_states.simps fst_conv get_h_m mem_Collect_eq) show "get_h x = (get_h a) ++ (get_h b)" by (metis Abs_state_inject CollectI Rep_state Rep_state_inverse \valid_state (add_states (Rep_state a) (Rep_state b))\ \x = Abs_state (add_states (Rep_state a) (Rep_state b))\ add_states.simps eq_snd_iff get_h.simps) qed lemma commutative: "a \ b = b \ a" proof (cases "compatible_heaps (get_h a) (get_h b) \ valid_mask (add_masks (get_m a) (get_m b))") case True - then have "compatible_heaps (get_h b) (get_h a) \ add_masks (get_m a) (get_m b) = add_masks (get_m b) (get_m a)" + then have r0: "compatible_heaps (get_h b) (get_h a) \ add_masks (get_m a) (get_m b) = add_masks (get_m b) (get_m a)" by (metis add_masks_comm compatible_heapsI compatible_heaps_def compatible_options.simps(1)) then have "(get_h a) ++ (get_h b) = (get_h b) ++ (get_h a)" by (simp add: compatible_heaps_comm) then show ?thesis - by (metis True \compatible_heaps (get_h b) (get_h a) \ add_masks (get_m a) (get_m b) = add_masks (get_m b) (get_m a)\ add_states.simps get_h_m plus_ab_defined plus_def) + by (metis True r0 add_states.simps get_h_m plus_ab_defined plus_def) next case False then show ?thesis by (metis add_masks_comm compatible_heapsI compatible_heaps_def compatible_options.simps(1) plus_ab_defined) qed lemma asso1: assumes "a \ b = Some ab \ b \ c = Some bc" shows "ab \ c = a \ bc" proof (cases "ab \ c") case None then show ?thesis proof (cases "compatible_heaps (get_h ab) (get_h c)") case True then have "\ valid_mask (add_masks (add_masks (get_m a) (get_m b)) (get_m c))" by (metis None assms plus_ab_defined plus_charact(1)) then show ?thesis by (metis add_masks_asso assms plus_ab_defined plus_charact(1)) next case False then have "\ compatible_heaps (get_h a ++ get_h b) (get_h c)" using assms plus_charact(2) by force then obtain l x y where "(get_h a ++ get_h b) l = Some x" "get_h c l = Some y" "x \ y" using compatible_heapsI by blast then have "\ compatible_heaps (get_h a) (get_h b ++ get_h c)" proof (cases "get_h a l") case None then show ?thesis by (metis \(get_h a ++ get_h b) l = Some x\ \get_h c l = Some y\ \x \ y\ assms compatible_heaps_comm map_add_dom_app_simps(1) map_add_dom_app_simps(3) map_add_find_right option.inject option.simps(3) plus_ab_defined) next case (Some aa) then show ?thesis by (metis \(get_h a ++ get_h b) l = Some x\ \get_h c l = Some y\ \x \ y\ assms commutative compatible_heaps_def compatible_options.elims(2) map_add_find_right option.inject option.simps(3) plus_charact(2)) qed then show ?thesis by (metis None assms plus_ab_defined plus_charact(2)) qed next case (Some x) then have "compatible_heaps (get_h a ++ get_h b) (get_h c)" by (metis assms option.simps(3) plus_ab_defined plus_charact(2)) then have "compatible_heaps (get_h a) (get_h b ++ get_h c)" by (metis (full_types) assms compatible_heaps_comm compatible_heaps_def compatible_heaps_sum compatible_options.simps(2) domIff map_add_dom_app_simps(1) option.distinct(1) plus_ab_defined) moreover have "valid_mask (add_masks (get_m a) (add_masks (get_m b) (get_m c)))" by (metis Some add_masks_asso assms option.distinct(1) plus_ab_defined plus_charact(1)) ultimately obtain y where "Some y = a \ bc" by (metis assms plus_ab_defined plus_charact(1) plus_charact(2) plus_def) then show ?thesis by (metis (mono_tags, lifting) Some add_masks_asso add_states.simps assms get_h_m map_add_assoc option.distinct(1) plus_charact(1) plus_charact(2) plus_def) qed lemma asso2: assumes "a \ b = Some ab \ b \ c = None" shows " ab \ c = None" proof (cases "valid_mask (add_masks (get_m b) (get_m c))") case True then have "\ compatible_heaps (get_h b) (get_h c)" using assms plus_ab_defined by blast then obtain l x y where "get_h b l = Some x" "get_h c l = Some y" "x \ y" using compatible_heapsI by blast then have "get_h ab l = Some x" by (metis assms map_add_find_right plus_charact(2)) then show ?thesis by (metis \get_h c l = Some y\ \x \ y\ compatible_heaps_def compatible_options.simps(1) plus_ab_defined) next case False then obtain l where "\ (pgte pwrite (add_masks (get_m b) (get_m c) l))" by (metis Abs_state_cases Rep_state_cases Rep_state_inverse add_masks_equiv_valid_null get_h_m mem_Collect_eq valid_mask.simps valid_null_def valid_state.simps) then have "\ (pgte pwrite (add_masks (get_m ab) (get_m c) l))" proof - have "pgte (add_masks (get_m ab) (get_m c) l) (add_masks (get_m b) (get_m c) l)" using assms p_greater_exists padd_asso padd_comm plus_charact(1) by auto then show ?thesis by (meson \\ pgte pwrite (add_masks (get_m b) (get_m c) l)\ order_trans pgte.rep_eq) qed then show ?thesis using plus_ab_defined valid_mask.simps by blast qed lemma core_defined: "get_h |\| = get_h \" "get_m |\| = empty_mask" using Abs_state_inverse core_def pnone.rep_eq ppos.rep_eq valid_empty valid_stateI apply force by (metis Abs_state_inverse CollectI core_def empty_mask.simps fst_conv get_pre(2) less_irrefl pnone.rep_eq ppos.rep_eq valid_empty valid_stateI) lemma state_ext: assumes "get_h a = get_h b" and "get_m a = get_m b" shows "a = b" by (metis Rep_state_inverse assms(1) assms(2) get_h_m) lemma core_is_smaller: "Some x = x \ |x|" proof - obtain y where "Some y = x \ |x|" by (metis Rep_state compatible_heapsI core_defined(1) core_defined(2) get_h_m mem_Collect_eq minus_empty option.collapse option.sel plus_ab_defined valid_state.simps) moreover have "y = x" proof (rule state_ext) have "get_h x = get_h x ++ get_h x" by (simp add: map_add_subsumed1) then show "get_h y = get_h x" using calculation core_defined(1) plus_charact(2) by presburger show "get_m y = get_m x" by (metis calculation core_defined(2) minus_empty plus_charact(1)) qed ultimately show ?thesis by blast qed lemma core_is_pure: "Some |x| = |x| \ |x|" proof - obtain y where "Some y = |x| \ |x|" by (metis core_def core_defined(1) core_is_smaller) moreover have "y = |x|" by (metis calculation core_def core_defined(1) core_is_smaller option.sel) ultimately show ?thesis by blast qed lemma core_sum: assumes "Some c = a \ b" shows "Some |c| = |a| \ |b|" proof - obtain x where "Some x = |a| \ |b|" by (metis assms core_defined(1) core_defined(2) minus_empty option.exhaust_sel plus_ab_defined valid_empty) moreover have "x = |c|" by (metis assms calculation core_defined(1) core_defined(2) minus_empty plus_charact(1) plus_charact(2) state_ext) ultimately show ?thesis by blast qed lemma core_max: assumes "Some x = x \ c" shows "\r. Some |x| = c \ r" proof - obtain y where "Some y = c \ |x|" by (metis assms asso2 core_is_smaller plus_def) moreover have "|x| = y" by (metis (mono_tags, opaque_lifting) Rep_state_inverse add_masks_cancellative assms calculation commutative core_defined(1) core_sum get_h_m minus_empty option.inject plus_charact(1)) ultimately show ?thesis by blast qed lemma positivity: assumes "a \ b = Some c" and "Some c = c \ c" shows "Some a = a \ a" proof - obtain x where "Some x = a \ a" by (metis assms(1) assms(2) asso2 commutative option.exhaust_sel) moreover have "x = a" by (metis Rep_state_inverse add_masks_cancellative add_masks_comm assms(1) assms(2) calculation core_defined(1) core_defined(2) core_is_smaller get_h_m greater_mask_def greater_mask_properties(3) option.sel plus_charact(1)) ultimately show ?thesis by blast qed lemma cancellative: assumes "Some a = b \ x" and "Some a = b \ y" and "|x| = |y|" shows "x = y" by (metis add_masks_cancellative assms(1) assms(2) assms(3) core_defined(1) plus_charact(1) state_ext) lemma unit_charact: "get_h unit = empty_heap" "get_m unit = empty_mask" proof - have "valid_state (empty_mask, empty_heap)" using valid_pre_unit by auto then show "get_h unit = empty_heap" using unit_def by (simp add: \unit = Abs_state (empty_mask, empty_heap)\ Abs_state_inverse) show "get_m unit = empty_mask" using \valid_state (empty_mask, empty_heap)\ unit_def Abs_state_inverse by fastforce qed lemma empty_heap_neutral: "a ++ empty_heap = a" proof (rule ext) fix x show "(a ++ empty_heap) x = a x" by (simp add: domIff empty_heap_def map_add_dom_app_simps(3)) qed lemma unit_neutral: "Some a = a \ unit" proof - obtain x where "Some x = a \ unit" by (metis Abs_state_cases Rep_state_cases Rep_state_inverse compatible_heapsI empty_heap_def fst_conv get_h_m mem_Collect_eq minus_empty option.distinct(1) option.exhaust_sel plus_ab_defined snd_conv unit_def valid_pre_unit valid_state.simps) moreover have "x = a" proof (rule state_ext) show "get_h x = get_h a" using calculation empty_heap_neutral plus_charact(2) unit_charact(1) by auto show "get_m x = get_m a" by (metis calculation minus_empty plus_charact(1) unit_charact(2)) qed ultimately show ?thesis by blast qed lemma stableI: assumes "\hl. ppos (get_m \ hl) \ get_h \ hl \ None" shows "stable \" using assms stable_def by blast lemma stable_unit: "stable unit" by (metis empty_heap_def stable_def unit_charact(1) unit_charact(2) valid_heap_def valid_pre_unit valid_state.simps) lemma stable_sum: assumes "stable a" and "stable b" and "Some x = a \ b" shows "stable x" proof (rule stableI) fix hl show "ppos (get_m x hl) = (get_h x hl \ None)" (is "?A \ ?B") proof show "?A \ ?B" by (metis add_le_same_cancel2 add_masks.simps assms(1) assms(2) assms(3) leI less_le_trans map_add_None padd.rep_eq plus_charact(1) plus_charact(2) ppos.rep_eq stable_def) show "?B \ ?A" by (metis add_masks.simps assms(1) assms(2) assms(3) map_add_None padd_comm plus_charact(1) plus_charact(2) ppos_add stable_def) qed qed lemma multiply_valid: assumes "pgte pwrite p" shows "valid_state (multiply_mask p (get_m \), get_h \)" proof (rule valid_stateI) show "valid_mask (multiply_mask p (get_m \))" by (metis Rep_state assms(1) get_h_m mem_Collect_eq valid_mult valid_state.simps) fix hl show "ppos (multiply_mask p (get_m \) hl) \ get_h \ hl \ None" by (metis Abs_state_cases Rep_state_cases Rep_state_inverse get_h_m mem_Collect_eq multiply_mask_def pmult_comm pmult_special(2) ppos_eq_pnone valid_heap_def valid_state.simps) qed subsection \This state model corresponds to a separation algebra\ global_interpretation PartialSA: package_logic plus core unit stable defines greater (infixl "\" 50) = "PartialSA.greater" and add_set (infixl "\" 60) = "PartialSA.add_set" and defined (infixl "|#|" 60) = "PartialSA.defined" and greater_set (infixl "|\|" 50) = "PartialSA.greater_set" and minus (infixl "|\|" 60) = "PartialSA.minus" apply standard apply (simp add: commutative) using asso1 apply blast using asso2 apply blast using core_is_smaller apply blast using core_is_pure apply blast using core_max apply blast using core_sum apply blast using positivity apply blast using cancellative apply blast using unit_neutral apply blast using stable_sum apply blast using stable_unit by blast lemma greaterI: assumes "larger_heap (get_h a) (get_h b)" and "greater_mask (get_m a) (get_m b)" shows "a \ b" proof - let ?m = "\l. SOME p. get_m a l = padd (get_m b l) p" - have "get_m a = add_masks (get_m b) ?m" + have r0: "get_m a = add_masks (get_m b) ?m" proof (rule ext) fix l have "pgte (get_m a l) (get_m b l)" by (meson assms(2) greater_mask_equiv_def) then have "get_m a l = padd (get_m b l) (SOME p. get_m a l = padd (get_m b l) p)" by (simp add: p_greater_exists verit_sko_ex') then show "get_m a l = add_masks (get_m b) (\l. SOME p. get_m a l = padd (get_m b l) p) l" by simp qed moreover have "valid_state (?m, get_h a)" proof (rule valid_stateI) show "valid_mask (\l. SOME p. get_m a l = padd (get_m b l) p)" by (metis (no_types, lifting) Rep_state calculation get_h_m mem_Collect_eq upper_valid valid_state.simps) fix hl assume asm0: "ppos (SOME p. get_m a hl = padd (get_m b hl) p)" then have "ppos (get_m a hl)" by (metis (no_types, lifting) add_masks.elims add_masks_comm calculation greater_mask_def ppos_add) then show "get_h a hl \ None" by (metis Rep_state get_h.simps get_pre(2) mem_Collect_eq prod.collapse valid_heap_def valid_state.simps) qed moreover have "compatible_heaps (get_h b) (get_h a)" by (metis (mono_tags, lifting) assms(1) compatible_heapsI larger_heap_def option.inject) - ultimately have "(get_m a, get_h a) = add_states (get_m b, get_h b) (?m, get_h a)" + ultimately have r2: "(get_m a, get_h a) = add_states (get_m b, get_h b) (?m, get_h a)" proof - have "get_h b ++ get_h a = get_h a" proof (rule ext) fix x show "(get_h b ++ get_h a) x = get_h a x" by (metis assms(1) domIff larger_heap_def map_add_dom_app_simps(1) map_add_dom_app_simps(3) not_Some_eq) qed then show ?thesis - by (metis \get_m a = add_masks (get_m b) (\l. SOME p. get_m a l = padd (get_m b l) p)\ add_states.simps) + by (metis r0 add_states.simps) qed - moreover have "compatible_heaps (get_h b) (get_h a) \ valid_mask (add_masks (get_m b) ?m)" - by (metis Rep_state \compatible_heaps (get_h b) (get_h a)\ \get_m a = add_masks (get_m b) (\l. SOME p. get_m a l = padd (get_m b l) p)\ get_h_m mem_Collect_eq valid_state.simps) + moreover have r1: "compatible_heaps (get_h b) (get_h a) \ valid_mask (add_masks (get_m b) ?m)" + by (metis Rep_state \compatible_heaps (get_h b) (get_h a)\ r0 get_h_m mem_Collect_eq valid_state.simps) ultimately have "Some a = b \ Abs_state (?m, get_h a)" proof - have "Rep_state (Abs_state (?m, get_h a)) = (?m, get_h a)" using Abs_state_inverse \valid_state (\l. SOME p. get_m a l = padd (get_m b l) p, get_h a)\ by blast moreover have "compatible (Rep_state b) (?m, get_h a)" - using \compatible_heaps (get_h b) (get_h a) \ valid_mask (add_masks (get_m b) (\l. SOME p. get_m a l = padd (get_m b l) p))\ compatible_def by auto + using r1 compatible_def by auto moreover have "valid_state (add_states (Rep_state b) (?m, get_h a))" - by (metis Rep_state \(get_m a, get_h a) = add_states (get_m b, get_h b) (\l. SOME p. get_m a l = padd (get_m b l) p, get_h a)\ get_h_m mem_Collect_eq) + by (metis Rep_state r2 get_h_m mem_Collect_eq) ultimately show ?thesis - by (metis (no_types, lifting) Rep_state_inverse \(get_m a, get_h a) = add_states (get_m b, get_h b) (\l. SOME p. get_m a l = padd (get_m b l) p, get_h a)\ get_h_m plus_def) + by (metis (no_types, lifting) Rep_state_inverse r2 get_h_m plus_def) qed then show ?thesis by (meson PartialSA.greater_def) qed lemma larger_implies_greater_mask_hl: assumes "a \ b" shows "pgte (get_m a hl) (get_m b hl)" using PartialSA.greater_def assms p_greater_exists plus_charact(1) by auto lemma larger_implies_larger_heap: assumes "a \ b" shows "larger_heap (get_h a) (get_h b)" by (metis (full_types) PartialSA.greater_equiv assms larger_heapI map_add_find_right plus_charact(2)) lemma compatibleI: assumes "compatible_heaps (get_h a) (get_h b)" and "valid_mask (add_masks (get_m a) (get_m b))" shows "a |#| b" using PartialSA.defined_def assms(1) assms(2) plus_ab_defined by presburger end