diff --git a/thys/Package_logic/PackageLogic.thy b/thys/Package_logic/PackageLogic.thy --- a/thys/Package_logic/PackageLogic.thy +++ b/thys/Package_logic/PackageLogic.thy @@ -1,1420 +1,1415 @@ section \Package Logic\ text \In this section, we define our package logic, as described in \cite{Dardinier22}, and then prove that this logic is sound and complete for packaging magic wands.\ theory PackageLogic imports Main SepAlgebra begin subsection Definitions type_synonym 'a abool = "'a \ bool" datatype 'a aassertion = AStar "'a aassertion" "'a aassertion" | AImp "'a abool" "'a aassertion" | ASem "'a abool" locale package_logic = sep_algebra + fixes unit :: "'a" fixes stable :: "'a \ bool" assumes unit_neutral: "Some a = a \ unit" and stable_sum: "stable a \ stable b \ Some x = a \ b \ stable x" and stable_unit: "stable unit" begin fun sat :: "'a aassertion \ 'a \ bool" where "sat (AStar A B) \ \ (\a b. Some \ = a \ b \ sat A a \ sat B b)" | "sat (AImp b A) \ \ (b \ \ sat A \)" | "sat (ASem A) \ \ A \" definition mono_pure_cond where "mono_pure_cond b \ (\\. b \ \ b |\| ) \ (\\' \ r. pure r \ Some \' = \ \ r \ \ b \ \ \ b \')" definition bool_conj where "bool_conj a b x \ a x \ b x" type_synonym 'c pruner = "'c \ bool" (* Only positively, so not-well defined = false *) definition mono_pruner :: "'a pruner \ bool" where "mono_pruner p \ (\\' \ r. pure r \ p \ \ Some \' = \ \ r \ p \')" (* opposite of mono_cond *) fun wf_assertion where "wf_assertion (AStar A B) \ wf_assertion A \ wf_assertion B" | "wf_assertion (AImp b A) \ mono_pure_cond b \ wf_assertion A" | "wf_assertion (ASem A) \ mono_pruner A" type_synonym 'c transformer = "'c \ 'c" type_synonym 'c ext_state = "'c \ 'c \ 'c transformer" inductive package_rhs :: "'a \ 'a \ 'a ext_state set \ 'a abool \ 'a aassertion \ 'a \ 'a \ 'a ext_state set \ bool" where AStar: "\ package_rhs \ f S pc A \' f' S' ; package_rhs \' f' S' pc B \'' f'' S'' \ \ package_rhs \ f S pc (AStar A B) \'' f'' S''" | AImp: "package_rhs \ f S (bool_conj pc b) A \' f' S' \ package_rhs \ f S pc (AImp b A) \' f' S'" (* witness means we *choose* how we satisfy B *) | ASem: "\ \a u T b. (a, u, T) \ S \ pc a \ b = witness (a, u, T) \ a \ b \ B b ; S' = { (a, u, T) |a u T. (a, u, T) \ S \ \ pc a } \ { (a \ b, the (u \ b), T) |a u T b. (a, u, T) \ S \ pc a \ b = witness (a, u, T) } \ \ package_rhs \ f S pc (ASem B) \ f S'" | AddFromOutside: "\ Some \ = \' \ m ; package_rhs \' f' S' pc A \'' f'' S'' ; stable m ; Some f' = f \ m ; S' = { (r, u, T) |a u T r. (a, u, T) \ S \ Some r = a \ (T f' \ T f) \ r ## u } \ \ package_rhs \ f S pc A \'' f'' S''" definition package_sat where "package_sat pc A a' u' u \ (pc |a'| \ (\x. Some x = |a'| \ (u' \ u ) \ sat A x))" definition package_rhs_connection :: "'a \ 'a \ 'a ext_state set \ 'a abool \ 'a aassertion \ 'a \ 'a \ 'a ext_state set \ bool" where "package_rhs_connection \ f S pc A \' f' S' \ f' \ f \ \ ## f \ \ \ f = \' \ f' \ stable f' \ (\(a, u, T) \ S. \au. Some au = a \ u \ (au ## (T f' \ T f) \ (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u)))" definition mono_transformer :: "'a transformer \ bool" where "mono_transformer T \ (\\ \'. \' \ \ \ T \' \ T \) \ T unit = unit" definition valid_package_set where "valid_package_set S f \ (\(a, u, T) \ S. a ## u \ |a| \ |u| \ mono_transformer T \ a \ |T f| )" definition intuitionistic where "intuitionistic A \ (\\' \. \' \ \ \ A \ \ A \')" definition pure_remains where "pure_remains S \ (\(a, u, p) \ S. pure a)" definition is_footprint_general :: "'a \ ('a \ 'a \ 'a) \ 'a aassertion \ 'a aassertion \ bool" where "is_footprint_general w R A B \ (\a b. sat A a \ Some b = a \ R a w \ sat B b)" definition is_footprint_standard :: "'a \ 'a aassertion \ 'a aassertion \ bool" where "is_footprint_standard w A B \ (\a b. sat A a \ Some b = a \ w \ sat B b)" subsection Lemmas lemma is_footprint_generalI: assumes "\a b. sat A a \ Some b = a \ R a w \ sat B b" shows "is_footprint_general w R A B" using assms is_footprint_general_def by blast lemma is_footprint_standardI: assumes "\a b. sat A a \ Some b = a \ w \ sat B b" shows "is_footprint_standard w A B" using assms is_footprint_standard_def by blast lemma mono_pure_condI: assumes "\\. b \ \ b |\|" and "\\ \' r. pure r \ Some \' = \ \ r \ \ b \ \ \ b \'" shows "mono_pure_cond b" using assms(1) assms(2) mono_pure_cond_def by blast lemma mono_pure_cond_conj: assumes "mono_pure_cond pc" and "mono_pure_cond b" shows "mono_pure_cond (bool_conj pc b)" proof (rule mono_pure_condI) show "\\. bool_conj pc b \ = bool_conj pc b |\|" by (metis assms(1) assms(2) bool_conj_def mono_pure_cond_def) show "\\ \' r. pure r \ Some \' = \ \ r \ \ bool_conj pc b \ \ \ bool_conj pc b \'" by (metis assms(1) assms(2) bool_conj_def mono_pure_cond_def) qed lemma bigger_sum: assumes "Some \ = a \ b" and "\' \ \" shows "\b'. b' \ b \ Some \' = a \ b'" proof - obtain r where "Some \' = \ \ r" using assms(2) greater_def by blast then obtain b' where "Some b' = b \ r" by (metis assms(1) asso2 domD domI domIff) then show ?thesis by (metis \Some \' = \ \ r\ assms(1) asso1 commutative sep_algebra.greater_equiv sep_algebra_axioms) qed lemma wf_assertion_sat_larger_pure: assumes "wf_assertion A" and "sat A \" and "Some \' = \ \ r" and "pure r" shows "sat A \'" using assms proof (induct arbitrary: \ \' r rule: wf_assertion.induct) case (1 A B) then obtain a b where "Some \ = a \ b" "sat A a" "sat B b" by (meson sat.simps(1)) then obtain b' where "Some b' = b \ r" by (metis "1.prems"(3) asso2 option.collapse) moreover obtain a' where "Some a' = a \ r" by (metis "1.prems"(3) \Some \ = a \ b\ asso2 commutative option.collapse) ultimately show ?case using 1 by (metis \Some \ = a \ b\ \sat A a\ \sat B b\ asso1 sat.simps(1) wf_assertion.simps(1)) next case (2 b A) then show ?case by (metis mono_pure_cond_def sat.simps(2) wf_assertion.simps(2)) next case (3 A) then show ?case by (metis mono_pruner_def sat.simps(3) wf_assertion.simps(3)) qed lemma package_satI: assumes "pc |a'| \ (\x. Some x = |a'| \ (u' \ u ) \ sat A x)" shows "package_sat pc A a' u' u" by (simp add: assms package_sat_def) lemma package_rhs_connection_instantiate: assumes "package_rhs_connection \ f S pc A \' f' S'" and "(a, u, T) \ S" obtains au where "Some au = a \ u" and "au ## (T f' \ T f) \ \a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u" using assms(1) assms(2) package_rhs_connection_def by fastforce lemma package_rhs_connectionI: assumes "\ \ f = \' \ f'" and "stable f'" and "\ ## f" and "f' \ f" and "\a u T. (a, u, T) \ S \ (\au. Some au = a \ u \ (au ## (T f' \ T f) \ (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u'\ u' \ u \ package_sat pc A a' u' u)))" shows "package_rhs_connection \ f S pc A \' f' S'" using package_rhs_connection_def assms by auto lemma valid_package_setI: assumes "\a u T. (a, u, T) \ S \ a ## u \ |a| \ |u| \ mono_transformer T \ a \ |T f| " shows "valid_package_set S f" using assms valid_package_set_def by auto lemma defined_sum_move: assumes "a ## b" and "Some b = x \ y" and "Some a' = a \ x" shows "a' ## y" by (metis assms defined_def sep_algebra.asso1 sep_algebra_axioms) lemma bigger_core_sum_defined: assumes "|a| \ b" shows "Some a = a \ b" by (metis (no_types, lifting) assms asso1 core_is_smaller greater_equiv max_projection_prop_pure_core mpp_prop pure_def pure_smaller) lemma package_rhs_proof: assumes "package_rhs \ f S pc A \' f' S'" and "valid_package_set S f" and "wf_assertion A" and "mono_pure_cond pc" and "stable f" and "\ ## f" shows "package_rhs_connection \ f S pc A \' f' S' \ valid_package_set S' f'" using assms proof (induct rule: package_rhs.induct) case (AImp \ f S pc b A \' f' S') then have asm0: "package_rhs_connection \ f S (bool_conj pc b) A \' f' S' \ valid_package_set S' f'" using mono_pure_cond_conj wf_assertion.simps(2) by blast let ?pc = "bool_conj pc b" obtain "\ \ f = \' \ f'" "stable f'" "\ ## f" "f' \ f" and \
: "\a u T. (a, u, T) \ S \ (\au. Some au = a \ u \ (au ## (T f' \ T f) \ (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat ?pc A a' u' u)))" using asm0 package_rhs_connection_def by force have "package_rhs_connection \ f S pc (AImp b A) \' f' S'" proof (rule package_rhs_connectionI) show "\ ## f" by (simp add: \\ ## f\) show "\ \ f = \' \ f'" by (simp add: \\ \ f = \' \ f'\) show "stable f'" using \stable f'\ by simp show "f' \ f" by (simp add: \f' \ f\) fix a u T assume asm1: "(a, u, T) \ S" then obtain au where asm2: "Some au = a \ u \ (au ## (T f' \ T f) \ (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat ?pc A a' u' u))" using \
by presburger then have "au ## (T f' \ T f) \ (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc (AImp b A) a' u' u)" proof - assume asm3: "au ## (T f' \ T f)" then obtain a' u' where au': "(a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat ?pc A a' u' u" using asm2 by blast have "(the ( |a'| \ (u' \ u))) \ |a'|" proof - have "u' \ u' \ u" by (metis minus_default minus_smaller succ_refl) then have "a' ## (u' \ u)" by (metis au' asm3 asso3 defined_def minus_exists) then show ?thesis by (metis core_is_smaller defined_def greater_def option.exhaust_sel sep_algebra.asso2 sep_algebra_axioms) qed have "package_sat pc (AImp b A) a' u' u" proof (rule package_satI) assume "pc |a'|" then show "\x. Some x = |a'| \ (u' \ u) \ sat (AImp b A) x" proof (cases "b |a'|") case True then have "?pc |a'|" by (simp add: \pc |a'|\ bool_conj_def) then show ?thesis by (metis au' package_logic.package_sat_def package_logic_axioms sat.simps(2)) next case False then have "\ b (the ( |a'| \ (u' \ u)))" using AImp.prems(2) \the ( |a'| \ (u' \ u)) \ |a'|\ core_sum max_projection_prop_def max_projection_prop_pure_core minus_exists mono_pure_cond_def wf_assertion.simps(2) by metis moreover obtain x where "Some x = |a'| \ (u' \ u)" by (metis au' asm3 asso2 commutative core_is_smaller defined_def minus_and_plus option.collapse) ultimately show ?thesis by (metis option.sel sat.simps(2)) qed qed then show "\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc (AImp b A) a' u' u" using au' by blast qed then show "\au. Some au = a \ u \ (au ## (T f' \ T f) \ (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc (AImp b A) a' u' u))" using asm2 by auto qed then show ?case using \package_rhs_connection \ f S (bool_conj pc b) A \' f' S' \ valid_package_set S' f'\ by blast next case (AStar \ f S pc A \' f' S' B \'' f'' S'') then have r1: "package_rhs_connection \ f S pc A \' f' S' \ valid_package_set S' f'" using wf_assertion.simps(1) by blast moreover have "\' ## f'" using r1 package_rhs_connection_def[of \ f S pc A \' f' S'] defined_def by fastforce ultimately have r2: "package_rhs_connection \' f' S' pc B \'' f'' S'' \ valid_package_set S'' f''" using AStar.hyps(4) AStar.prems(2) AStar.prems(3) package_rhs_connection_def by force moreover obtain fa_def: "\ \ f = \' \ f'" "stable f'" "\ ## f" "f' \ f" and **: "\a u T. (a, u, T) \ S \ (\au. Some au = a \ u \ (au ## (T f' \ T f) \ (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u)))" using r1 package_rhs_connection_def by fastforce then obtain fb_def: "\' \ f' = \'' \ f''" "stable f''" "\' ## f'" "f'' \ f'" and "\a u T. (a, u, T) \ S' \ (\au. Some au = a \ u \ (au ## (T f'' \ T f') \ (\a' u'. (a', u', T) \ S'' \ |a'| \ |a| \ au \ (T f'' \ T f') = a' \ u' \ u' \ u \ package_sat pc B a' u' u)))" using r2 package_rhs_connection_def by fastforce moreover have "package_rhs_connection \ f S pc (AStar A B) \'' f'' S''" proof (rule package_rhs_connectionI) show "\ \ f = \'' \ f''" by (simp add: fa_def(1) fb_def(1)) show "stable f''" by (simp add: fb_def(2)) show "\ ## f" using fa_def(3) by auto show "f'' \ f" using fa_def(4) fb_def(4) succ_trans by blast fix a u T assume asm0: "(a, u, T) \ S" then have f_def: "Some (T f'' \ T f) = (T f'' \ T f') \ (T f' \ T f)" proof - have "mono_transformer T" using valid_package_set_def asm0 \valid_package_set S f\ by fastforce then have "T f'' \ T f'" by (simp add: fb_def(4) mono_transformer_def) moreover have "T f' \ T f" using \mono_transformer T\ fa_def(4) mono_transformer_def by blast ultimately show ?thesis using commutative minus_and_plus minus_equiv_def by presburger qed then obtain au where au_def: "Some au = a \ u" "au ## (T f' \ T f) \ (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u)" - using \\u a T. (a, u, T) \ S \ \au. Some au = a \ u \ (au ## T f' \ T f \ (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u))\ asm0 by blast + using ** asm0 by blast then show "\au. Some au = a \ u \ (au ## (T f'' \ T f) \ (\a' u'. (a', u', T) \ S'' \ |a'| \ |a| \ au \ (T f'' \ T f) = a' \ u' \ u' \ u \ package_sat pc (AStar A B) a' u' u))" proof (cases "au ## (T f'' \ T f)") case True moreover have "mono_transformer T" using \valid_package_set S f\ valid_package_set_def asm0 by fastforce ultimately have "au ## (T f'' \ T f') \ au ## (T f' \ T f)" using asso3 commutative defined_def f_def by metis - then obtain a' u' where "(a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u" + then obtain a' u' where r3: "(a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u" using au_def(2) by blast then obtain au' where au'_def: "Some au' = a' \ u'" "au' ## (T f'' \ T f') \ (\a'' u''. (a'', u'', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u'' \ u'' \ u' \ package_sat pc B a'' u'' u')" - using \\u a T. (a, u, T) \ S' \ \au. Some au = a \ u \ (au ## T f'' \ T f' \ (\a' u'. (a', u', T) \ S'' \ |a'| \ |a| \ au \ (T f'' \ T f') = a' \ u' \ u' \ u \ package_sat pc B a' u' u))\ by blast + by (meson package_logic.package_rhs_connection_instantiate package_logic_axioms r2) moreover have "au' ## T f'' \ T f'" - using True \(a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u\ calculation(1) commutative defined_sum_move f_def by fastforce - ultimately obtain a'' u'' where "(a'', u'', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u'' \ u'' \ u' \ package_sat pc B a'' u'' u'" + using True r3 calculation(1) commutative defined_sum_move f_def by fastforce + ultimately obtain a'' u'' where r4: "(a'', u'', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u'' \ u'' \ u' \ package_sat pc B a'' u'' u'" by blast then have "au \ (T f'' \ T f) = a'' \ u''" proof - have "au \ (T f'' \ T f) = splus (Some au) (Some (T f'' \ T f))" by simp also have "... = splus (Some au) (splus (Some (T f'' \ T f')) (Some (T f' \ T f)))" using f_def by auto finally show ?thesis - by (metis (full_types) \(a'', u'', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u'' \ u'' \ u' \ package_sat pc B a'' u'' u'\ \(a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u\ au'_def(1) splus.simps(3) splus_asso splus_comm) + by (metis (full_types) r3 r4 au'_def(1) splus.simps(3) splus_asso splus_comm) qed moreover have "package_sat pc (AStar A B) a'' u'' u" proof (rule package_satI) assume "pc |a''|" then have "pc |a'|" - by (metis AStar.prems(3) \(a'', u'', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u'' \ u'' \ u' \ package_sat pc B a'' u'' u'\ greater_equiv minus_core minus_core_weaker minus_equiv_def mono_pure_cond_def pure_def) + by (metis AStar.prems(3) r4 greater_equiv minus_core minus_core_weaker minus_equiv_def mono_pure_cond_def pure_def) then obtain x where "Some x = |a'| \ (u' \ u) \ sat A x" - using \(a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u\ package_sat_def by fastforce + using r3 package_sat_def by fastforce then obtain x' where "Some x' = |a''| \ (u'' \ u') \ sat B x'" - using \(a'', u'', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u'' \ u'' \ u' \ package_sat pc B a'' u'' u'\ \pc |a''|\ package_sat_def by auto + using \pc |a''|\ package_sat_def r4 by presburger + have "u'' \ u'' \ u" by (metis minus_default minus_smaller succ_refl) moreover have "a'' ## u''" using True \au \ (T f'' \ T f) = a'' \ u''\ defined_def by auto ultimately obtain x'' where "Some x'' = |a''| \ (u'' \ u)" by (metis commutative defined_def max_projection_prop_pure_core mpp_smaller not_None_eq smaller_compatible) moreover have "Some (u'' \ u) = (u'' \ u') \ (u' \ u)" - using \(a'', u'', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u'' \ u'' \ u' \ package_sat pc B a'' u'' u'\ \(a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u\ commutative minus_and_plus minus_equiv_def by presburger + using r4 \(a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u\ commutative minus_and_plus minus_equiv_def by presburger moreover have "|a''| \ |a'|" - using \(a'', u'', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u'' \ u'' \ u' \ package_sat pc B a'' u'' u'\ by blast + using r4 by blast moreover have "Some |a''| = |a'| \ |a''|" by (metis (no_types, lifting) calculation(3) core_is_pure sep_algebra.asso1 sep_algebra.minus_exists sep_algebra_axioms) ultimately have "Some x'' = x' \ x" using asso1[of _ _ x'] \Some x = |a'| \ (u' \ u) \ sat A x\ \Some x' = |a''| \ (u'' \ u') \ sat B x'\ commutative by metis then show "\x. Some x = |a''| \ (u'' \ u) \ sat (AStar A B) x" using \Some x = |a'| \ (u' \ u) \ sat A x\ \Some x' = |a''| \ (u'' \ u') \ sat B x'\ \Some x'' = |a''| \ (u'' \ u)\ commutative by fastforce qed ultimately show ?thesis - using \(a'', u'', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u'' \ u'' \ u' \ package_sat pc B a'' u'' u'\ \(a', u', T) \ S' \ |a'| \ |a| \ au \ (T f' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u\ au_def(1) succ_trans by blast + using r3 r4 au_def(1) succ_trans by blast next case False then show ?thesis using au_def(1) by blast qed qed ultimately show ?case by blast next case (ASem S pc witness B S' \ f) have "valid_package_set S' f" proof (rule valid_package_setI) fix a' u' T assume asm0: "(a', u', T) \ S'" then show "a' ## u' \ |a'| \ |u'| \ mono_transformer T \ a' \ |T f|" proof (cases "(a', u', T) \ S") case True then show ?thesis using ASem.prems(1) valid_package_set_def by auto next case False then have "(a', u', T) \ {(a \ b, the (u \ b), T) |a u T b. (a, u, T) \ S \ pc a \ b = witness (a, u, T)}" using ASem.hyps(2) asm0 by blast then obtain a u b where "(a, u, T) \ S" "pc a" "b = witness (a, u, T)" "a' = a \ b" "u' = the (u \ b)" by blast then have "a \ b \ B b" using ASem.hyps(1) by presburger have "a ## u" using ASem.prems(1) \(a, u, T) \ S\ valid_package_set_def by fastforce then have "Some u' = u \ b" by (metis \a \ b \ B b\ \u' = the (u \ b)\ commutative defined_def option.exhaust_sel smaller_compatible) moreover have "Some a = a' \ b" using \a \ b \ B b\ \a' = a \ b\ commutative minus_equiv_def by presburger ultimately have "a' ## u'" by (metis \a ## u\ asso1 commutative defined_def) moreover have "|a'| \ |u'|" proof - have "|a| \ |u|" using ASem.prems(1) \(a, u, T) \ S\ valid_package_set_def by fastforce moreover have "|a'| \ |a|" by (simp add: \a' = a \ b\ minus_core succ_refl) moreover have "|a'| \ |b|" using \a \ b \ B b\ \a' = a \ b\ max_projection_prop_pure_core minus_core mpp_mono by presburger ultimately show ?thesis by (metis \Some u' = u \ b\ \a' = a \ b\ core_is_pure core_sum minus_core pure_def smaller_pure_sum_smaller) qed moreover have "a' \ |T f|" proof - have "a \ |T f|" using \(a, u, T) \ S\ \valid_package_set S f\ valid_package_set_def by fastforce then show ?thesis by (metis \a' = a \ b\ max_projection_prop_pure_core minus_core mpp_mono mpp_smaller sep_algebra.mpp_invo sep_algebra.succ_trans sep_algebra_axioms) qed ultimately show ?thesis using \(a, u, T) \ S\ \valid_package_set S f\ valid_package_set_def by fastforce qed qed moreover have "package_rhs_connection \ f S pc (ASem B) \ f S'" proof (rule package_rhs_connectionI) show "\ \ f = \ \ f" by simp show "stable f" by (simp add: ASem.prems(4)) show "\ ## f" by (simp add: ASem.prems(5)) show "f \ f" by (simp add: succ_refl) fix a u T assume asm0: "(a, u, T) \ S" then obtain au where "Some au = a \ u" using \valid_package_set S f\ valid_package_set_def defined_def by auto - then have "(\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ Some au = a' \ u' \ u' \ u \ package_sat pc (ASem B) a' u' u)" + then have r0: "(\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ Some au = a' \ u' \ u' \ u \ package_sat pc (ASem B) a' u' u)" proof - let ?b = "witness (a, u, T)" let ?a = "a \ ?b" let ?u = "the (u \ ?b)" show "\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ Some au = a' \ u' \ u' \ u \ package_sat pc (ASem B) a' u' u" proof (cases "pc a") case True then have "(?a, ?u, T) \ S'" using ASem.hyps(2) asm0 by blast then have "a \ ?b \ B ?b" using ASem.hyps(1) True asm0 by blast - moreover have "(?a, ?u, T) \ S' \ |?a| \ |a| \ Some au = ?a \ ?u \ ?u \ u" + moreover have r1: "(?a, ?u, T) \ S' \ |?a| \ |a| \ Some au = ?a \ ?u \ ?u \ u" proof show "(a \ witness (a, u, T), the (u \ witness (a, u, T)), T) \ S'" by (simp add: \(a \ witness (a, u, T), the (u \ witness (a, u, T)), T) \ S'\) have "|a \ witness (a, u, T)| \ |a| " by (simp add: minus_core succ_refl) moreover have "Some au = a \ witness (a, u, T) \ the (u \ witness (a, u, T))" using \Some au = a \ u\ \a \ witness (a, u, T) \ B (witness (a, u, T))\ asso1[of "a \ witness (a, u, T)" "witness (a, u, T)" a u "the (u \ witness (a, u, T))"] commutative option.distinct(1) option.exhaust_sel asso3 minus_equiv_def by metis moreover have "the (u \ witness (a, u, T)) \ u" using \Some au = a \ u\ \a \ witness (a, u, T) \ B (witness (a, u, T))\ commutative greater_def option.distinct(1) option.exhaust_sel asso3[of u "witness (a, u, T)" ] by metis ultimately show "|a \ witness (a, u, T)| \ |a| \ Some au = a \ witness (a, u, T) \ the (u \ witness (a, u, T)) \ the (u \ witness (a, u, T)) \ u" by blast qed moreover have "package_sat pc (ASem B) ?a ?u u" proof (rule package_satI) assume "pc |a \ witness (a, u, T)|" have "Some ?u = u \ ?b" by (metis (no_types, lifting) \Some au = a \ u\ calculation(1) commutative minus_equiv_def option.distinct(1) option.exhaust_sel sep_algebra.asso3 sep_algebra_axioms) moreover have "?a ## ?u" - by (metis \(a \ witness (a, u, T), the (u \ witness (a, u, T)), T) \ S' \ |a \ witness (a, u, T)| \ |a| \ Some au = a \ witness (a, u, T) \ the (u \ witness (a, u, T)) \ the (u \ witness (a, u, T)) \ u\ defined_def option.distinct(1)) + by (metis r1 defined_def option.distinct(1)) moreover have "?u \ ?u \ u" - using \(a \ witness (a, u, T), the (u \ witness (a, u, T)), T) \ S' \ |a \ witness (a, u, T)| \ |a| \ Some au = a \ witness (a, u, T) \ the (u \ witness (a, u, T)) \ the (u \ witness (a, u, T)) \ u\ minus_smaller by blast + using r1 minus_smaller by blast ultimately obtain x where "Some x = |a \ ?b| \ (?u \ u)" by (metis (no_types, opaque_lifting) \a \ witness (a, u, T) \ B (witness (a, u, T))\ commutative defined_def minus_core minus_equiv_def option.exhaust smaller_compatible) moreover have "x \ ?b" proof - have "?u \ u \ ?b" using \Some (the (u \ witness (a, u, T))) = u \ witness (a, u, T)\ minus_bigger by blast then show ?thesis using calculation greater_equiv succ_trans by blast qed ultimately show "\x. Some x = |a \ witness (a, u, T)| \ (the (u \ witness (a, u, T)) \ u) \ sat (ASem B) x" using ASem.prems(2) \Some (the (u \ witness (a, u, T))) = u \ witness (a, u, T)\ \a \ witness (a, u, T) \ B (witness (a, u, T))\ commutative max_projection_prop_def[of pure core] max_projection_prop_pure_core minus_equiv_def_any_elem mono_pruner_def[of B] sat.simps(3)[of B] wf_assertion.simps(3)[of B] by metis qed ultimately show ?thesis by blast next case False then have "package_sat pc (ASem B) a u u" by (metis ASem.prems(3) mono_pure_cond_def package_sat_def) moreover have "(a, u, T) \ S'" using False ASem.hyps(2) asm0 by blast ultimately show ?thesis using \Some au = a \ u\ succ_refl by blast qed qed moreover have "au \ (T f \ T f) = Some au" proof - have "a \ |T f|" using \(a, u, T) \ S\ \valid_package_set S f\ valid_package_set_def by fastforce then have "|a| \ T f \ T f" using core_is_smaller max_projection_prop_def max_projection_prop_pure_core minusI by presburger then have "|au| \ T f \ T f" using \Some au = a \ u\ core_sum greater_def succ_trans by blast then show ?thesis using bigger_core_sum_defined by force qed ultimately show "\au. Some au = a \ u \ (au ## (T f \ T f) \ (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f \ T f) = a' \ u' \ u' \ u \ package_sat pc (ASem B) a' u' u))" using \Some au = a \ u\ by fastforce qed ultimately show ?case by blast next case (AddFromOutside \ \' m f' S' pc A \'' f'' S'' f S) have "valid_package_set S' f'" proof (rule valid_package_setI) fix a' u T assume asm0: "(a', u, T) \ S'" then obtain a where "(a, u, T) \ S" "a' ## u" "Some a' = a \ (T f' \ T f)" using AddFromOutside.hyps(6) by blast then have "|a| \ |u| \ mono_transformer T \ a \ |T f|" using \valid_package_set S f\ valid_package_set_def by fastforce moreover have "a' \ |T f'|" by (metis (no_types, opaque_lifting) \Some a' = a \ (T f' \ T f)\ commutative greater_equiv minus_core minus_equiv_def minus_smaller succ_trans unit_neutral) ultimately show "a' ## u \ |a'| \ |u| \ mono_transformer T \ a' \ |T f'|" using \Some a' = a \ (T f' \ T f)\ \a' ## u\ greater_def max_projection_prop_pure_core mpp_mono succ_trans by blast qed then have r: "package_rhs_connection \' f' S' pc A \'' f'' S'' \ valid_package_set S'' f''" by (metis AddFromOutside.hyps(1) AddFromOutside.hyps(3) AddFromOutside.hyps(4) AddFromOutside.hyps(5) AddFromOutside.prems(2) AddFromOutside.prems(3) AddFromOutside.prems(4) AddFromOutside.prems(5) asso1 commutative defined_def stable_sum) then obtain r2: "\' \ f' = \'' \ f''" "stable f''" "\' ## f'" "f'' \ f'" "\a u T. (a, u, T) \ S' \ (\au. Some au = a \ u \ (au ## (T f'' \ T f') \ (\a' u'. (a', u', T) \ S'' \ |a'| \ |a| \ au \ (T f'' \ T f') = a' \ u' \ u' \ u \ package_sat pc A a' u' u)))" using package_rhs_connection_def by fastforce moreover have "package_rhs_connection \ f S pc A \'' f'' S''" proof (rule package_rhs_connectionI) show "\ \ f = \'' \ f''" by (metis AddFromOutside.hyps(1) AddFromOutside.hyps(5) asso1 commutative r2(1)) show "stable f''" using AddFromOutside.hyps(4) calculation(4) r2(2) stable_sum by blast show "\ ## f" by (simp add: AddFromOutside.prems(5)) show "f'' \ f" using AddFromOutside.hyps(5) bigger_sum greater_def r2(4) by blast fix a u T assume asm0: "(a, u, T) \ S" then obtain au where "Some au = a \ u" using \valid_package_set S f\ valid_package_set_def defined_def by fastforce moreover have "au ## (T f'' \ T f) \ (\a' u'. (a', u', T) \ S'' \ |a'| \ |a| \ au \ (T f'' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u)" proof - assume asm1: "au ## (T f'' \ T f)" moreover have "mono_transformer T" using \valid_package_set S f\ valid_package_set_def asm0 by fastforce then have "Some (T f'' \ T f) = (T f'' \ T f') \ (T f' \ T f)" by (metis AddFromOutside.hyps(5) commutative greater_equiv minus_and_plus minus_equiv_def mono_transformer_def r2(4)) ultimately have "a ## (T f' \ T f)" using \Some au = a \ u\ asso2 commutative defined_def minus_exists by metis then obtain a' where "Some a' = a \ (T f' \ T f)" by (meson defined_def option.collapse) moreover have "a' ## u" proof - have "T f'' \ T f \ T f' \ T f" using \Some (T f'' \ T f) = T f'' \ T f' \ (T f' \ T f)\ greater_equiv by blast then show ?thesis using \Some au = a \ u\ asm1 asso1[of u a au "T f' \ T f" a'] asso2[of ] calculation commutative defined_def[of ] greater_equiv[of "T f'' \ T f" "T f' \ T f"] by metis qed ultimately have "(a', u, T) \ S'" using AddFromOutside.hyps(6) asm0 by blast moreover have "au ## (T f'' \ T f')" by (metis \Some (T f'' \ T f) = T f'' \ T f' \ (T f' \ T f)\ asm1 asso3 defined_def) then have "\au. Some au = a' \ u \ (au ## (T f'' \ T f') \ (\a'a u'. (a'a, u', T) \ S'' \ |a'a| \ |a'| \ au \ (T f'' \ T f') = a'a \ u' \ u' \ u \ package_sat pc A a'a u' u))" using r2(5) calculation by blast then obtain au' a'' u' where r3: "Some au' = a' \ u" "au' ## (T f'' \ T f') \ (a'', u', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u' \ u' \ u \ package_sat pc A a'' u' u" using \au ## (T f'' \ T f')\ by blast moreover have "au' ## (T f'' \ T f')" using \au ## (T f'' \ T f)\ \Some au = a \ u\ r3(1) \Some (T f'' \ T f) = (T f'' \ T f') \ (T f' \ T f)\ \Some a' = a \ (T f' \ T f)\ asso1[of u a au "T f' \ T f" a'] commutative defined_sum_move[of au "T f'' \ T f"] by metis ultimately have r4: "(a'', u', T) \ S'' \ |a''| \ |a'| \ au' \ (T f'' \ T f') = a'' \ u' \ u' \ u \ package_sat pc A a'' u' u" by blast moreover have "|a''| \ |a|" proof - have "|a'| \ |a|" using \Some a' = a \ (T f' \ T f)\ core_sum greater_def by blast then show ?thesis using r4 succ_trans by blast qed ultimately show "\a' u'. (a', u', T) \ S'' \ |a'| \ |a| \ au \ (T f'' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u" using \Some (T f'' \ T f) = T f'' \ T f' \ (T f' \ T f)\ \Some a' = a \ (T f' \ T f)\ \Some au = a \ u\ commutative r3(1) asso1 splus.simps(3) splus_asso by metis qed ultimately show "\au. Some au = a \ u \ (au ## (T f'' \ T f) \ (\a' u'. (a', u', T) \ S'' \ |a'| \ |a| \ au \ (T f'' \ T f) = a' \ u' \ u' \ u \ package_sat pc A a' u' u))" by blast qed ultimately show ?case using r by blast qed lemma unit_core: "|unit| = unit" by (meson core_is_pure max_projection_prop_pure_core sep_algebra.cancellative sep_algebra.mpp_invo sep_algebra_axioms unit_neutral) lemma unit_smaller: "\ \ unit" using greater_equiv unit_neutral by auto subsection \Lemmas for completeness\ lemma sat_star_exists_bigger: assumes "sat (AStar A B) \" and "wf_assertion A" and "wf_assertion B" shows "\a b. |a| \ |\| \ |b| \ |\| \ Some \ = a \ b \ sat A a \ sat B b" proof - - obtain a b where "Some \ = a \ b \ sat A a \ sat B b" + obtain a b where "Some \ = a \ b" "sat A a" "sat B b" using assms sat.simps(1) by blast then obtain a' b' where "Some a' = a \ |\|" "Some b' = b \ |\|" by (meson defined_def greater_def greater_equiv option.collapse smaller_compatible_core) then have "a' \ a \ b' \ b" using greater_def by blast then have "sat A a' \ sat B b'" - using \Some \ = a \ b \ sat A a \ sat B b\ \Some a' = a \ |\|\ \Some b' = b \ |\|\ assms(2) assms(3) core_is_pure pure_def wf_assertion_sat_larger_pure by blast + by (metis \Some a' = a \ |\|\ \Some b' = b \ |\|\ \sat A a\ \sat B b\ assms(2) assms(3) max_projection_prop_pure_core mpp_prop package_logic.wf_assertion_sat_larger_pure package_logic_axioms) moreover have "Some \ = a' \ b'" - by (metis (no_types, lifting) \Some \ = a \ b \ sat A a \ sat B b\ \Some a' = a \ |\|\ \Some b' = b \ |\|\ asso1 commutative core_is_smaller) + by (metis (no_types, lifting) \Some \ = a \ b\ \Some a' = a \ |\|\ \Some b' = b \ |\|\ asso1 commutative core_is_smaller) ultimately show ?thesis - by (metis \Some \ = a \ b \ sat A a \ sat B b\ \Some a' = a \ |\|\ \Some b' = b \ |\|\ commutative greater_def smaller_than_core succ_refl) + by (metis \Some a' = a \ |\|\ \Some b' = b \ |\|\ commutative extract_core greater_equiv max_projection_prop_pure_core mpp_mono) qed lemma let_pair_instantiate: assumes "(a, b) = f x y" shows "(let (a, b) = f x y in g a b) = g a b" by (metis assms case_prod_conv) lemma greater_than_sum_exists: assumes "a \ b" and "Some b = b1 \ b2" shows "\r. Some a = r \ b2 \ |r| \ |a| \ r \ b1" proof - obtain r where "Some a = r \ b2 \ r \ b1" by (metis assms(1) assms(2) bigger_sum commutative) then obtain r' where "Some r' = r \ |a|" by (metis defined_def greater_def option.exhaust smaller_compatible_core) then have "Some a = r' \ b2" by (metis \Some a = r \ b2 \ r \ b1\ commutative core_is_smaller sep_algebra.asso1 sep_algebra_axioms) then show ?thesis by (metis \Some a = r \ b2 \ r \ b1\ \Some r' = r \ |a|\ core_is_pure greater_def smaller_than_core succ_trans) qed lemma bigger_the: assumes "Some a = x' \ y" and "x' \ x" shows "the ( |a| \ x') \ the ( |a| \ x)" proof - have "a \ x'" using assms(1) greater_def by blast then have "|a| ## x'" using commutative defined_def smaller_compatible_core by auto moreover have "|a| ## x" by (metis assms(2) calculation defined_def sep_algebra.asso3 sep_algebra.minus_exists sep_algebra_axioms) ultimately show ?thesis using addition_bigger assms(2) commutative defined_def by force qed lemma wf_assertion_and_the: assumes "|a| ## b" and "sat A b" and "wf_assertion A" shows "sat A (the ( |a| \ b))" by (metis assms(1) assms(2) assms(3) commutative defined_def max_projection_prop_pure_core option.collapse sep_algebra.mpp_prop sep_algebra_axioms wf_assertion_sat_larger_pure) lemma minus_some: assumes "a \ b" shows "Some a = b \ (a \ b)" using assms commutative minus_equiv_def by force lemma core_mono: assumes "a \ b" shows "|a| \ |b|" using assms max_projection_prop_pure_core mpp_mono by auto lemma prove_last_completeness: assumes "a' \ a" and "Some a = nf1 \ f2" shows "a' \ nf1 \ f2" by (meson assms(1) assms(2) greater_def greater_minus_trans minus_bigger succ_trans) lemma completeness_aux: assumes "\a u T. (a, u, T) \ S \ |f1 a u T| \ |a| \ Some a = f1 a u T \ f2 a u T \ (pc |a| \ sat A (the ( |a| \ (f1 a u T))))" and "valid_package_set S f" and "wf_assertion A" and "mono_pure_cond pc" and "stable f \ \ ## f" shows "\S'. package_rhs \ f S pc A \ f S' \ (\(a', u', T) \ S'. \a u. (a, u, T) \ S \ a' \ f2 a u T \ |a'| = |a| )" using assms proof (induct A arbitrary: S pc f1 f2) case (AImp b A) let ?pc = "bool_conj pc b" - have "\S'. package_rhs \ f S (bool_conj pc b) A \ f S' \ (\a\S'. case a of (a', u', T) \ \a u. (a, u, T) \ S \ a' \ f2 a u T \ |a'| = |a| )" + have r0: "\S'. package_rhs \ f S (bool_conj pc b) A \ f S' \ (\a\S'. case a of (a', u', T) \ \a u. (a, u, T) \ S \ a' \ f2 a u T \ |a'| = |a| )" proof (rule AImp(1)) show "valid_package_set S f" by (simp add: AImp.prems(2)) show "wf_assertion A" using AImp.prems(3) by auto show "mono_pure_cond (bool_conj pc b)" by (meson AImp.prems(3) AImp.prems(4) mono_pure_cond_conj wf_assertion.simps(2)) show "stable f \ \ ## f" using \stable f \ \ ## f\ by simp fix a u T - assume asm0: "(a, u, T) \ S" + assume asm0: "(a, u, T) \ S" then have "Some a = f1 a u T \ f2 a u T" using AImp.prems(1) by blast moreover have "bool_conj pc b |a| \ sat A (the ( |a| \ f1 a u T))" proof - assume "bool_conj pc b |a|" then have "pc |a|" by (meson bool_conj_def) then have "|f1 a u T| \ |a| \ Some a = f1 a u T \ f2 a u T \ sat (AImp b A) (the ( |a| \ f1 a u T))" using AImp.prems(1) asm0(1) by blast moreover have "b (the ( |a| \ f1 a u T))" proof - have "|a| ## f1 a u T \ |a| \ |f1 a u T|" by (metis calculation commutative core_is_smaller defined_def greater_def max_projection_prop_pure_core mpp_mono option.discI succ_antisym) then obtain x where "Some x = |a| \ f1 a u T" by (meson defined_def option.collapse) then have "|x| = |a|" by (metis \Some x = |a| \ f1 a u T\ \|a| ## f1 a u T \ |a| \ |f1 a u T|\ commutative core_is_pure core_sum max_projection_prop_pure_core mpp_smaller smaller_than_core) then show ?thesis by (metis AImp.prems(3) \Some x = |a| \ f1 a u T\ \bool_conj pc b |a|\ bool_conj_def mono_pure_cond_def option.sel wf_assertion.simps(2)) qed ultimately show "sat A (the ( |a| \ f1 a u T))" by (metis sat.simps(2)) qed ultimately show "|f1 a u T| \ |a| \ Some a = f1 a u T \ f2 a u T \ (bool_conj pc b |a| \ sat A (the ( |a| \ f1 a u T)))" by (metis AImp.prems(1) asm0) qed then obtain S' where r: "package_rhs \ f S (bool_conj pc b) A \ f S'" "\a' u' T. (a', u', T) \ S' \ (\a u. (a, u, T) \ S \ a' \ f2 a u T)" by fast moreover have "package_rhs \ f S pc (AImp b A) \ f S'" by (simp add: package_rhs.AImp r(1)) ultimately show ?case - using \\S'. package_rhs \ f S (bool_conj pc b) A \ f S' \ (\a\S'. case a of (a', u', T) \ \a u. (a, u, T) \ S \ a' \ f2 a u T \ |a'| = |a| )\ package_rhs.AImp by blast + using r0 package_rhs.AImp by blast next case (ASem A) let ?witness = "\(a, u, T). the ( |a| \ f1 a u T)" obtain S' where S'_def: "S' = { (a, u, T) |a u T. (a, u, T) \ S \ \ pc a } \ { (a \ b, the (u \ b), T) |a u T b. (a, u, T) \ S \ pc a \ b = ?witness (a, u, T) }" by blast have "package_rhs \ f S pc (ASem A) \ f S'" proof (rule package_rhs.ASem) show "S' = {(a, u, T) |a u T. (a, u, T) \ S \ \ pc a} \ {(a \ b, the (u \ b), T) |a u T b. (a, u, T) \ S \ pc a \ b = ?witness (a, u, T)}" using S'_def by blast fix a u T b assume asm0: "(a, u, T) \ S" "pc a" "b = (case (a, u, T) of (a, u, T) \ the ( |a| \ f1 a u T))" then have "b = the ( |a| \ f1 a u T)" by fastforce moreover have "pc |a|" by (meson ASem.prems(4) asm0(2) mono_pure_cond_def) - then have "|f1 a u T| \ |a| \ Some a = f1 a u T \ f2 a u T \ sat (ASem A) (the ( |a| \ f1 a u T))" + then obtain "|f1 a u T| \ |a|" "Some a = f1 a u T \ f2 a u T" "sat (ASem A) (the ( |a| \ f1 a u T))" using ASem.prems(1) asm0(1) by blast then have "Some b = |a| \ f1 a u T" by (metis calculation commutative defined_def minus_bigger minus_core option.exhaust_sel smaller_compatible_core) moreover have "a \ b" proof - have "a \ f1 a u T" - using \|f1 a u T| \ |a| \ Some a = f1 a u T \ f2 a u T \ sat (ASem A) (the ( |a| \ f1 a u T))\ asso1 calculation(2) commutative core_is_smaller greater_def by metis + using \Some a = f1 a u T \ f2 a u T\ greater_def by blast then show ?thesis by (metis calculation(2) commutative max_projection_prop_pure_core mpp_smaller sep_algebra.mpp_prop sep_algebra_axioms smaller_pure_sum_smaller) qed ultimately show "a \ b \ A b" - using \|f1 a u T| \ |a| \ Some a = f1 a u T \ f2 a u T \ sat (ASem A) (the ( |a| \ f1 a u T))\ commutative greater_def max_projection_prop_def max_projection_prop_pure_core sat.simps(3) smaller_pure_sum_smaller - by metis + using \sat (ASem A) (the ( |a| \ f1 a u T))\ sat.simps(3) by blast qed - moreover have "\a' u' T. (a', u', T) \ S' \ (\a u. (a, u, T) \ S \ a' \ f2 a u T \ |a'| = |a| )" + moreover have r0: "\a' u' T. (a', u', T) \ S' \ (\a u. (a, u, T) \ S \ a' \ f2 a u T \ |a'| = |a| )" proof - fix a' u' T assume asm0: "(a', u', T) \ S'" then show "\a u. (a, u, T) \ S \ a' \ f2 a u T \ |a'| = |a| " proof (cases "(a', u', T) \ {(a, u, T) |a u T. (a, u, T) \ S \ \ pc a}") case True then show ?thesis using ASem.prems(1) greater_equiv by fastforce next case False then have "(a', u', T) \ { (a \ b, the (u \ b), T) |a u T b. (a, u, T) \ S \ pc a \ b = ?witness (a, u, T) }" using S'_def asm0 by blast then obtain a u b where "a' = a \ b" "u' = the (u \ b)" "(a, u, T) \ S" "pc a" "b = ?witness (a, u, T)" by blast then have "a' \ f2 a u T" proof - have "a \ b" proof - have "a \ f1 a u T" using ASem.prems(1) \(a, u, T) \ S\ greater_def by blast moreover have "Some b = |a| \ f1 a u T" by (metis \b = (case (a, u, T) of (a, u, T) \ the ( |a| \ f1 a u T))\ calculation case_prod_conv commutative defined_def option.exhaust_sel smaller_compatible_core) ultimately show ?thesis by (metis commutative max_projection_prop_pure_core mpp_smaller sep_algebra.mpp_prop sep_algebra_axioms smaller_pure_sum_smaller) qed then show ?thesis using ASem.prems(1)[of a u T] \(a, u, T) \ S\ \a' = a \ b\ \b = (case (a, u, T) of (a, u, T) \ the ( |a| \ f1 a u T))\ commutative core_is_smaller minus_bigger option.exhaust_sel option.simps(3) asso1[of "f2 a u T" "f1 a u T" a "|a|" "the ( |a| \ f1 a u T)"] asso2[of "f2 a u T" "f1 a u T"] split_conv by metis qed then show ?thesis using \(a, u, T) \ S\ \a' = a \ b\ minus_core by blast qed qed ultimately show ?case by blast next case (AStar A B) let ?fA = "\a u T. SOME x. \y. Some (f1 a u T) = x \ y \ |x| \ |f1 a u T| \ |y| \ |a| \ (pc |a| \ sat A (the ( |a| \ x)) \ sat B (the ( |a| \ y)))" let ?fB = "\a u T. SOME y. Some (f1 a u T) = ?fA a u T \ y \ |y| \ |a| \ (pc |a| \ sat B (the ( |a| \ y)))" let ?f2 = "\a u T. the (?fB a u T \ f2 a u T)" have r: "\a u T. (a, u, T) \ S \ Some (f1 a u T) = ?fA a u T \ ?fB a u T \ |?fA a u T| \ |f1 a u T| \ |?fB a u T| \ |a| \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ ?fB a u T))) \ Some (?f2 a u T) = ?fB a u T \ f2 a u T" proof - fix a u T assume asm0: "(a, u, T) \ S" - then have "Some a = f1 a u T \ f2 a u T \ (pc |a| \ sat (AStar A B) (the ( |a| \ f1 a u T)))" + then have r0: "Some a = f1 a u T \ f2 a u T \ (pc |a| \ sat (AStar A B) (the ( |a| \ f1 a u T)))" using AStar.prems(1) by blast then have "\x y. Some (the ( |a| \ f1 a u T )) = x \ y \ (pc |a| \ sat A x) \ (pc |a| \ sat B y) \ x \ |(the ( |a| \ f1 a u T))| \ y \ |(the ( |a| \ f1 a u T))|" proof (cases "pc |a|") case True then show ?thesis - using AStar.prems(3) \Some a = f1 a u T \ f2 a u T \ (pc |a| \ sat (AStar A B) (the ( |a| \ f1 a u T)))\ + using AStar.prems(3) r0 max_projection_prop_def[of pure core] max_projection_prop_pure_core sat_star_exists_bigger[of A B "(the ( |a| \ f1 a u T))"] succ_trans[of ] wf_assertion.simps(1)[of A B] by blast next case False then have "Some (the ( |a| \ f1 a u T )) = the ( |a| \ f1 a u T) \ |the ( |a| \ f1 a u T )|" by (simp add: core_is_smaller) then show ?thesis by (metis False max_projection_prop_pure_core mpp_smaller succ_refl) qed then obtain x y where "Some (the ( |a| \ f1 a u T)) = x \ y" "pc |a| \ sat A x" "pc |a| \ sat B y" "x \ |(the ( |a| \ f1 a u T))|" "y \ |(the ( |a| \ f1 a u T))|" by blast moreover obtain af where "Some af = |a| \ f1 a u T" - by (metis \Some a = f1 a u T \ f2 a u T \ (pc |a| \ sat (AStar A B) (the ( |a| \ f1 a u T)))\ commutative defined_def minus_bigger minus_core option.exhaust_sel smaller_compatible_core) + by (metis r0 commutative defined_def minus_bigger minus_core option.exhaust_sel smaller_compatible_core) ultimately have "Some (f1 a u T) = x \ y" - by (metis AStar.prems(1) \Some a = f1 a u T \ f2 a u T \ (pc |a| \ sat (AStar A B) (the ( |a| \ f1 a u T)))\ asm0 commutative core_is_smaller greater_def max_projection_prop_pure_core mpp_mono option.sel succ_antisym) + by (metis AStar.prems(1) r0 asm0 commutative core_is_smaller greater_def max_projection_prop_pure_core mpp_mono option.sel succ_antisym) moreover have "|a| ## x \ |a| ## y" by (metis \Some af = |a| \ f1 a u T\ calculation commutative defined_def option.discI sep_algebra.asso3 sep_algebra_axioms) then have "the ( |a| \ x) \ x \ the ( |a| \ y) \ y" using commutative defined_def greater_def by auto - ultimately have "pc |a| \ sat A (the ( |a| \ x)) \ sat B (the ( |a| \ y))" + ultimately have pc_implies_sat: "pc |a| \ sat A (the ( |a| \ x)) \ sat B (the ( |a| \ y))" by (metis AStar.prems(3) \pc |a| \ sat A x\ \pc |a| \ sat B y\ \|a| ## x \ |a| ## y\ commutative defined_def max_projection_prop_pure_core option.exhaust_sel package_logic.wf_assertion.simps(1) package_logic_axioms sep_algebra.mpp_prop sep_algebra_axioms wf_assertion_sat_larger_pure) - have "\y. Some (f1 a u T) = ?fA a u T \ y \ |?fA a u T| \ |f1 a u T| \ |y| \ |a| \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ y)))" + have r1: "\y. Some (f1 a u T) = ?fA a u T \ y \ |?fA a u T| \ |f1 a u T| \ |y| \ |a| \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ y)))" proof (rule someI_ex) show "\x y. Some (f1 a u T) = x \ y \ |x| \ |f1 a u T| \ |y| \ |a| \ (pc |a| \ sat A (the ( |a| \ x)) \ sat B (the ( |a| \ y)))" - using \Some (f1 a u T) = x \ y\ \Some (the ( |a| \ f1 a u T)) = x \ y\ \pc |a| \ sat A (the ( |a| \ x)) \ sat B (the ( |a| \ y))\ \x \ |the ( |a| \ f1 a u T)|\ \y \ |the ( |a| \ f1 a u T)|\ core_is_pure max_projection_propE(3) max_projection_prop_pure_core option.sel pure_def + using \Some (f1 a u T) = x \ y\ \Some (the ( |a| \ f1 a u T)) = x \ y\ pc_implies_sat \x \ |the ( |a| \ f1 a u T)|\ \y \ |the ( |a| \ f1 a u T)|\ core_is_pure max_projection_propE(3) max_projection_prop_pure_core option.sel pure_def by (metis AStar.prems(1) asm0 minusI minus_core) qed - then obtain yy where "Some (f1 a u T) = ?fA a u T \ yy \ |?fA a u T| \ |f1 a u T| \ |yy| \ |a| \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ yy)))" + then obtain yy where yy_prop: "Some (f1 a u T) = ?fA a u T \ yy \ |?fA a u T| \ |f1 a u T| \ |yy| \ |a| \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ yy)))" by blast - moreover have "Some (f1 a u T) = ?fA a u T \ ?fB a u T \ |?fB a u T| \ |a| \ (pc |a| \ sat B (the ( |a| \ ?fB a u T)))" + moreover have r2: "Some (f1 a u T) = ?fA a u T \ ?fB a u T \ |?fB a u T| \ |a| \ (pc |a| \ sat B (the ( |a| \ ?fB a u T)))" proof (rule someI_ex) show "\y. Some (f1 a u T) = ?fA a u T \ y \ |y| \ |a| \ (pc |a| \ sat B (the ( |a| \ y)))" - using \\y. Some (f1 a u T) = ?fA a u T \ y \ |?fA a u T| \ |f1 a u T| \ |y| \ |a| \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ y)))\ - by blast + using r1 by blast qed ultimately have "?fB a u T \ f2 a u T \ None" - using \Some a = f1 a u T \ f2 a u T \ (pc |a| \ sat (AStar A B) (the ( |a| \ f1 a u T)))\ + using r0 option.distinct(1) [of ] option.exhaust_sel[of "?fB a u T \ f2 a u T"] asso2[of "?fA a u T" "?fB a u T" "f1 a u T" "f2 a u T"] by metis - then show "Some (f1 a u T) = ?fA a u T \ ?fB a u T \ |?fA a u T| \ |f1 a u T| \ |?fB a u T| \ |a| \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ ?fB a u T))) -\ Some (?f2 a u T) = ?fB a u T \ f2 a u T" - using \Some a = f1 a u T \ f2 a u T \ (pc |a| \ sat (AStar A B) (the ( |a| \ f1 a u T)))\ - option.distinct(1) option.exhaust_sel[of "?fB a u T \ f2 a u T"] asso2[of "?fA a u T" "?fB a u T" "f1 a u T" "f2 a u T"] -\Some (f1 a u T) = ?fA a u T \ ?fB a u T \ |?fB a u T| \ |a| \ (pc |a| \ sat B (the ( |a| \ ?fB a u T)))\ -\Some (f1 a u T) = ?fA a u T \ yy \ |?fA a u T| \ |f1 a u T| \ |yy| \ |a| \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ yy)))\ + then show "Some (f1 a u T) = ?fA a u T \ ?fB a u T \ |?fA a u T| \ |f1 a u T| \ |?fB a u T| \ |a| + \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ ?fB a u T))) \ Some (?f2 a u T) = ?fB a u T \ f2 a u T" + using r0 r2 yy_prop + option.distinct(1) option.exhaust_sel[of "?fB a u T \ f2 a u T"] asso2[of "?fA a u T" "?fB a u T" "f1 a u T" "f2 a u T"] by simp qed have ih1: "\S'. package_rhs \ f S pc A \ f S' \ (\a\S'. case a of (a', u', T) \ \a u. (a, u, T) \ S \ a' \ ?f2 a u T \ |a'| = |a| )" proof (rule AStar(1)) show "valid_package_set S f" by (simp add: AStar.prems(2)) show "wf_assertion A" using AStar.prems(3) by auto show "mono_pure_cond pc" by (simp add: AStar.prems(4)) show "stable f \ \ ## f" using \stable f \ \ ## f\ by simp fix a u T assume asm0: "(a, u, T) \ S" then have b: "Some (f1 a u T) = ?fA a u T \ ?fB a u T \ |?fA a u T| \ |f1 a u T| \ |?fB a u T| \ |a| \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ ?fB a u T)))" using r by fast show "|?fA a u T| \ |a| \ Some a = ?fA a u T \ ?f2 a u T \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)))" proof - have "|?fA a u T| \ |a|" using AStar.prems(1)[of a u T] asm0 b asso1[of "?fA a u T" "?fB a u T" "f1 a u T" ] asso2[of "?fA a u T" "?fB a u T" ] option.sel succ_trans[of "|?fA a u T|" _ "|a|"] by blast moreover have "Some a = ?fA a u T \ ?f2 a u T" using AStar.prems(1)[of a u T] asm0 b asso1[of "?fA a u T" "?fB a u T" "f1 a u T" "f2 a u T" "?f2 a u T"] asso2[of "?fA a u T" "?fB a u T" "f1 a u T" "f2 a u T"] option.sel option.exhaust_sel[of "?fB a u T \ f2 a u T" "Some a = ?fA a u T \ ?f2 a u T"] by force moreover have "pc |a| \ sat A (the ( |a| \ ?fA a u T))" using AStar.prems(1)[of a u T] asm0 b asso2[of "?fA a u T" "?fB a u T" ] option.sel succ_trans[of "|?fA a u T|" _ "|a|"] by blast ultimately show ?thesis by blast qed qed then obtain S' where r': "package_rhs \ f S pc A \ f S'" "\a' u' T. (a', u', T) \ S' \ \a u. (a, u, T) \ S \ a' \ ?f2 a u T \ |a'| = |a| " by fast let ?project = "\a' T. (SOME r. \a u. r = (a, u) \ (a, u, T) \ S \ a' \ ?f2 a u T \ |a'| = |a| )" have project_prop: "\a' u' T. (a', u', T) \ S' \ \a u. ?project a' T = (a, u) \ (a, u, T) \ S \ a' \ ?f2 a u T \ |a'| = |a| " proof - fix a' u' T assume "(a', u', T) \ S'" then obtain a u where "(a, u, T) \ S \ a' \ ?f2 a u T \ |a'| = |a| " - using \\a' u' p. (a', u', T) \ S' \ \a u. (a, u, T) \ S \ a' \ ?f2 a u T \ |a'| = |a| \ by blast - show "\a u. ?project a' T = (a, u) \ (a, u, T) \ S \ a' \ ?f2 a u T \ |a'| = |a| " + using r' by blast + moreover show "\a u. ?project a' T = (a, u) \ (a, u, T) \ S \ a' \ ?f2 a u T \ |a'| = |a| " proof (rule someI_ex) - show "\r a u. r = (a, u) \ (a, u, T) \ S \ a' \ ?f2 a u T \ |a'| = |a| " using \(a, u, T) \ S \ a' \ ?f2 a u T \ |a'| = |a| \ by blast + show "\r a u. r = (a, u) \ (a, u, T) \ S \ a' \ ?f2 a u T \ |a'| = |a| " using calculation by blast qed qed let ?nf1 = "\a' u' T. let (a, u) = ?project a' T in (SOME r. Some r = |a'| \ ?fB a u T)" let ?nf2 = "\a' u' T. a' \ ?nf1 a' u' T" have "\S''. package_rhs \ f S' pc B \ f S'' \ (\a\S''. case a of (a', u', T) \ \a u. (a, u, T) \ S' \ a' \ ?nf2 a u T \ |a'| = |a| )" proof (rule AStar(2)) show "stable f \ \ ## f" using \stable f \ \ ## f\ by simp then show "valid_package_set S' f" using AStar.prems \package_rhs \ f S pc A \ f S'\ package_logic.package_rhs_proof package_logic.wf_assertion.simps(1) package_logic_axioms by metis show "wf_assertion B" using AStar.prems(3) by auto show "mono_pure_cond pc" by (simp add: AStar.prems(4)) fix a' u' T assume "(a', u', T) \ S'" then obtain a u where a_u_def: "(a, u) = ?project a' T" "(a, u, T) \ S" "a' \ ?f2 a u T" "|a'| = |a|" using project_prop by force define nf1 where "nf1 = ?nf1 a' u' T" define nf2 where "nf2 = ?nf2 a' u' T" moreover have rnf1_def: "Some nf1 = |a'| \ ?fB a u T" proof - let ?x = "(SOME r. Some r = |a'| \ ?fB a u T )" have "Some ?x = |a'| \ ?fB a u T" proof (rule someI_ex) have "Some (f1 a u T) = ?fA a u T \ ?fB a u T \ |?fA a u T| \ |f1 a u T| \ |?fB a u T| \ |a| \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ ?fB a u T)))" using r a_u_def by blast then have "Some (?f2 a u T) = ?fB a u T \ f2 a u T" by (metis (no_types, lifting) AStar.prems(1) a_u_def(2) asso2 option.distinct(1) option.exhaust_sel) moreover have "a' \ (?f2 a u T)" using \a' \ ?f2 a u T\ by blast ultimately have "a' \ ?fB a u T" using succ_trans greater_def by blast then obtain r where "Some r = |a'| \ ?fB a u T" using commutative greater_equiv[of a' "?fB a u T"] minus_equiv_def_any_elem[of a'] by fastforce then show "\r. Some r = |a'| \ ?fB a u T" by blast qed moreover have "?nf1 a' u' T = ?x" using let_pair_instantiate[of a u _ a' T "\a u. (SOME r. Some r = |a'| \ ?fB a u T )"] a_u_def by fast ultimately show ?thesis using nf1_def by argo qed moreover have rnf2_def: "Some a' = nf1 \ nf2" proof - have "nf2 = a' \ nf1" using nf1_def nf2_def by blast moreover have "a' \ nf1" proof - have "?f2 a u T \ nf1" proof - have "Some (?f2 a u T) = ?fB a u T \ f2 a u T" using r \(a, u, T) \ S\ by blast then have "?f2 a u T \ ?fB a u T" using greater_def by blast moreover have "?f2 a u T \ |a'|" proof - have "|?f2 a u T| \ |a|" proof - have "|?f2 a u T| \ |?fB a u T|" using \?f2 a u T \ ?fB a u T\ core_mono by blast moreover have "|?fB a u T| \ |a|" using r \(a, u, T) \ S\ by blast ultimately show ?thesis using succ_trans \|a'| = |a|\ by blast qed then show ?thesis using a_u_def(4) bigger_core_sum_defined[of "?f2 a u T"] greater_equiv[of _ "|a|"] by auto qed ultimately show ?thesis using core_is_pure[of a'] commutative pure_def[of "|a'|"] smaller_pure_sum_smaller[of _ _ "|a'|"] rnf1_def by (metis (no_types, lifting)) qed then show ?thesis using \a' \ ?f2 a u T\ succ_trans by blast qed ultimately show ?thesis using minus_some nf2_def by blast qed moreover have "pc |a'| \ sat B (the ( |a'| \ ?nf1 a' u' T))" proof - assume "pc |a'|" moreover have "|a'| = |a|" by (simp add: a_u_def(4)) then have "pc |a|" using \pc |a'|\ by simp ultimately have "sat B (the ( |a| \ ?fB a u T))" using r a_u_def by blast then have "sat B (the ( |a'| \ ?fB a u T))" using \|a'| = |a|\ by simp then show "sat B (the ( |a'| \ ?nf1 a' u' T))" proof - have "nf1 \ |a'|" using rnf1_def using greater_def by blast then have "Some nf1 = |a'| \ nf1" by (metis bigger_core_sum_defined commutative core_mono max_projection_prop_pure_core mpp_invo) then show ?thesis using nf1_def rnf1_def \sat B (the ( |a'| \ ?fB a u T))\ by argo qed qed moreover have "|?nf1 a' u' T| \ |a'|" proof - have "?nf1 a' u' T \ |a'|" using nf1_def greater_def rnf1_def by blast then show ?thesis using max_projection_propE(3) max_projection_prop_pure_core sep_algebra.mpp_prop sep_algebra_axioms by fastforce qed ultimately show "|?nf1 a' u' T| \ |a'| \ Some a' = ?nf1 a' u' T \ ?nf2 a' u' T \ (pc |a'| \ sat B (the ( |a'| \ ?nf1 a' u' T)))" using nf1_def by blast qed - then obtain S'' where "package_rhs \ f S' pc B \ f S''" "\a' u' T. (a', u', T) \ S'' \ \a u. (a, u, T) \ S' \ a' \ ?nf2 a u T \ |a'| = |a| " + then obtain S'' where S''_prop: "package_rhs \ f S' pc B \ f S''" "\a' u' T. (a', u', T) \ S'' \ \a u. (a, u, T) \ S' \ a' \ ?nf2 a u T \ |a'| = |a| " by fast then have "package_rhs \ f S pc (AStar A B) \ f S''" using \package_rhs \ f S pc A \ f S'\ package_rhs.AStar by presburger moreover have "\a'' u'' T. (a'', u'', T) \ S'' \ \a u. (a, u, T) \ S \ a'' \ f2 a u T \ |a''| = |a|" proof - fix a'' u'' T assume asm0: "(a'', u'', T) \ S''" then obtain a' u' where "(a', u', T) \ S' \ a'' \ ?nf2 a' u' T \ |a''| = |a'| " - using \\a' u' p. (a', u', T) \ S'' \ \a u. (a, u, T) \ S' \ a' \ ?nf2 a u T \ |a'| = |a| \ by blast + using S''_prop by blast then obtain a u where a_u_def: "(a, u) = ?project a' T" "(a, u, T) \ S" "a' \ ?f2 a u T" "|a'| = |a|" using project_prop by force define nf1 where "nf1 = ?nf1 a' u' T" define nf2 where "nf2 = ?nf2 a' u' T" moreover have rnf1_def: "Some nf1 = |a'| \ ?fB a u T" proof - let ?x = "(SOME r. Some r = |a'| \ ?fB a u T )" have "Some ?x = |a'| \ ?fB a u T" proof (rule someI_ex) have "Some (f1 a u T) = ?fA a u T \ ?fB a u T \ |?fA a u T| \ |f1 a u T| \ |?fB a u T| \ |a| \ (pc |a| \ sat A (the ( |a| \ ?fA a u T)) \ sat B (the ( |a| \ ?fB a u T)))" using r a_u_def by blast then have "Some (?f2 a u T) = ?fB a u T \ f2 a u T" by (metis (no_types, lifting) AStar.prems(1) a_u_def(2) asso2 option.distinct(1) option.exhaust_sel) moreover have "a' \ (?f2 a u T)" using \a' \ ?f2 a u T\ by blast ultimately have "a' \ ?fB a u T" using succ_trans greater_def by blast then obtain r where "Some r = |a'| \ ?fB a u T" using commutative greater_equiv[of a' "?fB a u T"] minus_equiv_def_any_elem[of a' ] by fastforce then show "\r. Some r = |a'| \ ?fB a u T" by blast qed moreover have "?nf1 a' u' T = ?x" using let_pair_instantiate[of a u _ a' T "\a u. (SOME r. Some r = |a'| \ ?fB a u T )"] a_u_def by fast ultimately show ?thesis using nf1_def by argo qed moreover have rnf2_def: "a' \ nf1 \ ?nf2 a' u' T \ f2 a u T" proof - have "nf2 = a' \ nf1" using nf1_def nf2_def by blast moreover have "a' \ nf1 \ a' \ nf1 \ f2 a u T" proof - have "?f2 a u T \ nf1" proof - have "Some (?f2 a u T) = ?fB a u T \ f2 a u T" using r \(a, u, T) \ S\ by blast then have "?f2 a u T \ ?fB a u T" using greater_def by blast moreover have "?f2 a u T \ |a'|" proof - have "|?f2 a u T| \ |a|" proof - have "|?f2 a u T| \ |?fB a u T|" using \?f2 a u T \ ?fB a u T\ core_mono by blast moreover have "|?fB a u T| \ |a|" using r \(a, u, T) \ S\ by blast ultimately show ?thesis using succ_trans \|a'| = |a|\ by blast qed then show ?thesis using a_u_def(4) bigger_core_sum_defined greater_equiv[of "?f2 a u T" "|a'|"] by auto qed ultimately show ?thesis using core_is_pure[of "a'"] commutative pure_def[of "|a'|"] smaller_pure_sum_smaller[of "?f2 a u T" _ "|a'|"] rnf1_def by simp qed then have r1: "a' \ nf1" using \a' \ ?f2 a u T\ succ_trans by blast then have "Some a' = nf1 \ nf2" using minus_some nf2_def \nf2 = a' \ nf1\ by presburger have r2: "a' \ nf1 \ f2 a u T" using \a' \ ?f2 a u T\ proof (rule prove_last_completeness) have "Some (?f2 a u T) = ?fB a u T \ f2 a u T" using r \(a, u, T) \ S\ by blast moreover have "Some nf1 = |a'| \ ?fB a u T" using rnf1_def by blast have "Some (?f2 a u T) = ?fB a u T \ f2 a u T" using r \(a, u, T) \ S\ by blast then have "?f2 a u T \ ?fB a u T" using greater_def by blast moreover have "?f2 a u T \ |a'|" proof - have "|?f2 a u T| \ |a|" proof - have "|?f2 a u T| \ |?fB a u T|" using \?f2 a u T \ ?fB a u T\ core_mono by blast moreover have "|?fB a u T| \ |a|" using r \(a, u, T) \ S\ by blast ultimately show ?thesis using succ_trans \|a'| = |a|\ by blast qed then show ?thesis using a_u_def(4) bigger_core_sum_defined[of _ "|a|"] greater_equiv[of "?f2 a u T" "|a|"] by auto qed ultimately show "Some (?f2 a u T) = nf1 \ f2 a u T" using asso1[of "|a'|" "?fB a u T" nf1 "f2 a u T" "?f2 a u T"] asso1[of "|a'|" "|a'|" "|a'|" ] core_is_pure[of "a'"] greater_def[of "?f2 a u T" "|a'|"] rnf1_def by (metis (no_types, lifting)) qed then show ?thesis using \a' \ ?f2 a u T\ succ_trans using r1 by force qed ultimately show ?thesis using nf2_def by argo qed ultimately have "(a, u, T) \ S \ a' \ ?f2 a u T \ ?nf2 a' u' T \ f2 a u T" using nf1_def nf2_def a_u_def by blast then have "a'' \ f2 a u T \ |a''| = |a'| " using \(a', u', T) \ S' \ a'' \ ?nf2 a' u' T \ |a''| = |a'| \ using succ_trans by blast then show "\a u. (a, u, T) \ S \ a'' \ f2 a u T \ |a''| = |a| " using r' using a_u_def(2) a_u_def(4) by auto qed ultimately show ?case by blast qed subsection Soundness theorem general_soundness: assumes "package_rhs \ unit { (a, unit, T) |a T. (a, T) \ S } (\_. True) A \' f S'" and "\a T. (a, T) \ S \ mono_transformer T" and "wf_assertion A" and "intuitionistic (sat A) \ pure_remains S'" shows "Some \ = \' \ f \ stable f \ (\(a, T) \ S. a ## T f \ sat A (the (a \ T f)))" proof - let ?S = "{ (a, unit, p) |a p. (a, p) \ S }" let ?pc = "\_. True" have "package_rhs_connection \ unit ?S ?pc A \' f S' \ valid_package_set S' f" proof (rule package_rhs_proof) show "package_rhs \ unit {(a, unit, p) |a p. (a, p) \ S} (\_. True) A \' f S'" using assms(1) by auto show "valid_package_set {(a, unit, p) |a p. (a, p) \ S} unit" proof (rule valid_package_setI) fix a u T assume "(a, u, T) \ {(a, unit, p) |a p. (a, p) \ S}" then have "u = unit" by blast moreover have "|T unit| = unit" using \(a, u, T) \ {(a, unit, p) |a p. (a, p) \ S}\ assms(2) mono_transformer_def unit_core by fastforce then show "a ## u \ |a| \ |u| \ mono_transformer T \ a \ |T unit|" using \(a, u, T) \ {(a, unit, p) |a p. (a, p) \ S}\ assms(2) defined_def unit_core unit_neutral unit_smaller by auto qed show "wf_assertion A" by (simp add: assms(3)) show "mono_pure_cond (\_. True)" using mono_pure_cond_def by auto show "stable unit" by (simp add: stable_unit) show "\ ## unit" using defined_def unit_neutral by auto qed then obtain r: "\ \ unit = \' \ f" "stable f" "\a u T. (a, u, T) \ ?S \ (\au. Some au = a \ u \ (au ## (T f \ T unit) \ (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ (T f \ T unit) = a' \ u' \ u' \ u \ package_sat ?pc A a' u' u)))" using package_rhs_connection_def by force moreover have "\a T x. (a, T) \ S \ Some x = a \ T f \ sat A x" proof - fix a T x assume asm0: "(a, T) \ S \ Some x = a \ T f" then have "T f \ T unit = T f" by (metis assms(2) commutative minus_equiv_def mono_transformer_def option.sel unit_neutral unit_smaller) - then obtain au where "Some au = a \ unit \ (au ## T f \ + then obtain au where au_def: "Some au = a \ unit \ (au ## T f \ (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ T f = a' \ u' \ u' \ unit \ package_sat ?pc A a' u' unit))" using r asm0 by fastforce then have "au = a" by (metis option.inject unit_neutral) then have "(\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ a \ T f = a' \ u' \ package_sat ?pc A a' u' unit)" - using \Some au = a \ unit \ (au ## T f \ (\a' u'. (a', u', T) \ S' \ |a'| \ |a| \ au \ T f = a' \ u' \ u' \ unit \ package_sat (\_. True) A a' u' unit))\ asm0 defined_def + using au_def asm0 defined_def by auto - then obtain a' u' where "(a', u', T) \ S' \ |a'| \ |a| \ a \ T f = a' \ u' \ package_sat ?pc A a' u' unit" + then obtain a' u' where r0: "(a', u', T) \ S' \ |a'| \ |a| \ a \ T f = a' \ u' \ package_sat ?pc A a' u' unit" by presburger - then obtain y where "Some y = |a'| \ (u' \ unit) \ sat A y" + then obtain y where "Some y = |a'| \ (u' \ unit)" "sat A y" using package_sat_def by auto then have "Some y = |a'| \ u'" by (metis commutative minus_equiv_def splus.simps(3) unit_neutral unit_smaller) then have "x \ y" - by (metis \(a', u', T) \ S' \ |a'| \ |a| \ a \ T f = a' \ u' \ package_sat (\_. True) A a' u' unit\ addition_bigger asm0 max_projection_prop_pure_core mpp_smaller) + by (metis r0 addition_bigger asm0 max_projection_prop_pure_core mpp_smaller) then show "sat A x" proof (cases "intuitionistic (sat A)") case True - then show ?thesis by (meson \Some y = |a'| \ (u' \ unit) \ sat A y\ \x \ y\ intuitionistic_def) + then show ?thesis by (meson \Some y = |a'| \ (u' \ unit)\ \sat A y\ \x \ y\ intuitionistic_def) next case False then have "pure_remains S'" using assms(4) by auto - then have "pure a'" using pure_remains_def \(a', u', T) \ S' \ |a'| \ |a| \ a \ T f = a' \ u' \ package_sat (\_. True) A a' u' unit\ + then have "pure a'" using pure_remains_def r0 by fast - then show ?thesis using \(a', u', T) \ S' \ |a'| \ |a| \ a \ T f = a' \ u' \ package_sat (\_. True) A a' u' unit\ - \Some y = |a'| \ (u' \ unit) \ sat A y\ \Some y = |a'| \ u'\ asm0 core_is_smaller - core_max option.sel pure_def asso1[of a'] - by metis + then show ?thesis using r0 \Some y = |a'| \ (u' \ unit)\ \sat A y\ \Some y = |a'| \ u'\ asm0 core_is_smaller + core_max option.sel pure_def asso1[of a'] by metis qed qed then have "(\(a, T) \ S. a ## T f \ sat A (the (a \ T f)))" using sep_algebra.defined_def sep_algebra_axioms by fastforce moreover have "Some \ = \' \ f \ stable f" using r(1) r(2) unit_neutral by auto ultimately show ?thesis by blast qed theorem soundness: assumes "wf_assertion B" and "\a. sat A a \ a \ S" and "\a. a \ S \ mono_transformer (R a)" and "package_rhs \ unit { (a, unit, R a) |a. a \ S } (\_. True) B \' w S'" and "intuitionistic (sat B) \ pure_remains S'" shows "stable w \ Some \ = \' \ w \ is_footprint_general w R A B" proof - let ?S = "{ (a, R a) |a. a \ S} " have r: "Some \ = \' \ w \ stable w \ (\(a, T)\{(a, R a) |a. a \ S}. a ## T w \ sat B (the (a \ T w)))" proof (rule general_soundness) show "package_rhs \ unit {(a, unit, T) |a T. (a, T) \ {(a, R a) |a. a \ S}} (\_. True) B \' w S'" using assms(4) by auto show "\a T. (a, T) \ {(a, R a) |a. a \ S} \ mono_transformer T" using assms(3) by blast show "wf_assertion B" by (simp add: assms(1)) show "intuitionistic (sat B) \ pure_remains S'" by (simp add: assms(5)) qed moreover have "is_footprint_general w R A B" proof (rule is_footprint_generalI) fix a b assume asm: "sat A a \ Some b = a \ R a w" then have "(a, R a) \ ?S" using assms(2) by blast then have "sat B (the (a \ R a w))" using r using asm defined_def by fastforce then show "sat B b" by (metis asm option.sel) qed ultimately show ?thesis by blast qed corollary soundness_paper: assumes "wf_assertion B" and "\a. sat A a \ a \ S" and "package_rhs \ unit { (a, unit, id) |a. a \ S } (\_. True) B \' w S'" and "intuitionistic (sat B) \ pure_remains S'" shows "stable w \ Some \ = \' \ w \ is_footprint_standard w A B" proof - have "stable w \ Some \ = \' \ w \ is_footprint_general w (\_. id) A B" using assms soundness[of B A S "\_. id" \ \' w S'] by (simp add: mono_transformer_def) then show ?thesis using is_footprint_general_def is_footprint_standardI by fastforce qed subsection Completeness theorem general_completeness: assumes "\a u T x. (a, u, T) \ S \ Some x = a \ T f \ sat A x" and "Some \ = \' \ f" and "stable f" and "valid_package_set S unit" and "wf_assertion A" shows "\S'. package_rhs \ unit S (\_. True) A \' f S'" proof - define S' where "S' = { (r, u, T) |a u T r. (a, u, T) \ S \ Some r = a \ (T f \ T unit) \ r ## u }" let ?pc = "\_. True" have "\S''. package_rhs \' f S' ?pc A \' f S''" proof - let ?f2 = "\a u T. unit" let ?f1 = "\a u T. a" have "\S''. package_rhs \' f S' ?pc A \' f S'' \ (\(a', u', T) \ S''. \a u. (a, u, T) \ S' \ a' \ ?f2 a u T \ |a'| = |a| )" proof (rule completeness_aux) show "mono_pure_cond (\_. True)" by (simp add: mono_pure_cond_def) show "wf_assertion A" by (simp add: assms(5)) show "valid_package_set S' f" proof (rule valid_package_setI) fix a' u' T assume "(a', u', T) \ S'" then obtain a where asm: "(a, u', T) \ S \ Some a' = a \ (T f \ T unit) \ a' ## u'" using S'_def by blast then have "a ## u' \ |a| \ |u'| \ mono_transformer T " using assms(4) valid_package_set_def by fastforce moreover have "|T f \ T unit| = |T f|" by (simp add: minus_core) ultimately show "a' ## u' \ |a'| \ |u'| \ mono_transformer T \ a' \ |T f| " by (meson asm core_sum greater_def greater_equiv minus_equiv_def mono_transformer_def succ_trans unit_neutral) qed show "stable f \ \' ## f" by (metis assms(2) assms(3) defined_def domI domIff) fix a u T assume "(a, u, T) \ S'" then obtain a' u' where "(a', u', T) \ S" "Some a = a' \ (T f \ T unit)" using S'_def by blast moreover have "T f \ T unit = T f" proof - have "mono_transformer T" using \valid_package_set S unit\ valid_package_set_def \(a', u', T) \ S\ by auto then show ?thesis by (metis commutative minus_default minus_equiv_def mono_transformer_def option.sel unit_neutral) qed then have "sat A (the ( |a| \ a))" by (metis assms(1) calculation(1) calculation(2) commutative core_is_smaller option.sel) then show "|a| \ |a| \ Some a = a \ unit \ (True \ sat A (the ( |a| \ a)))" by (simp add: succ_refl unit_neutral) qed then show ?thesis by auto qed then obtain S'' where "package_rhs \' f S' ?pc A \' f S''" by blast have "package_rhs \ unit S ?pc A \' f S''" using assms(2) proof (rule package_rhs.AddFromOutside) show "package_rhs \' f S' ?pc A \' f S''" by (simp add: \package_rhs \' f S' ?pc A \' f S''\) show "stable f" using assms(3) by simp show "Some f = unit \ f" by (simp add: commutative unit_neutral) show "S' = { (r, u, T) |a u T r. (a, u, T) \ S \ Some r = a \ (T f \ T unit) \ r ## u }" using S'_def by blast qed then show ?thesis by blast qed theorem completeness: assumes "wf_assertion B" and "stable w \ is_footprint_general w R A B" and "Some \ = \' \ w" and "\a. sat A a \ mono_transformer (R a)" shows "\S'. package_rhs \ unit {(a, unit, R a) |a. sat A a} (\_. True) B \' w S'" proof - let ?S = "{(a, unit, R a) |a. sat A a}" have "\S'. package_rhs \ unit {(a, unit, R a) |a. sat A a} (\_. True) B \' w S'" proof (rule general_completeness[of ?S w B \ \']) show "\a u T x. (a, u, T) \ {(a, unit, R a) |a. sat A a} \ Some x = a \ T w \ sat B x" using assms(2) is_footprint_general_def by blast show "Some \ = \' \ w" by (simp add: assms(3)) show "stable w" by (simp add: assms(2)) show "wf_assertion B" by (simp add: assms(1)) show "valid_package_set {(a, unit, R a) |a. sat A a} unit" proof (rule valid_package_setI) fix a u T assume asm0: "(a, u, T) \ {(a, unit, R a) |a. sat A a}" then have "u = unit \ T = R a \ sat A a" by fastforce then show "a ## u \ |a| \ |u| \ mono_transformer T \ a \ |T unit|" using assms(4) defined_def mono_transformer_def unit_core unit_neutral unit_smaller by auto qed qed then show ?thesis by meson qed corollary completeness_paper: assumes "wf_assertion B" and "stable w \ is_footprint_standard w A B" and "Some \ = \' \ w" shows "\S'. package_rhs \ unit {(a, unit, id) |a. sat A a} (\_. True) B \' w S'" proof - have "\S'. package_rhs \ unit {(a, unit, (\_. id) a) |a. sat A a} (\_. True) B \' w S'" using assms(1) proof (rule completeness) show "stable w \ is_footprint_general w (\a. id) A B" using assms(2) is_footprint_general_def is_footprint_standard_def by force show "Some \ = \' \ w" by (simp add: assms(3)) show "\a. sat A a \ mono_transformer id" using mono_transformer_def by auto qed then show ?thesis by meson qed end end diff --git a/thys/Package_logic/SepAlgebra.thy b/thys/Package_logic/SepAlgebra.thy --- a/thys/Package_logic/SepAlgebra.thy +++ b/thys/Package_logic/SepAlgebra.thy @@ -1,1042 +1,1043 @@ section \Separation Algebra\ text \In this section, we formalize the concept of a separation algebra~\cite{Calcagno2007, Dockins2009}, on which our package logic is based.\ theory SepAlgebra imports Main begin type_synonym 'a property = "'a \ bool" locale sep_algebra = fixes plus :: "'a \ 'a \ 'a option" (infixl "\" 63) fixes core :: "'a \ 'a" (" |_| ") (* Largest duplicable part of a state *) assumes commutative: "a \ b = b \ a" and asso1: "a \ b = Some ab \ b \ c = Some bc \ ab \ c = a \ bc" and asso2: "a \ b = Some ab \ b \ c = None \ ab \ c = None" (* The core of x is the max of { p | pure p \ x \ p} *) and core_is_smaller: "Some x = x \ |x|" and core_is_pure: "Some |x| = |x| \ |x|" and core_max: "Some x = x \ c \ (\r. Some |x| = c \ r)" and core_sum: "Some c = a \ b \ Some |c| = |a| \ |b|" and positivity: "a \ b = Some c \ Some c = c \ c \ Some a = a \ a" and cancellative: "Some a = b \ x \ Some a = b \ y \ |x| = |y| \ x = y" begin lemma asso3: assumes "a \ b = None" and "b \ c = Some bc" shows "a \ bc = None" by (metis assms(1) assms(2) sep_algebra.asso2 sep_algebra.commutative sep_algebra_axioms) subsection \Definitions\ definition defined :: "'a \ 'a \ bool" (infixl "##" 62) where "a ## b \ a \ b \ None" definition greater :: "'a \ 'a \ bool" (infixl "\" 50) where "a \ b \ (\c. Some a = b \ c)" definition pure :: "'a \ bool" where "pure a \ Some a = a \ a" definition minus :: "'a \ 'a \ 'a" (infixl "\" 63) where "b \ a = (THE_default b (\x. Some b = a \ x \ x \ |b| ))" definition add_set :: "'a set \ 'a set \ 'a set" (infixl "\" 60) where "A \ B = { \ | \ a b. a \ A \ b \ B \ Some \ = a \ b }" definition greater_set :: "'a set \ 'a set \ bool" (infixl "\" 50) where "A \ B \ (\a \ A. \b \ B. a \ b)" definition up_closed :: "'a set \ bool" where "up_closed A \ (\\'. (\\ \ A. \' \ \) \ \' \ A)" definition equiv :: "'a set \ 'a set \ bool" (infixl "\" 40) where "A \ B \ A \ B \ B \ A" definition setify :: "'a property \ ('a set \ bool)" where "setify P A \ (\x \ A. P x)" definition mono_prop :: "'a property \ bool" where "mono_prop P \ (\x y. y \ x \ P x \ P y)" definition under :: "'a set \ 'a \ 'a set" where "under A \ = { \' | \'. \' \ A \ \ \ \'}" definition max_projection_prop :: "('a \ bool) \ ('a \ 'a) \ bool" where "max_projection_prop P f \ (\x. x \ f x \ P (f x) \ (\p. P p \ x \ p \ f x \ p))" inductive multi_plus :: "'a list \ 'a \ bool" where MPSingle: "multi_plus [a] a" | MPConcat: "\ length la > 0 ; length lb > 0 ; multi_plus la a ; multi_plus lb b ; Some \ = a \ b \ \ multi_plus (la @ lb) \" fun splus :: "'a option \ 'a option \ 'a option" where "splus None _ = None" | "splus _ None = None" | "splus (Some a) (Some b) = a \ b" subsection \First lemmata\ lemma greater_equiv: "a \ b \ (\c. Some a = c \ b)" using commutative greater_def by auto lemma smaller_compatible: assumes "a' ## b" and "a' \ a" shows "a ## b" by (metis (full_types) assms(1) assms(2) asso3 commutative defined_def greater_def) lemma bigger_sum_smaller: assumes "Some c = a \ b" and "a \ a'" shows "\b'. b' \ b \ Some c = a' \ b'" proof - obtain r where "Some a = a' \ r" using assms(2) greater_def by auto then obtain br where "Some br = r \ b" by (metis assms(1) asso2 domD domIff option.discI) then have "Some c = a' \ br" by (metis \Some a = a' \ r\ assms(1) asso1) then show ?thesis using \Some br = r \ b\ commutative greater_def by force qed subsubsection \splus\ lemma splus_develop: assumes "Some a = b \ c" shows "a \ d = splus (splus (Some b) (Some c)) (Some d)" by (metis assms splus.simps(3)) lemma splus_comm: "splus a b = splus b a" apply (cases a) apply (cases b) apply simp_all apply (cases b) by (simp_all add: commutative) lemma splus_asso: "splus (splus a b) c = splus a (splus b c)" proof (cases a) case None then show ?thesis by simp next case (Some a') then have "a = Some a'" by simp then show ?thesis proof (cases b) case None then show ?thesis by (simp add: Some) next case (Some b') then have "b = Some b'" by simp then show ?thesis proof (cases c) case None then show ?thesis by (simp add: splus_comm) next case (Some c') then have "c = Some c'" by simp then show ?thesis proof (cases "a' \ b'") case None then have "a' \ b' = None" by simp then show ?thesis proof (cases "b' \ c'") case None then show ?thesis by (simp add: Some \a = Some a'\ \a' \ b' = None\ \b = Some b'\) next case (Some bc) then show ?thesis by (metis (full_types) None \a = Some a'\ \b = Some b'\ \c = Some c'\ sep_algebra.asso2 sep_algebra_axioms splus.simps(2) splus.simps(3) splus_comm) qed next case (Some ab) then have "Some ab = a' \ b'" by simp then show ?thesis proof (cases "b' \ c'") case None then show ?thesis by (metis Some \a = Some a'\ \b = Some b'\ \c = Some c'\ asso2 splus.simps(2) splus.simps(3)) next case (Some bc) then show ?thesis by (metis \Some ab = a' \ b'\ \a = Some a'\ \b = Some b'\ \c = Some c'\ sep_algebra.asso1 sep_algebra_axioms splus.simps(3)) qed qed qed qed qed subsubsection \Pure\ (* Maybe need more *) lemma pure_stable: assumes "pure a" and "pure b" and "Some c = a \ b" shows "pure c" by (metis assms asso1 commutative pure_def) (* Specific to pure *) lemma pure_smaller: assumes "pure a" and "a \ b" shows "pure b" by (metis assms greater_def positivity pure_def) subsection \Succ is an order\ lemma succ_antisym: assumes "a \ b" and "b \ a" shows "a = b" proof - obtain ra where "Some a = b \ ra" using assms(1) greater_def by auto obtain rb where "Some b = a \ rb" using assms(2) greater_def by auto then have "Some a = splus (Some a) (splus (Some ra) (Some rb))" proof - have "Some b = splus (Some a) (Some rb)" by (simp add: \Some b = a \ rb\) then show ?thesis by (metis (full_types) \Some a = b \ ra\ sep_algebra.splus.simps(3) sep_algebra_axioms splus_asso splus_comm) qed moreover have "Some b = splus (Some b) (splus (Some ra) (Some rb))" by (metis \Some a = b \ ra\ \Some b = a \ rb\ sep_algebra.splus.simps(3) sep_algebra_axioms splus_asso) moreover have "pure ra \ pure rb" proof - obtain rab where "Some rab = ra \ rb" by (metis calculation(2) splus.elims splus.simps(3)) then have "|a| \ rab" by (metis calculation(1) core_max greater_def splus.simps(3)) then have "pure rab" using core_is_pure pure_def pure_smaller by blast moreover have "rab \ ra \ rab \ rb" using \Some rab = ra \ rb\ greater_def greater_equiv by blast ultimately have "pure ra" using pure_smaller by blast moreover have "pure rb" using \pure rab\ \rab \ ra \ rab \ rb\ pure_smaller by blast ultimately show ?thesis by blast qed ultimately show ?thesis by (metis \Some b = a \ rb\ option.inject pure_def sep_algebra.splus.simps(3) sep_algebra_axioms splus_asso) qed lemma succ_trans: assumes "a \ b" and "b \ c" shows "a \ c" using assms(1) assms(2) bigger_sum_smaller greater_def by blast lemma succ_refl: "a \ a" using core_is_smaller greater_def by blast subsection \Core (pure) and stabilize (stable)\ lemma max_projection_propI: assumes "\x. x \ f x" and "\x. P (f x)" and "\x p. P p \ x \ p \ f x \ p" shows "max_projection_prop P f" by (simp add: assms(1) assms(2) assms(3) max_projection_prop_def) lemma max_projection_propE: assumes "max_projection_prop P f" shows "\x. x \ f x" and "\x. P (f x)" and "\x p. P p \ x \ p \ f x \ p" using assms max_projection_prop_def by auto lemma max_projection_prop_pure_core: "max_projection_prop pure core" proof (rule max_projection_propI) fix x show "x \ |x|" using core_is_smaller greater_equiv by blast show "pure |x|" by (simp add: core_is_pure pure_def) show "\p. pure p \ x \ p \ |x| \ p" proof - fix p assume "pure p \ x \ p" then obtain r where "Some x = p \ r" using greater_def by blast then show "|x| \ p" by (metis \pure p \ x \ p\ asso1 commutative core_max greater_equiv pure_def) qed qed lemma mpp_smaller: assumes "max_projection_prop P f" shows "x \ f x" using assms max_projection_propE(1) by auto lemma mpp_compatible: assumes "max_projection_prop P f" and "a ## b" shows "f a ## f b" by (metis (mono_tags, opaque_lifting) assms(1) assms(2) commutative defined_def max_projection_prop_def smaller_compatible) lemma mpp_prop: assumes "max_projection_prop P f" shows "P (f x)" by (simp add: assms max_projection_propE(2)) lemma mppI: assumes "max_projection_prop P f" and "a \ x" and "P x" and "x \ f a" shows "x = f a" proof - have "f a \ x" using assms max_projection_propE(3) by auto then show ?thesis by (simp add: assms(4) succ_antisym) qed lemma mpp_invo: assumes "max_projection_prop P f" shows "f (f x) = f x" using assms max_projection_prop_def succ_antisym by auto lemma mpp_mono: assumes "max_projection_prop P f" and "a \ b" shows "f a \ f b" by (metis assms max_projection_prop_def succ_trans) subsection \Subtraction\ lemma addition_bigger: assumes "a' \ a" and "Some x' = a' \ b" and "Some x = a \ b" shows "x' \ x" by (metis assms asso1 bigger_sum_smaller greater_def) lemma smaller_than_core: assumes "y \ x" and "Some z = x \ |y|" shows "|z| = |y|" proof - have "Some |z| = |x| \ |y|" using assms(2) core_sum max_projection_prop_pure_core mpp_invo by fastforce then have "Some |z| = |x| \ |y|" by simp moreover have "|z| \ |y|" using calculation greater_equiv by blast ultimately show ?thesis by (meson addition_bigger assms(1) assms(2) core_is_smaller core_sum greater_def succ_antisym) qed lemma extract_core: assumes "Some b = a \ x \ x \ |b|" shows "|x| = |b|" proof - obtain r where "Some x = r \ |b|" using assms greater_equiv by auto show ?thesis proof (rule smaller_than_core) show "Some x = r \ |b|" using \Some x = r \ |b|\ by auto show "b \ r" by (metis \Some x = r \ |b|\ assms commutative greater_def succ_trans) qed qed lemma minus_unique: assumes "Some b = a \ x \ x \ |b|" and "Some b = a \ y \ y \ |b|" shows "x = y" proof - have "|x| = |b|" using assms(1) extract_core by blast moreover have "|y| = |b|" using assms(2) extract_core by blast ultimately show ?thesis using assms(1) assms(2) cancellative by auto qed lemma minus_exists: assumes "b \ a" shows "\x. Some b = a \ x \ x \ |b|" using assms bigger_sum_smaller core_is_smaller by blast lemma minus_equiv_def: assumes "b \ a" shows "Some b = a \ (b \ a) \ (b \ a) \ |b|" proof - let ?x = "THE_default b (\x. Some b = a \ x \ x \ |b| )" have "(\x. Some b = a \ x \ x \ |b| ) ?x" proof (rule THE_defaultI') show "\!x. Some b = a \ x \ x \ |b|" using assms local.minus_unique minus_exists by blast qed then show ?thesis by (metis minus_def) qed lemma minus_default: assumes "\ b \ a" shows "b \ a = b" using THE_default_none assms greater_def minus_def by fastforce lemma minusI: assumes "Some b = a \ x" and "x \ |b|" shows "x = b \ a" using assms(1) assms(2) greater_def local.minus_unique minus_equiv_def by blast lemma minus_core: "|a \ b| = |a|" proof (cases "a \ b") case True then have "Some a = b \ (a \ b) \ a \ b \ |a|" using minus_equiv_def by auto then show ?thesis using extract_core by blast next case False then show ?thesis by (simp add: minus_default) qed lemma minus_core_weaker: "|a \ b| = |a| \ |b|" proof (cases "a \ b") case True then show ?thesis by (metis greater_equiv max_projection_prop_pure_core minus_core minus_default minus_equiv_def mpp_invo succ_antisym) next case False then show ?thesis by (metis greater_equiv max_projection_prop_pure_core minus_default minus_equiv_def mpp_invo succ_antisym) qed lemma minus_equiv_def_any_elem: assumes "Some x = a \ b" shows "Some (x \ a) = b \ |x|" proof - obtain r where "Some r = b \ |x|" by (metis assms core_is_smaller domD domIff option.simps(3) sep_algebra.asso2 sep_algebra_axioms) have "r = x \ a" proof (rule minusI) show "Some x = a \ r" by (metis \Some r = b \ |x|\ assms asso1 core_is_smaller) moreover show "r \ |x|" using \Some r = b \ |x|\ greater_equiv by blast qed then show ?thesis using \Some r = b \ |x|\ by blast qed lemma minus_bigger: assumes "Some x = a \ b" shows "x \ a \ b" using assms greater_def minus_equiv_def_any_elem by blast lemma minus_smaller: assumes "x \ a" shows "x \ x \ a" using assms greater_equiv minus_equiv_def by blast lemma minus_sum: assumes "Some a = b \ c" and "x \ a" shows "x \ a = (x \ b) \ c" proof (rule minusI) obtain r where "Some r = c \ (x \ a)" by (metis assms(1) assms(2) asso2 minus_equiv_def option.exhaust_sel) have "r = (x \ b)" proof (rule minusI) show "Some x = b \ r" by (metis \Some r = c \ (x \ a)\ assms(1) assms(2) asso1 minus_equiv_def) moreover show "r \ |x|" by (meson \Some r = c \ (x \ a)\ assms(2) greater_equiv sep_algebra.minus_equiv_def sep_algebra_axioms succ_trans) qed then show "Some (x \ b) = c \ (x \ a)" using \Some r = c \ (x \ a)\ by blast moreover show "x \ a \ |x \ b|" by (simp add: assms(2) minus_core minus_equiv_def) qed lemma smaller_compatible_core: assumes "y \ x" shows "x ## |y|" by (metis assms asso2 core_is_smaller defined_def greater_equiv option.discI) lemma smaller_pure_sum_smaller: assumes "y \ a" and "y \ b" and "Some x = a \ b" and "pure b" shows "y \ x" proof - obtain r where "Some y = r \ b" "r \ a" by (metis assms(1) assms(2) assms(4) asso1 greater_equiv pure_def) then show ?thesis using addition_bigger assms(3) by blast qed lemma greater_minus_trans: assumes "y \ x" and "x \ a" shows "y \ a \ x \ a" proof - obtain r where "Some y = x \ r" using assms(1) greater_def by blast then obtain ra where "Some x = a \ ra" using assms(2) greater_def by blast then have "Some (x \ a) = ra \ |x|" by (simp add: minus_equiv_def_any_elem) then obtain yy where "Some yy = (x \ a) \ r" by (metis (full_types) \Some y = x \ r\ assms(2) asso3 commutative minus_equiv_def not_Some_eq) - then have "Some x = a \ (x \ a) \ x \ a \ |x|" - by (simp add: assms(2) sep_algebra.minus_equiv_def sep_algebra_axioms) + then obtain "Some x = a \ (x \ a)" "x \ a \ |x|" + by (simp_all add: assms(2) sep_algebra.minus_equiv_def sep_algebra_axioms) then obtain y' where "Some y' = a \ yy" using \Some y = x \ r\ \Some yy = x \ a \ r\ asso1 by metis moreover have "y \ y'" - by (metis \Some x = a \ (x \ a) \ x \ a \ |x|\ \Some y = x \ r\ \Some yy = x \ a \ r\ asso1 calculation option.inject succ_refl) + by (metis \Some x = a \ (x \ a)\ \Some y = x \ r\ \Some yy = x \ a \ r\ asso1 calculation option.inject succ_refl) moreover obtain x' where "Some x' = (x \ a) \ a" using assms(2) commutative minus_equiv_def by fastforce then have "y \ x'" by (metis assms(1) assms(2) commutative minus_equiv_def option.sel) moreover have "x' \ x \ a" using \Some x' = x \ a \ a\ greater_def by auto ultimately show ?thesis using \Some x' = x \ a \ a\ \Some y = x \ r\ assms(2) asso1 commutative greater_equiv minus_bigger minus_equiv_def option.sel sep_algebra.succ_trans sep_algebra_axioms proof - have f1: "Some y' = a \ yy" by (simp add: \Some y' = a \ yy\ commutative) then have "y = y'" by (metis \Some y = x \ r\ \Some yy = x \ a \ r\ \x \ a\ asso1 minus_equiv_def option.sel) then show ?thesis using f1 by (metis (no_types) \Some yy = x \ a \ r\ commutative greater_equiv minus_bigger sep_algebra.succ_trans sep_algebra_axioms) qed qed lemma minus_and_plus: assumes "Some \' = \ \ r" and "\ \ a" shows "Some (\' \ a) = (\ \ a) \ r" proof - have "\ \ \ \ a" by (simp add: assms(2) minus_smaller) then have "(\ \ a) ## r" by (metis (full_types) assms(1) defined_def option.discI sep_algebra.smaller_compatible sep_algebra_axioms) then obtain x where "Some x = (\ \ a) \ r" using defined_def by auto then have "Some \' = a \ x \ x \ |\'|" by (metis (no_types, lifting) assms asso1 core_sum max_projection_prop_pure_core minus_core minus_equiv_def mpp_smaller option.inject) then have "x = \' \ a" by (simp add: minusI) then show ?thesis using \Some x = \ \ a \ r\ by blast qed subsection \Lifting the algebra to sets of states\ lemma add_set_commm: "A \ B = B \ A" proof show "A \ B \ B \ A" using add_set_def sep_algebra.commutative sep_algebra_axioms by fastforce show "B \ A \ A \ B" using add_set_def commutative by fastforce qed lemma x_elem_set_product: "x \ A \ B \ (\a b. a \ A \ b \ B \ Some x = a \ b)" using sep_algebra.add_set_def sep_algebra_axioms by fastforce lemma x_elem_set_product_splus: "x \ A \ B \ (\a b. a \ A \ b \ B \ Some x = splus (Some a) (Some b))" using sep_algebra.add_set_def sep_algebra_axioms by fastforce lemma add_set_asso: "(A \ B) \ C = A \ (B \ C)" (is "?A = ?B") proof - have "?A \ ?B" proof (rule subsetI) fix x assume "x \ ?A" then obtain ab c where "Some x = ab \ c" "ab \ A \ B" "c \ C" using x_elem_set_product by auto then obtain a b where "Some ab = a \ b" "a \ A" "b \ B" using x_elem_set_product by auto then obtain bc where "Some bc = b \ c" by (metis \Some x = ab \ c\ asso2 option.exhaust) then show "x \ ?B" by (metis \Some ab = a \ b\ \Some x = ab \ c\ \a \ A\ \b \ B\ \c \ C\ asso1 x_elem_set_product) qed moreover have "?B \ ?A" proof (rule subsetI) fix x assume "x \ ?B" then obtain a bc where "Some x = a \ bc" "a \ A" "bc \ B \ C" using x_elem_set_product by auto then obtain b c where "Some bc = b \ c" "c \ C" "b \ B" using x_elem_set_product by auto then obtain ab where "Some ab = a \ b" by (metis \Some x = a \ bc\ asso3 option.collapse) then show "x \ ?A" by (metis \Some bc = b \ c\ \Some x = a \ bc\ \a \ A\ \b \ B\ \c \ C\ asso1 x_elem_set_product) qed ultimately show ?thesis by blast qed lemma up_closedI: assumes "\\' \. (\' :: 'a) \ \ \ \ \ A \ \' \ A" shows "up_closed A" using assms up_closed_def by blast lemma up_closed_plus_UNIV: "up_closed (A \ UNIV)" proof (rule up_closedI) fix \ \' assume asm: "\' \ \ \ \ \ A \ UNIV" then obtain r a b where "Some \' = \ \ r" "Some \ = a \ b" "a \ A" using greater_def x_elem_set_product by auto then obtain br where "Some br = b \ r" by (metis asso2 option.exhaust_sel) then have "Some \' = a \ br" by (metis \Some \ = a \ b\ \Some \' = \ \ r\ splus.simps(3) splus_asso) then show "\' \ A \ UNIV" using \a \ A\ x_elem_set_product by auto qed lemma succ_set_trans: assumes "A \ B" and "B \ C" shows "A \ C" by (meson assms(1) assms(2) greater_set_def succ_trans) lemma greater_setI: assumes "\a. a \ A \ (\b \ B. a \ b)" shows "A \ B" by (simp add: assms greater_set_def) lemma bigger_set: assumes "A' \ A" shows "A' \ B \ A \ B" proof (rule greater_setI) fix x assume "x \ A' \ B" then obtain a' b where "Some x = a' \ b" "a' \ A'" "b \ B" using x_elem_set_product by auto then obtain a where "a' \ a" "a \ A" using assms greater_set_def by blast then obtain ab where "Some ab = a \ b" by (metis \Some x = a' \ b\ asso2 domD domIff greater_equiv) then show "\ab\A \ B. x \ ab" using \Some x = a' \ b\ \a \ A\ \a' \ a\ \b \ B\ addition_bigger x_elem_set_product by blast qed lemma bigger_singleton: assumes "\' \ \" shows "{\'} \ {\}" by (simp add: assms greater_set_def) lemma add_set_elem: "\ \ A \ B \ (\a b. Some \ = a \ b \ a \ A \ b \ B)" using add_set_def by auto lemma up_closed_sum: assumes "up_closed A" shows "up_closed (A \ B)" proof (rule up_closedI) fix \' \ assume asm: "\' \ \ \ \ \ A \ B" then obtain a b where "a \ A" "b \ B" "Some \ = a \ b" using add_set_elem by auto moreover obtain r where "Some \' = \ \ r" using asm greater_def by blast then obtain ar where "Some ar = a \ r" by (metis asso2 calculation(3) commutative option.exhaust_sel option.simps(3)) then have "ar \ A" by (meson assms calculation(1) greater_def sep_algebra.up_closed_def sep_algebra_axioms) then show "\' \ A \ B" by (metis \Some \' = \ \ r\ \Some ar = a \ r\ add_set_elem asso1 calculation(2) calculation(3) commutative) qed lemma up_closed_bigger_subset: assumes "up_closed B" and "A \ B" shows "A \ B" by (meson assms(1) assms(2) greater_set_def sep_algebra.up_closed_def sep_algebra_axioms subsetI) lemma up_close_equiv: assumes "up_closed A" and "up_closed B" shows "A \ B \ A = B" proof - have "A \ B \ A \ B \ B \ A" using local.equiv_def by auto also have "... \ A \ B \ B \ A" by (metis assms(1) assms(2) greater_set_def set_eq_subset succ_refl up_closed_bigger_subset) ultimately show ?thesis by blast qed lemma equiv_stable_sum: assumes "A \ B" shows "A \ C \ B \ C" using assms bigger_set local.equiv_def by auto lemma equiv_up_closed_subset: assumes "up_closed A" and "equiv B C" shows "B \ A \ C \ A" (is "?B \ ?C") proof - have "?B \ ?C" by (meson greater_set_def up_closed_def equiv_def assms(1) assms(2) subsetD subsetI) moreover have "?C \ ?B" by (meson greater_set_def up_closed_def equiv_def assms(1) assms(2) subsetD subsetI) ultimately show ?thesis by blast qed lemma mono_propI: assumes "\x y. y \ x \ P x \ P y" shows "mono_prop P" using assms mono_prop_def by blast lemma mono_prop_set: assumes "A \ B" and "setify P B" and "mono_prop P" shows "setify P A" using assms(1) assms(2) assms(3) greater_set_def local.setify_def mono_prop_def by auto lemma mono_prop_set_equiv: assumes "mono_prop P" and "equiv A B" shows "setify P A \ setify P B" by (meson assms(1) assms(2) local.equiv_def sep_algebra.mono_prop_set sep_algebra_axioms) lemma setify_sum: "setify P (A \ B) \ (\x \ A. setify P ({x} \ B))" (is "?A \ ?B") proof - have "?A \ ?B" using local.setify_def sep_algebra.add_set_elem sep_algebra_axioms singletonD by fastforce moreover have "?B \ ?A" using add_set_elem local.setify_def by fastforce ultimately show ?thesis by blast qed lemma setify_sum_image: "setify P ((Set.image f A) \ B) \ (\x \ A. setify P ({f x} \ B))" proof show "setify P (f ` A \ B) \ \x\A. setify P ({f x} \ B)" by (meson rev_image_eqI sep_algebra.setify_sum sep_algebra_axioms) show "\x\A. setify P ({f x} \ B) \ setify P (f ` A \ B)" by (metis (mono_tags, lifting) image_iff sep_algebra.setify_sum sep_algebra_axioms) qed lemma equivI: assumes "A \ B" and "B \ A" shows "equiv A B" by (simp add: assms(1) assms(2) local.equiv_def) lemma sub_bigger: assumes "A \ B" shows "A \ B" by (meson assms greater_set_def in_mono succ_refl) lemma larger_set_refl: "A \ A" by (simp add: sub_bigger) definition upper_closure where "upper_closure A = { \' |\' \. \' \ \ \ \ \ A }" lemma upper_closure_up_closed: "up_closed (upper_closure A)" proof (rule up_closedI) fix \' \ assume asm0: "\' \ \ \ \ \ upper_closure A" then obtain a where "a \ A \ \ \ a" using sep_algebra.upper_closure_def sep_algebra_axioms by fastforce then have "\' \ a" using asm0 succ_trans by blast then show "\' \ upper_closure A" using \a \ A \ \ \ a\ upper_closure_def by auto qed subsection \Addition of more than two states\ lemma multi_decompose: assumes "multi_plus l \" shows "length l \ 2 \ (\a b la lb. l = la @ lb \ length la > 0 \ length lb > 0 \ multi_plus la a \ multi_plus lb b \ Some \ = a \ b)" using assms apply (rule multi_plus.cases) by auto[2] lemma multi_take_drop: assumes "multi_plus l \" and "length l \ 2" shows "\n a b. n > 0 \ n < length l \ multi_plus (take n l) a \ multi_plus (drop n l) b \ Some \ = a \ b" proof - - obtain a b la lb where "l = la @ lb \ length la > 0 \ length lb > 0 \ multi_plus la a \ multi_plus lb b \ Some \ = a \ b" + obtain a b la lb where asm0: "l = la @ lb \ length la > 0 \ length lb > 0 \ multi_plus la a \ multi_plus lb b \ Some \ = a \ b" using assms(1) assms(2) multi_decompose by blast let ?n = "length la" - have "la = take ?n l" - by (simp add: \l = la @ lb \ 0 < length la \ 0 < length lb \ multi_plus la a \ multi_plus lb b \ Some \ = a \ b\) + have "la = take ?n l" + by (simp add: asm0) moreover have "lb = drop ?n l" - by (simp add: \l = la @ lb \ 0 < length la \ 0 < length lb \ multi_plus la a \ multi_plus lb b \ Some \ = a \ b\) + by (simp add: asm0) ultimately show ?thesis - by (metis \l = la @ lb \ 0 < length la \ 0 < length lb \ multi_plus la a \ multi_plus lb b \ Some \ = a \ b\ length_drop zero_less_diff) + by (metis asm0 length_drop zero_less_diff) qed lemma multi_plus_single: assumes "multi_plus [v] a" shows "a = v" using assms apply (cases) apply simp by (metis (no_types, lifting) Nil_is_append_conv butlast.simps(2) butlast_append length_greater_0_conv) lemma multi_plus_two: assumes "length l \ 2" shows "multi_plus l \ \ (\a b la lb. l = (la @ lb) \ length la > 0 \ length lb > 0 \ multi_plus la a \ multi_plus lb b \ Some \ = a \ b)" (is "?A \ ?B") by (meson MPConcat assms multi_decompose) lemma multi_plus_head_tail: "length l \ n \ length l \ 2 \ (multi_plus l \ \ (\r. Some \ = (List.hd l) \ r \ multi_plus (List.tl l) r))" proof (induction n arbitrary: l \) case 0 then show ?case by auto next case (Suc n) then have IH: "\(l :: 'a list) \. length l \ n \ length l \ 2 \ multi_plus l \ = (\r. Some \ = hd l \ r \ multi_plus (tl l) r)" by blast then show ?case proof (cases "n = 0") case True then have "n = 0" by simp then show ?thesis by linarith next case False - then have "length (l :: 'a list) \ 2 \ length l \ n + 1 \ multi_plus l \ \ (\r. Some \ = hd l \ r \ multi_plus (tl l) r)" (is "length l \ 2 \ length l \ n + 1 \ ?A \ ?B") + then have "length (l :: 'a list) \ 2 \ length l \ n + 1 \ multi_plus l \ \ (\r. Some \ = hd l \ r \ multi_plus (tl l) r)" + (is "length l \ 2 \ length l \ n + 1 \ ?A \ ?B") proof - assume asm: "length (l :: 'a list) \ 2 \ length l \ n + 1" have "?B \ ?A" proof - assume "?B" then obtain r where "Some \ = hd l \ r \ multi_plus (tl l) r" by blast then have "multi_plus [hd l] (hd l)" using MPSingle by blast moreover have "[hd l] @ (tl l) = l" by (metis Suc_le_length_iff asm append_Cons list.collapse list.simps(3) numeral_2_eq_2 self_append_conv2) ultimately show ?A by (metis (no_types, lifting) MPConcat Suc_1 Suc_le_mono asm \Some \ = hd l \ r \ multi_plus (tl l) r\ append_Nil2 length_Cons length_greater_0_conv list.size(3) not_one_le_zero zero_less_Suc) qed moreover have "?A \ ?B" proof - assume ?A then obtain la lb a b where "l = la @ lb" "length la > 0" "length lb > 0" "multi_plus la a" "multi_plus lb b" "Some \ = a \ b" using asm multi_decompose by blast - then have "length la \ n \ length la \ 2 \ multi_plus la a = (\r. Some a = hd la \ r \ multi_plus (tl la) r)" + then have r0: "length la \ n \ length la \ 2 \ multi_plus la a = (\r. Some a = hd la \ r \ multi_plus (tl la) r)" using IH by blast then show ?B proof (cases "length la \ 2") case True then obtain ra where "Some a = (hd la) \ ra" "multi_plus (tl la) ra" - by (metis Suc_eq_plus1 \0 < length lb\ \l = la @ lb\ \length la \ n \ 2 \ length la \ multi_plus la a = (\r. Some a = hd la \ r \ multi_plus (tl la) r)\ \multi_plus la a\ append_eq_conv_conj asm drop_eq_Nil le_add1 le_less_trans length_append length_greater_0_conv less_Suc_eq_le order.not_eq_order_implies_strict) + by (metis Suc_eq_plus1 \0 < length lb\ \l = la @ lb\ r0 \multi_plus la a\ append_eq_conv_conj asm drop_eq_Nil le_add1 le_less_trans length_append length_greater_0_conv less_Suc_eq_le order.not_eq_order_implies_strict) moreover obtain rab where "Some rab = ra \ b" by (metis \Some \ = a \ b\ calculation(1) asso2 option.exhaust_sel) then have "multi_plus ((tl la) @ lb) rab" by (metis (no_types, lifting) Nil_is_append_conv \multi_plus lb b\ calculation(2) length_greater_0_conv list.simps(3) multi_plus.cases sep_algebra.MPConcat sep_algebra_axioms) moreover have "Some \ = hd la \ rab" by (metis \Some \ = a \ b\ \Some rab = ra \ b\ asso1 calculation(1)) ultimately show ?B using \0 < length la\ \l = la @ lb\ by auto next case False then have "length la = 1" using \0 < length la\ by linarith then have "la = [a]" by (metis Nitpick.size_list_simp(2) One_nat_def Suc_le_length_iff \multi_plus la a\ diff_Suc_1 le_numeral_extra(4) length_0_conv list.sel(3) sep_algebra.multi_plus_single sep_algebra_axioms) then show ?thesis using \Some \ = a \ b\ \l = la @ lb\ \multi_plus lb b\ by auto qed qed then show ?thesis using calculation by blast qed then show ?thesis by (metis (no_types, lifting) Suc_eq_plus1) qed qed lemma not_multi_plus_empty: "\ multi_plus [] \" by (metis Nil_is_append_conv length_greater_0_conv list.simps(3) sep_algebra.multi_plus.simps sep_algebra_axioms) lemma multi_plus_deter: "length l \ n \ multi_plus l \ \ multi_plus l \' \ \ = \'" proof (induction n arbitrary: l \ \') case 0 then show ?case using multi_plus.cases by auto next case (Suc n) then show ?case proof (cases "length l \ 2") case True then obtain r where "Some \ = (List.hd l) \ r \ multi_plus (List.tl l) r" using Suc.prems(2) multi_plus_head_tail by blast moreover obtain r' where "Some \' = (List.hd l) \ r' \ multi_plus (List.tl l) r'" using Suc.prems(3) True multi_plus_head_tail by blast ultimately have "r = r'" by (metis Suc.IH Suc.prems(1) drop_Suc drop_eq_Nil) then show ?thesis by (metis \Some \ = hd l \ r \ multi_plus (tl l) r\ \Some \' = hd l \ r' \ multi_plus (tl l) r'\ option.inject) next case False then have "length l \ 1" by simp then show ?thesis proof (cases "length l = 0") case True then show ?thesis using Suc.prems(2) sep_algebra.not_multi_plus_empty sep_algebra_axioms by fastforce next case False then show ?thesis by (metis One_nat_def Suc.prems(2) Suc.prems(3) Suc_length_conv \length l \ 1\ le_SucE le_zero_eq length_greater_0_conv less_numeral_extra(3) sep_algebra.multi_plus_single sep_algebra_axioms) qed qed qed lemma multi_plus_implies_multi_plus_of_drop: assumes "multi_plus l \" and "n < length l" shows "\a. multi_plus (drop n l) a \ \ \ a" using assms proof (induction n arbitrary: l \) case 0 then show ?case using succ_refl by fastforce next case (Suc n) then have "length l \ 2" by linarith then obtain r where "Some \ = (List.hd l) \ r \ multi_plus (List.tl l) r" using Suc.prems(1) multi_plus_head_tail by blast then obtain a where "multi_plus (drop n (List.tl l)) a \ r \ a" using Suc.IH Suc.prems(2) by fastforce then show ?case by (metis \Some \ = hd l \ r \ multi_plus (tl l) r\ bigger_sum_smaller commutative drop_Suc greater_def) qed lemma multi_plus_bigger_than_head: assumes "length l > 0" and "multi_plus l \" shows "\ \ List.hd l" proof (cases "length l \ 2") case True then obtain r where "Some \ = (List.hd l) \ r \ multi_plus (List.tl l) r" using assms(1) assms(2) multi_plus_head_tail by blast then show ?thesis using greater_def by blast next case False then show ?thesis by (metis Cons_nth_drop_Suc MPSingle assms(1) assms(2) drop_0 drop_eq_Nil hd_conv_nth length_greater_0_conv not_less_eq_eq numeral_2_eq_2 sep_algebra.multi_plus_deter sep_algebra_axioms succ_refl) qed lemma multi_plus_bigger: assumes "i < length l" and "multi_plus l \" shows "\ \ (l ! i)" proof - obtain a where "multi_plus (drop i l) a \ \ \ a" using assms(1) assms(2) multi_plus_implies_multi_plus_of_drop order.strict_trans by blast moreover have "List.hd (drop i l) = l ! i" by (simp add: assms(1) hd_drop_conv_nth) then show ?thesis by (metis (no_types, lifting) succ_trans assms(1) assms(2) drop_eq_Nil leD length_greater_0_conv multi_plus_bigger_than_head multi_plus_implies_multi_plus_of_drop) qed lemma sum_then_singleton: "Some a = b \ c \ {a} = {b} \ {c}" (is "?A \ ?B") proof - have "?A \ ?B" proof - assume ?A then have "{a} \ {b} \ {c}" using add_set_elem by auto moreover have "{b} \ {c} \ {a}" proof (rule subsetI) fix x assume "x \ {b} \ {c}" then show "x \ {a}" by (metis \Some a = b \ c\ option.sel sep_algebra.add_set_elem sep_algebra_axioms singleton_iff) qed ultimately show ?thesis by blast qed moreover have "?B \ ?A" using add_set_elem by auto ultimately show ?thesis by blast qed lemma empty_set_sum: "{} \ A = {}" by (simp add: add_set_def) end end