theory Ribbons_Soundness imports Ribbons_Graphical "~~/src/HOL/Library/Permutation" "~~/src/HOL/Library/Quotient_List" begin text {* We prove that the proof rules defined in ribbons_graphical.thy are sound with respect to the rules of separation logic defined in ribbons_basic.thy, under the assumption that variables-as-resource is in use (which means that the Frame rule has no side-condition). The script is very long, and not intended for reading! The soundness theorem is stated at the end. *} subsection {* Proof chains *} text {* To enable the proof of soundness, we introduce proof chains. An (a,c) proof chain is a sequence of alternating a's and c's, beginning and ending with an a. Usually "a" represents an assertion or an interface, and "c" represents a command or a command-node. *} datatype ('a,'c) chain = cNil "'a" | cCons "'a" "'c" "('a,'c) chain" text {* Project first interface *} fun pre :: "('a,'c) chain \ 'a" where "pre (cNil P) = P" | "pre (cCons P x \) = P" text {* Project final interface *} fun post :: "('a,'c) chain \ 'a" where "post (cNil P) = P" | "post (cCons P x \) = post \" text {* Project list of commands *} fun comlist :: "('a,'c) chain \ 'c list" where "comlist (cNil _) = []" | "comlist (cCons _ x \) = x # (comlist \)" text {* Extract nth triple from a non-empty chain. *} fun nthtriple :: "('a,'c) chain \ nat \ ('a * 'c * 'a)" where "nthtriple (cCons P x \) 0 = (P, x, pre \)" | "nthtriple (cCons P x \) (Suc n) = nthtriple \ n" text {* Length of a chain *} fun chainlen :: "('a,'c) chain \ nat" where "chainlen (cNil _) = 0" | "chainlen (cCons _ _ \) = 1 + (chainlen \)" text {* The list of middle components of \'s triples is the list of \'s commands *} lemma snds_of_triples_form_comlist: fixes \ shows "\i. i < chainlen \ \ snd3 (nthtriple \ i) = (comlist \)!i" proof (induct \) case cNil thus ?case by auto next case (cCons p c \) thus ?case proof (induct i) (* actually just a case-split *) case 0 thus ?case by (auto simp add: snd3_def) next case (Suc i) hence "i < chainlen \" by auto from Suc.prems(1)[OF this] have "snd3 (nthtriple \ i) = comlist \ ! i" by auto thus "snd3 (nthtriple (cCons p c \) (Suc i)) = comlist (cCons p c \) ! Suc i" by auto qed qed text {* Map one function over all the interfaces, and another over all the commands. *} fun chainmap :: "('a \ 'b) \ ('c \ 'd) \ ('a,'c) chain \ ('b,'d) chain" where "chainmap f g (cNil P) = cNil (f P)" | "chainmap f g (cCons P x \) = cCons (f P) (g x) (chainmap f g \)" text {* Mapping over a chain preserves its length *} lemma chainmap_preserves_length: "chainlen (chainmap f g \) = chainlen \" by (induct \, auto) text {* Extend a chain on its right-hand side. *} fun cSnoc :: "('a,'c) chain \ 'c \ 'a \ ('a,'c) chain" where "cSnoc (cNil P) y Q = cCons P y (cNil Q)" | "cSnoc (cCons P x \) y Q = cCons P x (cSnoc \ y Q)" lemma len_snoc: fixes \ x P shows "chainlen (cSnoc \ x P) = 1 + (chainlen \)" by (induct \, auto) lemma pre_snoc: "pre (cSnoc \ x P) = pre \" by (induct \, auto) lemma comlist_snoc: "comlist (cSnoc \ x p) = comlist \ @ [x]" by (induct \, auto) text {* Like set-difference, but for lists *} definition listdiff :: "'a list \ 'a list \ 'a list" where "listdiff X Y \ [x \ X . x \ set Y]" lemma listdiff_nil_right: "listdiff X [] = X" by (unfold listdiff_def, auto) lemma listdiff_is_fold_rem: fixes X Y shows "listdiff X Y = foldr removeAll Y X" proof (induct Y) case Nil show ?case unfolding listdiff_def by auto next case (Cons y Y) have "foldr removeAll (y # Y) X = removeAll y (foldr removeAll Y X)" by auto also have "... = removeAll y (listdiff X Y)" unfolding Cons.hyps by auto also have "... = removeAll y [x \ X . x \ set Y]" unfolding listdiff_def by auto also have "... = filter (op \ y) [x \ X . x \ set Y]" unfolding removeAll_filter_not_eq by auto also have "... = [x\X . x \ set Y \ y \ x]" unfolding filter_filter by auto also have "... = [x\X . \ (x \ set Y \ x = y)]" unfolding eq_commute by auto also have "... = [x\X . \ (x \ insert y (set Y))]" unfolding insert_iff disj_commute by auto also have "... = [x\X . x \ set (y # Y)]" unfolding set.simps by auto also have "... = listdiff X (y # Y)" unfolding listdiff_def by auto finally show ?case by auto qed text {* Markers to indicate whether we're at the "top" or the "bottom" of a node; i.e., whether it hasn't (top) or has (bottom) been processed. *} datatype topbot = Top | Bot text {* A proofstate is a list of "currently initial" nodes, each marked as processed or not. The list is not ordered. Hence we could have used the theory of Finite Multisets here. *} quotient_type proofstate = "(node * topbot) list" / "perm" proof (intro equivpI) show "reflp perm" by (metis perm_refl reflpI) next show "symp perm" by (metis perm_sym sympI) next show "transp perm" by (metis perm.trans transpI) qed text {* \ converts a particular list to its equivalence class. \ converts an equivalence class to a particular list (in that class). *} abbreviation \ where "\ \ abs_proofstate" abbreviation \ where "\ \ rep_proofstate" lemma conc_abs: "\ (\ X) <~~> X" by (metis Quotient_proofstate perm_refl rep_abs_rsp_left) lemma abs_conc: "\ (\ X) = X" by (metis Quotient_def Quotient_proofstate) lemma abs_equiv: "X <~~> Y \ \ X = \ Y" by (metis Quotient_proofstate Quotient_rel) type_synonym rawchain = "(proofstate, node + edge) chain" type_synonym cookedchain = "(interface, assnode + comnode) chain" text {* mk \ \ converts the node+edge list \ into a rawchain by interspersing the appropriate proofstates. The first argument \ is the part of the chain that has already been converted. *} definition mk :: "[rawchain, (node + edge) list] \ rawchain" where "mk \ \ \ foldl (\\. sum_case (\v. cSnoc \ (Inl v) (\ ((listdiff (\ (post \)) [(v,Top)]) @ [(v,Bot)]))) (\e. cSnoc \ (Inr e) (\ ((listdiff (\ (post \)) [(v,Bot) . v \ fst3 e]) @ [(v,Top) . v \ thd3 e])))) \ \" lemma mk_preserves_length: fixes \ shows "\\. chainlen (mk \ \) = chainlen \ + length \" proof (induct \) case Nil show ?case by (unfold mk_def, auto) next case (Cons x \) hence "\\. chainlen (mk \ \) = chainlen \ + length \" by auto show ?case proof (cases x) case (Inl v) let ?lhs = "chainlen (mk \ (x # \))" have "?lhs = chainlen (mk \ ((Inl v) # \))" using Inl by auto also have "... = chainlen (mk (cSnoc \ (Inl v) (\ (listdiff (\ (post \)) [(v, Top)] @ [(v, Bot)]))) \)" unfolding mk_def by auto also have "... = chainlen (cSnoc \ (Inl v) (\ (listdiff (\ (post \)) [(v, Top)] @ [(v, Bot)]))) + length \" using Cons.hyps by auto also have "... = 1 + chainlen \ + length \" using len_snoc by auto also have "... = chainlen \ + length (x # \)" by auto finally show ?thesis by auto next case (Inr e) let ?lhs = "chainlen (mk \ (x # \))" have "?lhs = chainlen (mk \ ((Inr e) # \))" using Inr by auto also have "... = chainlen (mk (cSnoc \ (Inr e) (\ (listdiff (\ (post \)) [(v, Bot) . v \ fst3 e] @ [(v, Top) . v \ thd3 e]))) \)" unfolding mk_def by auto also have "... = chainlen (cSnoc \ (Inr e) (\ (listdiff (\ (post \)) [(v, Bot) . v \ fst3 e] @ [(v, Top) . v \ thd3 e]))) + length \" using Cons.hyps by auto also have "... = 1 + chainlen \ + length \" using len_snoc by auto also have "... = chainlen \ + length (x # \)" by auto finally show ?thesis by auto qed qed text {* mk distributes over cCons *} lemma mk_ccons: fixes \ \ shows "mk (cCons \ x \) \ = cCons \ x (mk \ \)" proof (induct \ arbitrary: \) case Nil thus ?case unfolding mk_def by auto next case (Cons y \) let ?f = "\\. sum_case (\v. cSnoc \ (Inl v) (\ ((listdiff (\ (post \)) [(v,Top)]) @ [(v,Bot)]))) (\e. cSnoc \ (Inr e) (\ ((listdiff (\ (post \)) [(v,Bot) . v \ fst3 e]) @ [(v,Top) . v \ thd3 e])))" show ?case proof (cases y) case (Inl v) hence sleik: "y = Inl v" by auto let ?lhs = "mk (cCons \ x \) ((Inl v) # \)" have "?lhs = foldl ?f (cCons \ x \) ((Inl v) # \)" unfolding mk_def by auto also have "... = foldl ?f (?f (cCons \ x \) (Inl v)) \" by (unfold foldl.simps(2), auto) also have "... = foldl ?f (cSnoc (cCons \ x \) (Inl v) (\ ((listdiff (\ (post (cCons \ x \))) [(v,Top)]) @ [(v,Bot)]))) \" by auto also have "... = foldl ?f (cCons \ x (cSnoc \ (Inl v) (\ ((listdiff (\ (post \)) [(v,Top)]) @ [(v,Bot)])))) \" by auto also have "... = mk (cCons \ x (cSnoc \ (Inl v) (\ ((listdiff (\ (post \)) [(v,Top)]) @ [(v,Bot)])))) \" unfolding mk_def by auto also have "... = cCons \ x (mk (cSnoc \ (Inl v) (\ ((listdiff (\ (post \)) [(v,Top)]) @ [(v,Bot)]))) \)" using Cons.hyps by auto also have "... = cCons \ x (mk \ ((Inl v) # \))" unfolding mk_def by auto finally show ?thesis using sleik by auto next case (Inr e) hence sleik: "y = Inr e" by auto let ?lhs = "mk (cCons \ x \) ((Inr e) # \)" have "?lhs = foldl ?f (cCons \ x \) ((Inr e) # \)" unfolding mk_def by auto also have "... = foldl ?f (?f (cCons \ x \) (Inr e)) \" by (unfold foldl.simps(2), auto) also have "... = foldl ?f (cSnoc (cCons \ x \) (Inr e) (\ ((listdiff (\ (post (cCons \ x \))) [(v,Bot) . v \ fst3 e]) @ [(v,Top) . v \ thd3 e]))) \" by auto also have "... = foldl ?f (cCons \ x (cSnoc \ (Inr e) (\ ((listdiff (\ (post \)) [(v,Bot) . v \ fst3 e]) @ [(v,Top) . v \ thd3 e])))) \" by auto also have "... = mk (cCons \ x (cSnoc \ (Inr e) (\ ((listdiff (\ (post \)) [(v,Bot) . v \ fst3 e]) @ [(v,Top) . v \ thd3 e])))) \" unfolding mk_def by auto also have "... = cCons \ x (mk (cSnoc \ (Inr e) (\ ((listdiff (\ (post \)) [(v,Bot) . v \ fst3 e]) @ [(v,Top) . v \ thd3 e]))) \)" using Cons.hyps by auto also have "... = cCons \ x (mk \ ((Inr e) # \))" unfolding mk_def by auto finally show ?thesis using sleik by auto qed qed text {* mk preserves \ as its list of commands *} lemma mk_comlist: fixes \ \ shows "comlist (mk \ \) = (comlist \) @ \" proof (induct \ arbitrary: \) case Nil thus ?case unfolding mk_def by auto next case (Cons x \) hence "\\. comlist (mk \ \) = comlist \ @ \" by auto let ?f = "\\. sum_case (\v. cSnoc \ (Inl v) (\ ((listdiff (\ (post \)) [(v,Top)]) @ [(v,Bot)]))) (\e. cSnoc \ (Inr e) (\ ((listdiff (\ (post \)) [(v,Bot) . v \ fst3 e]) @ [(v,Top) . v \ thd3 e])))" show ?case proof (induct x) case (Inl v) let ?lhs = "comlist (mk \ (Inl v # \))" let ?rhs = "comlist \ @ (Inl v) # \" have "?lhs = comlist (foldl ?f (?f \ (Inl v)) \)" unfolding mk_def by auto hence "?lhs = comlist (foldl ?f (?f \ (Inl v)) \)" by auto hence "?lhs = comlist (foldl ?f (cSnoc \ (Inl v) (\ ((listdiff (\ (post \)) [(v,Top)]) @ [(v,Bot)]))) \)" by auto hence "?lhs = comlist (mk (cSnoc \ (Inl v) (\ ((listdiff (\ (post \)) [(v,Top)]) @ [(v,Bot)]))) \)" unfolding mk_def by auto hence "?lhs = comlist (cSnoc \ (Inl v) (\ ((listdiff (\ (post \)) [(v,Top)]) @ [(v,Bot)]))) @ \" using Cons.hyps by auto hence "?lhs = (comlist \ @ [Inl v]) @ \" using comlist_snoc by auto thus "?lhs = ?rhs" by auto next case (Inr e) let ?lhs = "comlist (mk \ (Inr e # \))" let ?rhs = "comlist \ @ (Inr e) # \" have "?lhs = comlist (foldl ?f (?f \ (Inr e)) \)" unfolding mk_def by auto hence "?lhs = comlist (foldl ?f (?f \ (Inr e)) \)" by auto hence "?lhs = comlist (foldl ?f (cSnoc \ (Inr e) (\ ((listdiff (\ (post \)) [(v,Bot). v\fst3 e]) @ [(v,Top). v\thd3 e]))) \)" by auto hence "?lhs = comlist (mk (cSnoc \ (Inr e) (\ ((listdiff (\ (post \)) [(v,Bot). v\fst3 e]) @ [(v,Top). v\thd3 e]))) \)" unfolding mk_def by auto hence "?lhs = comlist (cSnoc \ (Inr e) (\ ((listdiff (\ (post \)) [(v,Bot). v\fst3 e]) @ [(v,Top). v\thd3 e]))) @ \" using Cons.hyps by auto hence "?lhs = (comlist \ @ [Inr e]) @ \" using comlist_snoc by auto thus "?lhs = ?rhs" by auto qed qed lemma pre_mk: fixes \ \ shows "pre (mk \ \) = pre \" proof (induct \ arbitrary: \) case Nil thus ?case by (unfold mk_def, auto) next case (Cons x \') hence "\\. pre (mk \ \') = pre \" by auto let ?f = "\\. sum_case (\v. cSnoc \ (Inl v) (\ ((listdiff (\ (post \)) [(v,Top)]) @ [(v,Bot)]))) (\e. cSnoc \ (Inr e) (\ ((listdiff (\ (post \)) [(v,Bot) . v \ fst3 e]) @ [(v,Top) . v \ thd3 e])))" have "pre (mk \ (x # \')) = pre (foldl ?f \ (x # \'))" unfolding mk_def by auto also have "... = pre (foldl ?f (?f \ x) \')" unfolding foldl.simps(2) by auto also have "... = pre (mk (?f \ x) \')" unfolding mk_def by auto also have "... = pre (?f \ x)" unfolding Cons.hyps by auto also have "... = pre \" proof (cases x) case (Inl v) hence "pre (?f \ x) = pre (?f \ (Inl v))" by auto also have "... = pre (cSnoc \ (Inl v) (\ ((listdiff (\ (post \)) [(v,Top)]) @ [(v,Bot)])))" by auto also have "... = pre \" unfolding pre_snoc by auto finally show ?thesis by auto next case (Inr e) hence "pre (?f \ x) = pre (?f \ (Inr e))" by auto also have "... = pre (cSnoc \ (Inr e) (\ ((listdiff (\ (post \)) [(v,Bot) . v \ fst3 e]) @ [(v,Top) . v \ thd3 e])))" by auto also have "... = pre \" unfolding pre_snoc by auto finally show ?thesis by auto qed finally show ?case by auto qed text {* Converts a "raw" chain, which talks about nodes and edges, into a "cooked" chain, which talks about interfaces and command-/assertion-nodes. *} fun cook :: "[diagram, rawchain] \ cookedchain" where "cook (Graph V \ E) \ = chainmap ((foldl (op \) Emp_int) \ (map (\(v,z). topbot_case top_ass bot_ass z (\ v))) \ \) (sum_case (Inl \ \) (Inr \ snd3)) \" text {* The S argument is the subset of initial nodes that have already been processed, and shouldn't be included in the linear extensions. *} fun lins2 :: "[node list, diagram] \ ((node + edge) list) set" where "lins2 S (Graph V \ E) = {\ . (distinct \) \ (set \ = ((Inl ` (set V - set S)) \ (Inr ` (set E)))) \ (\i j v e. i < length \ \ j < length \ \ \!i = Inl v \ \!j = Inr e \ v \ set (fst3 e) \ i (\j k w e. j < length \ \ k < length \ \ \!j = Inr e \ \!k = Inl w \ w \ set (thd3 e) \ j E shows "lins (Graph V \ E) = lins2 [] (Graph V \ E)" proof (intro set_eqI iffI) fix \ assume "\ \ lins (Graph V \ E)" hence "distinct \ \ set \ = Inl ` set V \ Inr ` set E \ (\i j v e. i < length \ \ j < length \ \ \ ! i = Inl v \ \ ! j = Inr e \ v \ set (fst3 e) \ i < j) \ (\j k w e. j < length \ \ k < length \ \ \ ! j = Inr e \ \ ! k = Inl w \ w \ set (thd3 e) \ j < k)" apply (unfold lins.simps) apply (erule CollectE, assumption) done hence "distinct \ \ set \ = Inl ` (set V - set []) \ Inr ` set E \ (\i j v e. i < length \ \ j < length \ \ \ ! i = Inl v \ \ ! j = Inr e \ v \ set (fst3 e) \ i < j) \ (\j k w e. j < length \ \ k < length \ \ \ ! j = Inr e \ \ ! k = Inl w \ w \ set (thd3 e) \ j < k)" apply (elim conjE) apply (intro conjI) apply assumption apply simp apply assumption+ done thus "\ \ lins2 [] (Graph V \ E)" apply (unfold lins2.simps) apply (intro CollectI, assumption) done next fix \ assume "\ \ lins2 [] (Graph V \ E)" hence "distinct \ \ set \ = Inl ` (set V - set []) \ Inr ` set E \ (\i j v e. i < length \ \ j < length \ \ \ ! i = Inl v \ \ ! j = Inr e \ v \ set (fst3 e) \ i < j) \ (\j k w e. j < length \ \ k < length \ \ \ ! j = Inr e \ \ ! k = Inl w \ w \ set (thd3 e) \ j < k)" apply (unfold lins2.simps) apply (erule CollectE, assumption) done hence "distinct \ \ set \ = Inl ` (set V) \ Inr ` set E \ (\i j v e. i < length \ \ j < length \ \ \ ! i = Inl v \ \ ! j = Inr e \ v \ set (fst3 e) \ i < j) \ (\j k w e. j < length \ \ k < length \ \ \ ! j = Inr e \ \ ! k = Inl w \ w \ set (thd3 e) \ j < k)" apply (elim conjE) apply (intro conjI) apply assumption apply simp apply assumption+ done thus "\ \ lins (Graph V \ E)" apply (unfold lins.simps) apply (intro CollectI, assumption) done qed text {* The set of raw chains of a diagram *} definition rawchains :: "diagram \ rawchain set" where "rawchains G \ {mk (cNil (\ [(v,Top). v \ initials G])) \ | \ . \ \ lins G}" text {* The set of raw chains of a diagram, where S is the set of initial nodes that should not be included in the chains. *} definition rawchains2 :: "[node list, diagram] \ rawchain set" where "rawchains2 S G \ { mk (cNil (\ ([(v,Top). v \ initials G, v \ set S] @ [(v,Bot). v \ S]))) \ | \ . \ \ lins2 S G }" text {* When S is empty, the two definitions coincide. *} lemma rawchains_is_rawchains2_with_empty_S: fixes V \ E shows "rawchains (Graph V \ E) = rawchains2 [] (Graph V \ E)" proof (intro set_eqI iffI) fix \ assume "\ \ rawchains (Graph V \ E)" then obtain \ where zgico: "\ = mk (cNil (\ [(v,Top). v \ initials (Graph V \ E)])) \" and "\ \ lins (Graph V \ E)" by (unfold rawchains_def, auto) with lins_is_lins2_with_empty_S[of V \ E] have "\ \ lins2 [] (Graph V \ E)" by metis with zgico show "\ \ rawchains2 [] (Graph V \ E)" unfolding rawchains2_def proof (intro CollectI exI[of _ \] conjI) assume "\ = mk (cNil (\ [(v,Top). v \ initials (Graph V \ E)])) \" thus "\ = mk (cNil (\ ([(v,Top). v \ initials (Graph V \ E), v \ set []] @ [(v,Bot). v \ []]))) \" by auto qed (assumption) next fix \ assume "\ \ rawchains2 [] (Graph V \ E)" then obtain \ where zgico: "\ = mk (cNil (\ ([(v,Top). v \ initials (Graph V \ E), v \ set []] @ [(v,Bot). v \ []]))) \" and "\ \ lins2 [] (Graph V \ E)" unfolding rawchains2_def by auto with lins_is_lins2_with_empty_S[of V \ E] have "\ \ lins (Graph V \ E)" by metis with zgico show "\ \ rawchains (Graph V \ E)" unfolding rawchains_def proof (intro CollectI exI[of _ \] conjI) assume "\ = mk (cNil (\ ([(v,Top). v \ initials (Graph V \ E), v \ set []] @ [(v,Bot). v \ []]))) \" thus "\ = mk (cNil (\ [(v,Top). v \ initials (Graph V \ E)])) \" by auto qed (assumption) qed text {* A rawchain is well-formed if for each triple {P} (Inl v) {Q}, P is of the form [(v,Top)] @ F, and Q is of the form [(v,Bot)] @ F, and for each triple {P} (Inr (vs,_,ws)) {Q}, P is of the form [(v,Bot). v\vs] @ F, and Q is of the form [(v,Top), v \ ws] @ F. *} definition wf_rawchain :: "rawchain \ bool" where "wf_rawchain \ \ \i < chainlen \. \\'. (\v. nthtriple \ i = (\ ([(v,Top)] @ \'), Inl v, \ ([(v,Bot)] @ \'))) \ (\e. nthtriple \ i = (\ ([(v,Bot). v\fst3 e] @ \'), Inr e, \ ([(v,Top). v\thd3 e] @ \')))" text {* The nil chain is well-formed. *} lemma wf_rawchain_cnil: "wf_rawchain (cNil (\ \))" by (unfold wf_rawchain_def, auto) lemma wf_rawchain_ccons_inl: fixes \ v \' \ assumes "\ <~~> [(v,Top)] @ \'" assumes "\ (pre \) <~~> [(v,Bot)] @ \'" assumes "wf_rawchain \" shows "wf_rawchain (cCons (\ \) (Inl v) \)" proof (unfold wf_rawchain_def, intro allI impI) fix i assume vzoyp: "i < chainlen (cCons (\ \) (Inl v) \)" from assms(1) assms(2) have guhla: "\ <~~> (v, Top) # \'" "\ (pre \) <~~> (v, Bot) # \'" by auto from assms(3) have xautg: "\i. i < chainlen \ \ \\'. (\v. nthtriple \ i = (\ ([(v, Top)] @ \'), Inl v, \ ([(v, Bot)] @ \'))) \ (\e. nthtriple \ i = (\ (map (\v. (v, Bot)) (fst3 e) @ \'), Inr e, \ (map (\v. (v, Top)) (thd3 e) @ \')))" unfolding wf_rawchain_def by auto show "\\'. (\va. nthtriple (cCons (\ \) (Inl v) \) i = (\ ([(va, Top)] @ \'), Inl va, \ ([(va, Bot)] @ \'))) \ (\e. nthtriple (cCons (\ \) (Inl v) \) i = (\ (map (\v. (v, Bot)) (fst3 e) @ \'), Inr e, \ (map (\v. (v, Top)) (thd3 e) @ \')))" proof (cases i) case 0 show ?thesis apply (unfold 0) apply (intro exI disjI1) apply (unfold nthtriple.simps(1)) apply (intro tripleI) apply (unfold fst3_def snd3_def thd3_def) apply (simp_all) apply (rule abs_equiv[OF guhla(1)]) proof - from abs_equiv[OF guhla(2)] have "\ (\ (pre \)) = \ ((v, Bot) # \')" by auto with abs_conc[of "pre \"] show "pre \ = \ ((v, Bot) # \')" by auto qed next case (Suc i') with vzoyp have "i' < chainlen \" by auto show ?thesis apply (unfold Suc) apply (unfold nthtriple.simps(2)) apply (rule xautg[OF `i' < chainlen \`]) done qed qed lemma wf_rawchain_ccons_inr: fixes \ e \' \ assumes "\ <~~> [(v,Bot) . v \ fst3 e] @ \'" assumes "\ (pre \) <~~> [(v,Top) . v \ thd3 e] @ \'" assumes "wf_rawchain \" shows "wf_rawchain (cCons (\ \) (Inr e) \)" proof (unfold wf_rawchain_def, intro allI impI) fix i assume vzoyp: "i < chainlen (cCons (\ \) (Inr e) \)" from assms(1) assms(2) have guhla: "\ <~~> [(v, Bot). v\fst e] @ \'" "\ (pre \) <~~> [(v, Top). v\ snd (snd e)] @ \'" unfolding fst3_def thd3_def by auto from assms(3) have xautg: "\i. i < chainlen \ \ \\'. (\v. nthtriple \ i = (\ ([(v, Top)] @ \'), Inl v, \ ([(v, Bot)] @ \'))) \ (\e. nthtriple \ i = (\ (map (\v. (v, Bot)) (fst3 e) @ \'), Inr e, \ (map (\v. (v, Top)) (thd3 e) @ \')))" unfolding wf_rawchain_def by auto show "\\'. (\va. nthtriple (cCons (\ \) (Inr e) \) i = (\ ([(va, Top)] @ \'), Inl va, \ ([(va, Bot)] @ \'))) \ (\ea. nthtriple (cCons (\ \) (Inr e) \) i = (\ (map (\v. (v, Bot)) (fst3 ea) @ \'), Inr ea, \ (map (\v. (v, Top)) (thd3 ea) @ \')))" proof (cases i) case 0 show ?thesis apply (unfold 0) apply (intro exI disjI2) apply (unfold nthtriple.simps(1)) apply (intro tripleI) apply (unfold fst3_def snd3_def thd3_def) apply (simp_all) thm abs_equiv [OF guhla(1)] apply (rule abs_equiv[OF guhla(1)]) proof - from abs_equiv[OF guhla(2)] have "\ (\ (pre \)) = \ ([(v, Top). v\ snd (snd e)] @ \')" by auto with abs_conc[of "pre \"] show "pre \ = \ ([(v, Top). v\ snd (snd e)] @ \')" by auto qed next case (Suc i') with vzoyp have "i' < chainlen \" by auto show ?thesis apply (unfold Suc) apply (unfold nthtriple.simps(2)) apply (rule xautg[OF `i' < chainlen \`]) done qed qed lemma list_subseteq: fixes X shows "\Y. \ distinct X ; set X \ set Y \ \ length X \ length Y" proof (induct X) case (Cons x X) from Cons.prems(1) have zeiaq: "distinct X" and gpzjd: "x \ set X" by auto from Cons.prems(2) have "set X \ set Y" and gnvih: "x \ set Y" by auto from this(1) have nfvso: "set X - {x} \ set Y - {x}" by auto from nfvso gpzjd have "set X \ set Y - {x}" by auto moreover from nfvso gnvih have "set Y - {x} \ set (remove1 x Y)" by auto ultimately have "set X \ set (remove1 x Y)" by auto from Cons.hyps[OF zeiaq this] have "length X \ length (remove1 x Y)" by auto hence "1 + length X \ 1 + length (remove1 x Y)" by auto hence fuwjo: "length (x#X) \ 1 + length (remove1 x Y)" by auto from gnvih have "length (remove1 x Y) = length Y - 1" using length_remove1[of x Y] by auto with fuwjo have fnowt: "length (x#X) \ 1 + (length Y - 1)" by auto from gnvih have "length Y \ 0" by auto with fnowt show "length (x#X) \ length Y" by arith qed (auto) lemma length_listdiff: fixes X Y assumes "distinct X" shows "\distinct Y; set Y \ set X \ \ length (listdiff X Y) = length X - length Y" proof (induct Y) case Nil thus ?case unfolding listdiff_def by auto next case (Cons y Y) from assms have "distinct (listdiff X Y)" unfolding listdiff_def by auto from distinct_remove1_removeAll[OF this] have ptcbz: "remove1 y (listdiff X Y) = removeAll y (listdiff X Y)" by auto from Cons.prems have "distinct Y" "set Y \ set X" "y \ set Y" by auto from Cons.hyps[OF this(1) this(2)] have olttc: "length (listdiff X Y) = length X - length Y" by auto from Cons.prems(2) have "y \ set X" by auto with `y \ set Y` have jgvgk: "y \ set (listdiff X Y)" unfolding listdiff_def by auto have "length (listdiff X (y # Y)) = length (foldr removeAll (y # Y) X)" unfolding listdiff_is_fold_rem by auto also have "... = length (removeAll y (foldr removeAll Y X))" by auto also have "... = length (removeAll y (listdiff X Y))" unfolding listdiff_is_fold_rem by auto also have "... = length (remove1 y (listdiff X Y))" using ptcbz by auto also have "... = length (listdiff X Y) - 1" unfolding length_remove1 using jgvgk by auto also have "... = length X - length Y - 1" using olttc by auto also have "... = length X - length (y#Y)" by auto finally have "length (listdiff X (y # Y)) = length X - length (y # Y)" by auto thus ?case by auto qed lemma diff_then_append: fixes X Y assumes "distinct X" shows "\ set Y \ set X ; distinct Y \ \ X <~~> Y @ (listdiff X Y)" proof (induct Y) case Nil show "X <~~> [] @ listdiff X []" unfolding listdiff_def by auto next case (Cons y Y) from Cons.prems have "y \ set Y" and "distinct Y" and "y \ set X" and "set Y \ set X" by (metis distinct.simps(2), metis Cons(3) distinct.simps(2), metis Cons(2) ListMem_iff elem subsetD, auto) from Cons.hyps [OF this(4) this(2)] have "Y @ listdiff X Y <~~> X" using perm_sym by auto have "distinct (listdiff X Y)" using assms unfolding listdiff_def by auto let ?rhs = "(y # Y) @ listdiff X (y # Y)" have "?rhs = y # Y @ foldr removeAll (y#Y) X" unfolding listdiff_is_fold_rem by auto also have "... = y # Y @ (removeAll y (foldr removeAll Y X))" by auto also have "... = y # Y @ (removeAll y (listdiff X Y))" unfolding listdiff_is_fold_rem by auto also have "... = y # Y @ (remove1 y (listdiff X Y))" unfolding distinct_remove1_removeAll[OF `distinct (listdiff X Y)`] by auto also have "... = y # (remove1 y (Y @ (listdiff X Y)))" unfolding remove1_append using `y \ set Y` by auto also have "... <~~> y # (remove1 y X)" by (intro perm.Cons perm_remove_perm, rule `Y @ listdiff X Y <~~> X`) finally have "?rhs <~~> y # (remove1 y X)" by auto moreover have "y # (remove1 y X) <~~> X" using `y \ set X` by (metis perm_remove perm_sym) ultimately have "?rhs <~~> X" by auto thus ?case using perm_sym by auto qed lemma map_fst_pair: fixes a x shows "map fst (map (\v. (v, a)) x) = x" by (induct x, auto) lemma distinct_initials: fixes V \ E assumes "wf_dia (Graph V \ E)" shows "distinct (initials (Graph V \ E))" proof - from wf_dia_inv[OF assms] have "distinct V" by auto thus ?thesis unfolding initials.simps by auto qed lemma distinct_terminals: fixes V \ E assumes "wf_dia (Graph V \ E)" shows "distinct (terminals (Graph V \ E))" proof - from wf_dia_inv[OF assms] have "distinct V" by auto thus ?thesis unfolding terminals.simps by auto qed lemma map_filter_is_concat_map: fixes P X f shows "map f (filter P X) = concat (map (\x. if P x then [f x] else []) X)" (is "?lhs = ?rhs") proof - have "?lhs = map f (concat (map (\x. if P x then [x] else []) X))" by (induct X, auto) also have "... = concat (map (map f) (map (\x. if P x then [x] else []) X))" unfolding map_concat by auto also have "... = concat (map ((map f) \ (\x. if P x then [x] else [])) X)" unfolding map_map by auto also have "... = concat (map (\x. (map f) (if P x then [x] else [])) X)" unfolding comp_def by auto also have "... = concat (map (\x. if P x then (map f) [x] else (map f) []) X)" unfolding if_distrib by auto also have "... = ?rhs" unfolding map.simps by auto finally show ?thesis by auto qed text {* If two lists have the same sets of elements, and neither has any duplicates, then they are permutations of each other. *} lemma permI [intro]: fixes X Y assumes "set X = set Y" and "distinct X" and "distinct Y" shows "X <~~> Y" proof - have "X = remdups X" using distinct_remdups_id[OF assms(2), symmetric] by auto also have "... <~~> remdups Y" using eq_set_perm_remdups[OF assms(1)] by auto also have "... = Y" using distinct_remdups_id[OF assms(3)] by auto finally show ?thesis by auto qed lemma if_and: fixes p q a b shows "(if p \ q then a else b) = (if p then if q then a else b else b)" by auto lemma set_listdiff: fixes X Y shows "set (listdiff X Y) = set X - set Y" by (induct X, unfold listdiff_def, auto) lemma listdiff_perm: fixes X Y Z assumes "X <~~> Y" assumes "distinct X" "distinct Y" shows "listdiff X Z <~~> listdiff Y Z" proof - from assms(1) have "set X = set Y" using perm_set_eq by auto hence "set (listdiff X Z) = set (listdiff Y Z)" using set_listdiff by metis moreover from assms(2) assms(3) have "distinct (listdiff X Z)" "distinct (listdiff Y Z)" unfolding listdiff_def by auto ultimately show "listdiff X Z <~~> listdiff Y Z" by (intro permI, auto) qed lemma inj_imp_inj_on: fixes f X assumes "inj f" shows "inj_on f X" by (metis subset_UNIV subset_inj_on assms) lemma map_perm: fixes f X Y assumes "X <~~> Y" shows "map f X <~~> map f Y" using assms by (induct rule:perm.induct, auto) lemma listdiff_append: fixes X Y Z shows "listdiff (X @ Y) Z = (listdiff X Z) @ (listdiff Y Z)" unfolding listdiff_def by auto lemma listdiff_id: fixes X Y assumes "set X \ set Y = {}" shows "listdiff X Y = X" unfolding listdiff_def using assms by (induct X, auto) lemma bigunion_subset: "\X Y S. X \ Y \ (\x\X. S) \ (\x\Y. S)" by auto lemma all_but_one: fixes P a X assumes "a \ X" shows "(P a \ (\x\X. x\a \ P x)) = (\x\X. P x)" by (metis assms) lemma map_listdiff_inj: fixes f X Y assumes "inj f" shows "map f (listdiff X Y) = listdiff (map f X) (map f Y)" unfolding listdiff_is_fold_rem by (induct Y, auto simp add: map_removeAll_inj[OF assms]) lemma wf_chains2: fixes k shows "\S V \ E \. \ distinct S ; set S \ set (initials (Graph V \ E)) ; wf_dia (Graph V \ E) ; \ \ rawchains2 S (Graph V \ E) ; length V + length E = k + length S \ \ wf_rawchain \ \ \ (post \) <~~> [(v,Bot). v \ terminals (Graph V \ E)]" proof (induct k) case 0 let ?\1 = "[(v,Top). v \ initials (Graph V \ E), v \ set S]" let ?\2 = "[(v,Bot). v \ S]" let ?\ = "?\1 @ ?\2" have tklgv: "distinct ?\" proof - let ?\1 = "[(v,Top). v \ initials (Graph V \ E), v \ set S]" let ?\2 = "[(v,Bot). v \ S]" have "distinct ?\1" apply (unfold map_filter_is_concat_map [symmetric]) apply (unfold distinct_map) apply (intro conjI) apply (intro distinct_filter) apply (rule distinct_initials[OF "0.prems"(3)]) apply (unfold inj_on_def, simp) done moreover have "distinct ?\2" apply (unfold distinct_map) apply (intro conjI) apply (rule "0.prems"(1)) apply (unfold inj_on_def, simp) done ultimately show ?thesis unfolding distinct_append by auto qed from wf_dia_inv [OF "0.prems"(3)] have iecss: "set (initials (Graph V \ E)) \ set V" and nsckf: "distinct V" by auto from iecss and "0.prems"(2) have hfgey: "set S \ set V" by auto from list_subseteq[OF "0.prems"(1) this] have dwcgc: "length S \ length V" by auto from "0.prems"(5) have xglfj: "length V + length E = length S" by auto with dwcgc have pqshe: "length E = 0" by arith with xglfj have "length V = length S" by auto with distinct_card[OF nsckf] and distinct_card[OF "0.prems"(1)] have rophe: "card (set V) = card (set S)" by auto have hpjzb: "set V = set S" proof (rule ccontr) assume "set V \ set S" with hfgey have "finite (set V)" "set S \ set V" by auto from psubset_card_mono[OF this] have "card (set S) < card (set V)" by auto with rophe show False by auto qed with iecss and "0.prems"(2) have dakuy: "set S = set (initials (Graph V \ E))" and iuqxi: "set (initials (Graph V \ E)) = set V" by auto from pqshe have wsegy: "set E = {}" by auto hence hkimj: "E = []" by auto have xfbme: "?\1 = []" using dakuy by auto from no_edges_imp_all_nodes_terminal and no_edges_imp_all_nodes_initial and hkimj have hjaws: "terminals (Graph V \ E) = initials (Graph V \ E)" by auto from hjaws dakuy have qoeqk: "set S = set (terminals (Graph V \ E))" by auto hence socgi: "set ?\2 = set [(v,Bot). v \ terminals (Graph V \ E)]" by auto have "?\2 <~~> [(v,Bot). v \ terminals (Graph V \ E)]" apply (intro permI) apply (rule socgi) apply (metis "0.prems"(1) distinct_zipI1 map_fst_pair zip_map_fst_snd) apply (metis (no_types) `length V = length S` append_Nil card_distinct distinct_card hjaws hkimj length_map no_edges_imp_all_nodes_initial socgi tklgv xfbme) done hence hislv: "?\ <~~> [(v,Bot). v \ terminals (Graph V \ E)]" by (metis append_Nil xfbme) hence "set (map fst ?\2) = set (terminals (Graph V \ E))" by (metis qoeqk map_fst_pair) from eq_set_perm_remdups[OF this] have cpzwf: "remdups (map fst ?\2) <~~> remdups (terminals (Graph V \ E))" by auto have "fst \ (\v. (v,Bot)) = id" by auto hence "map fst ?\2 = S" by (metis map.id map_map map_fst_pair) with "0.prems"(1) have xecbe: "distinct (map fst ?\2)" by auto hence uismw: "distinct (map fst ?\)" using xfbme by (metis append_Nil) from distinct_remdups_id[OF xecbe] and distinct_remdups_id[OF distinct_terminals[OF "0.prems"(3)]] and cpzwf have arvry: "map fst ?\2 <~~> terminals (Graph V \ E)" by metis have eyzmp: "map fst ?\ <~~> terminals (Graph V \ E)" using xfbme arvry by (metis append_Nil) from "0.prems"(4) obtain \ where mkaec: "\ = mk (cNil (\ ?\)) \" and "\ \ lins2 S (Graph V \ E)" unfolding rawchains2_def by auto from this(2) have "distinct \" "set \ = Inl ` (set V - set S) \ Inr ` set E" "\i j v e. i < length \ \ j < length \ \ \ ! i = Inl v \ \ ! j = Inr e \ v \ set (fst3 e) \ i < j" "\j k w e. j < length \ \ k < length \ \ \ ! j = Inr e \ \ ! k = Inl w \ w \ set (thd3 e) \ j < k" apply (unfold lins2.simps) apply (elim CollectE conjE, assumption+)+ done from this(2) and hpjzb and wsegy have "set \ = {}" by auto hence "\ = []" by auto with mkaec have smliq: "\ = cNil (\ ?\)" unfolding mk_def by auto hence vqpgq: "wf_rawchain \" using wf_rawchain_cnil by auto from smliq have hhfar: "post \ = (\ ?\)" by auto hence "\ (post \) = \ (\ ?\)" by auto also have "... <~~> ?\" using conc_abs[of "?\"] by auto finally have ifega: "\ (post \) <~~> ?\" by auto with hislv have "\ (post \) <~~> [(v,Bot). v \ terminals (Graph V \ E)]" by auto with vqpgq show ?case by auto next case (Suc k) let ?\ = "[(v,Top). v \ initials (Graph V \ E), v \ set S] @ [(v,Bot). v \ S]" have tklgv: "distinct ?\" proof - let ?\1 = "[(v,Top). v \ initials (Graph V \ E), v \ set S]" let ?\2 = "[(v,Bot). v \ S]" have "distinct ?\1" apply (unfold map_filter_is_concat_map [symmetric]) apply (unfold distinct_map) apply (intro conjI) apply (intro distinct_filter) apply (rule distinct_initials[OF Suc.prems(3)]) apply (unfold inj_on_def, simp) done moreover have "distinct ?\2" apply (unfold distinct_map) apply (intro conjI) apply (rule Suc.prems(1)) apply (unfold inj_on_def, simp) done ultimately show ?thesis unfolding distinct_append by auto qed from Suc.prems(4) obtain \ where mkaec: "\ = mk (cNil (\ ?\)) \" and "\ \ lins2 S (Graph V \ E)" unfolding rawchains2_def by auto from this(2) have ujyes: "distinct \" and aqxbk: "set \ = Inl ` (set V - set S) \ Inr ` set E" and myqpt: "\i j v e. i < length \ \ j < length \ \ \ ! i = Inl v \ \ ! j = Inr e \ v \ set (fst3 e) \ i < j" and zjtlg: "\j k w e. j < length \ \ k < length \ \ \ ! j = Inr e \ \ ! k = Inl w \ w \ set (thd3 e) \ j < k" apply (unfold lins2.simps) apply (elim CollectE conjE, assumption+)+ done from wf_dia_inv [OF Suc.prems(3)] have jupgv: "set (initials (Graph V \ E)) \ set V" and nsckf: "distinct V" and xfrmj: "acyclicity E" and fivyp: "linearity E" and joven: "\e. e \ set E \ distinct (fst3 e) \ set (fst3 e) \ set V" and tbdcm: "\e. e \ set E \ distinct (thd3 e) \ set (thd3 e) \ set V" by auto from this(1) and Suc.prems(2) have hfgey: "set S \ set V" by auto show "wf_rawchain \ \ \ (post \) <~~> [(v,Bot). v \ terminals (Graph V \ E)]" proof (cases "\") case Nil hence "set \ = {}" by auto hence "Inl ` (set V - set S) \ Inr ` set E = {}" using aqxbk by auto hence "Inl ` (set V - set S) = {}" and "Inr ` set E = {}" by auto hence "(set V - set S) = {}" and "set E = {}" by auto hence "set V \ set S" and ruaau: "E = []" by auto with hfgey have "set V = set S" by auto hence "card (set V) = card (set S)" by auto with distinct_card[OF nsckf] and distinct_card[OF Suc.prems(1)] and ruaau have "length V = length S" and "length E = 0" by auto with Suc.prems(5) have "Suc k = 0" by auto hence False by auto thus ?thesis by auto next case (Cons x \') hence yketi: "\ = x # \'" by auto let ?f = "\\. sum_case (\v. cSnoc \ (Inl v) (\ ((listdiff (\ (post \)) [(v,Top)]) @ [(v,Bot)]))) (\e. cSnoc \ (Inr e) (\ ((listdiff (\ (post \)) [(v,Bot) . v \ fst3 e]) @ [(v,Top) . v \ thd3 e])))" from yketi mkaec have "\ = foldl ?f (cNil (\ ?\)) (x # \')" unfolding mk_def by auto hence ulrqd: "\ = foldl ?f (?f (cNil (\ ?\)) x) \'" by (unfold foldl.simps(2), auto) show ?thesis proof (cases x) case (Inl v) hence hnqdb: "x = Inl v" by auto with ulrqd have "\ = foldl ?f (?f (cNil (\ ?\)) (Inl v)) \'" by auto hence "\ = foldl ?f (cSnoc (cNil (\ ?\)) (Inl v) (\ ((listdiff (\ (post (cNil (\ ?\)))) [(v,Top)]) @ [(v,Bot)]))) \'" by simp hence "\ = foldl ?f (cCons (\ ?\) (Inl v) (cNil (\ ((listdiff (\ (\ ?\)) [(v,Top)]) @ [(v,Bot)])))) \'" by auto hence "\ = mk (cCons (\ ?\) (Inl v) (cNil (\ ((listdiff (\ (\ ?\)) [(v,Top)]) @ [(v,Bot)])))) \'" unfolding mk_def by auto hence lmkbq: "\ = cCons (\ ?\) (Inl v) (mk (cNil (\ ((listdiff (\ (\ ?\)) [(v,Top)]) @ [(v,Bot)]))) \')" (is "_ = cCons _ _ ?\'") using mk_ccons by auto from yketi hnqdb have "(Inl v) \ set \" by auto with aqxbk have "v \ set V - set S" by auto hence cygbs: "v \ set V" and kaucq: "v \ set S" by auto from kaucq and Suc.prems(1) have cuztr: "distinct (v#S)" by auto have bjmwl: "v \ set (initials (Graph V \ E))" proof (rule ccontr) assume "v \ set (initials (Graph V \ E))" hence "v \ set [v\V . v \ set (concat (map thd3 E))]" by auto with cygbs have "v \ set (concat (map thd3 E))" by auto then obtain e where "e \ set E" and sscmh: "v \ set (thd3 e)" by auto from aqxbk this(1) have "Inr e \ set \" by auto then obtain j where "\!j = Inr e" and "j < length \" unfolding in_set_conv_nth by auto moreover from yketi hnqdb have "\!0 = Inl v" and "0 < length \" by auto ultimately have "j < 0" using zjtlg sscmh by metis thus False by auto qed with Suc.prems(2) have fthcv: "set (v#S) \ set (initials (Graph V \ E))" by auto have "((listdiff (\ (\ ([(w,Top). w \ initials (Graph V \ E), w \ set S] @ [(w,Bot). w \ S]))) [(v, Top)]) @ [(v, Bot)]) <~~> ([(w,Top). w \ initials (Graph V \ E), w \ set (v#S)] @ [(w,Bot). w \ (v#S)])" (is "?lhs <~~> ?rhs") proof - have wargt: "inj (\w. (w, Top))" by (metis (no_types) Pair_inject injI) have kblbw: "\X y. listdiff X [y] = removeAll y X" unfolding listdiff_is_fold_rem by auto have pudxd: "(v,Top) \ set (map (\w. (w, Bot)) S)" by auto have "?rhs = concat (map (\w. if w \ v \ w \ set S then [(w, Top)] else []) (initials (Graph V \ E))) @ map (\w. (w, Bot)) (v#S)" by auto also have "... = map (\w. (w, Top)) (filter (\w. w \ v \ w \ set S) (initials (Graph V \ E))) @ map (\w. (w, Bot)) (v#S)" unfolding map_filter_is_concat_map by auto also have "... = map (\w. (w, Top)) (filter (op \ v) (filter (\w. w \ set S) (initials (Graph V \ E)))) @ map (\w. (w, Bot)) (v#S)" unfolding filter_filter conj_commute neq_commute by auto also have "... = map (\w. (w, Top)) (removeAll v [w\initials (Graph V \ E) . w \ set S]) @ map (\w. (w, Bot)) (v#S)" unfolding removeAll_filter_not_eq by auto also have "... = removeAll (v, Top) (map (\w. (w, Top)) [w\initials (Graph V \ E) . w \ set S]) @ map (\w. (w, Bot)) (v#S)" unfolding map_removeAll_inj[OF wargt] by auto also have "... = removeAll (v, Top) (map (\w. (w, Top)) [w\initials (Graph V \ E) . w \ set S]) @ [(v,Bot)] @ map (\w. (w, Bot)) S" by auto also have "... <~~> removeAll (v, Top) (map (\w. (w, Top)) [w\initials (Graph V \ E) . w \ set S]) @ map (\w. (w, Bot)) S @ [(v,Bot)]" by (metis perm_append1 perm_append_swap) also have "... = removeAll (v, Top) (map (\w. (w, Top)) [w\initials (Graph V \ E) . w \ set S]) @ removeAll (v, Top) (map (\w. (w, Bot)) S) @ [(v, Bot)]" unfolding removeAll_id[OF pudxd] by auto also have "... = removeAll (v, Top) ((map (\w. (w, Top)) [w\initials (Graph V \ E) . w \ set S]) @ (map (\w. (w, Bot)) S)) @ [(v, Bot)]" by auto also have "... = (listdiff ((map (\w. (w, Top)) [w\initials (Graph V \ E) . w \ set S]) @ (map (\w. (w, Bot)) S)) [(v,Top)]) @ [(v, Bot)]" unfolding kblbw by auto finally have "?rhs <~~> (listdiff ((([(w,Top). w \ initials (Graph V \ E), w \ set S] @ [(w,Bot). w \ S]))) [(v, Top)]) @ [(v, Bot)]" unfolding map_filter_is_concat_map by auto moreover have "(listdiff ((([(w,Top). w \ initials (Graph V \ E), w \ set S] @ [(w,Bot). w \ S]))) [(v, Top)]) @ [(v, Bot)] <~~> ?lhs" proof (intro perm_append2 listdiff_perm) show "([(w,Top). w \ initials (Graph V \ E), w \ set S] @ [(w,Bot). w \ S]) <~~> \ (\ ([(w,Top). w \ initials (Graph V \ E), w \ set S] @ [(w,Bot). w \ S]))" using perm_sym[OF conc_abs[of "[(w,Top). w \ initials (Graph V \ E), w \ set S] @ [(w,Bot). w \ S]"]] by auto next show "distinct ([(w,Top). w \ initials (Graph V \ E), w \ set S] @ [(w,Bot). w \ S])" by (metis tklgv) next show "distinct (\ (\ ([(w,Top). w \ initials (Graph V \ E), w \ set S] @ [(w,Bot). w \ S])))" by (metis (no_types) conc_abs listdiff_def map_filter_is_concat_map maps_def perm_distinct_iff tklgv) qed ultimately have "?rhs <~~> ?lhs" by (rule perm.trans) thus ?thesis by (rule perm_sym) qed hence jtgmn: "\ ((listdiff (\ (\ ([(w,Top). w \ initials (Graph V \ E), w \ set S] @ [(w,Bot). w \ S]))) [(v, Top)]) @ [(v, Bot)]) = \ ([(w,Top). w \ initials (Graph V \ E), w \ set (v#S)] @ [(w,Bot). w \ (v#S)])" using abs_equiv by auto have jvlal: "?\' \ rawchains2 (v#S) (Graph V \ E)" unfolding rawchains2_def unfolding jtgmn proof (intro CollectI exI[of _ \'] conjI, simp, unfold lins2.simps(1), intro CollectI conjI) from ujyes yketi show "distinct \'" by auto next show "set \' = Inl ` (set V - set (v#S)) \ Inr ` set E" (is "?lhs = ?rhs") proof - have "?rhs = Inl ` (set V - set S - {v}) \ Inr ` set E" by auto also have "... = set \ - {Inl v}" using aqxbk by auto also have "... = set (removeAll (Inl v) \)" unfolding set_removeAll by auto also have "... = set (remove1 (Inl v) \)" using distinct_remove1_removeAll[OF ujyes] by auto also have "... = set (remove1 (Inl v) ((Inl v)#\'))" using yketi hnqdb by auto also have "... = ?lhs" by auto finally show ?thesis by auto qed next show "\i j v e. i < length \' \ j < length \' \ \' ! i = Inl v \ \' ! j = Inr e \ v \ set (fst3 e) \ i < j" proof (intro allI impI, (erule conjE)+) fix i j v e assume "i < length \'" and "j < length \'" and "\' ! i = Inl v" and "\' ! j = Inr e" hence "i+1 < length \" "j+1 < length \" "\!(i+1) = Inl v" "\!(j+1) = Inr e" using yketi by auto moreover assume "v \ set (fst3 e)" ultimately have "i+1 < j+1" using myqpt by metis thus "i < j" by auto qed next show "\j k w e. j < length \' \ k < length \' \ \' ! j = Inr e \ \' ! k = Inl w \ w \ set (thd3 e) \ j < k" proof (intro allI impI, (erule conjE)+) fix j k w e assume "j < length \'" and "k < length \'" and "\' ! j = Inr e" and "\' ! k = Inl w" hence "j+1 < length \" "k+1 < length \" "\!(j+1) = Inr e" "\!(k+1) = Inl w" using yketi by auto moreover assume "w \ set (thd3 e)" ultimately have "j+1 < k+1" using zjtlg by metis thus "j < k" by auto qed qed from Suc.prems(5) have favzl: "length V + length E = k + length (v#S)" by auto from Suc.hyps[OF cuztr fthcv Suc.prems(3) jvlal favzl] have mapkz: "wf_rawchain ?\'" and uzlwq: "\ (post ?\') <~~> [(v,Bot). v \ terminals (Graph V \ E)]" by auto let ?\' = "remove1 (v,Top) ?\" from bjmwl and kaucq have "(v,Top) \ set ?\" by auto from perm_remove[OF this] have ppefa: "?\ <~~> [(v, Top)] @ ?\'" by auto from tklgv have zuuso: "distinct (\ (\ ?\))" by (metis (no_types) conc_abs perm_distinct_iff) have vpcvj: "pre ?\' = \ ((listdiff (\ (\ ?\)) [(v,Top)]) @ [(v,Bot)])" using pre_mk by auto have "listdiff (\ (\ ?\)) [(v,Top)] = removeAll (v,Top) (\ (\ ?\))" using listdiff_is_fold_rem[of "(\ (\ ?\))" "[(v,Top)]"] by auto also have "... = remove1 (v,Top) (\ (\ ?\))" using distinct_remove1_removeAll[OF zuuso] by auto also have "... <~~> remove1 (v,Top) ?\" by (rule perm_remove_perm, rule conc_abs) finally have "listdiff (\ (\ ?\)) [(v,Top)] <~~> ?\'" by auto hence "listdiff (\ (\ ?\)) [(v,Top)] @ [(v,Bot)] <~~> ?\' @ [(v,Bot)]" by auto from abs_equiv[OF this] have "\ (listdiff (\ (\ ?\)) [(v,Top)] @ [(v,Bot)]) = \ (?\' @ [(v,Bot)])" by auto with vpcvj have "pre ?\' = \ (?\' @ [(v,Bot)])" by auto hence "\ (pre ?\') <~~> ?\' @ [(v,Bot)]" using conc_abs by auto moreover have "?\' @ [(v,Bot)] <~~> [(v, Bot)] @ ?\'" by (metis perm_append_swap) ultimately have otqat: "\ (pre ?\') <~~> [(v, Bot)] @ ?\'" by (rule perm.trans) from wf_rawchain_ccons_inl[OF ppefa otqat mapkz] lmkbq have "wf_rawchain \" by auto moreover from lmkbq have "post \ = post ?\'" by auto with uzlwq have "\ (post \) <~~> [(v,Bot). v \ terminals (Graph V \ E)]" by auto ultimately show ?thesis by auto next case (Inr e) hence hnqdb: "x = Inr e" by auto with ulrqd have "\ = foldl ?f (?f (cNil (\ ?\)) (Inr e)) \'" by auto hence "\ = foldl ?f (cSnoc (cNil (\ ?\)) (Inr e) (\ ((listdiff (\ (post (cNil (\ ?\)))) [(v,Bot). v \ fst3 e]) @ [(v,Top). v \ thd3 e]))) \'" by simp hence "\ = foldl ?f (cCons (\ ?\) (Inr e) (cNil (\ ((listdiff (\ (\ ?\)) [(v,Bot). v\fst3 e]) @ [(v,Top). v \ thd3 e])))) \'" by auto hence "\ = mk (cCons (\ ?\) (Inr e) (cNil (\ ((listdiff (\ (\ ?\)) [(v,Bot). v\fst3 e]) @ [(v,Top). v\thd3 e])))) \'" unfolding mk_def by auto hence lmkbq: "\ = cCons (\ ?\) (Inr e) (mk (cNil (\ ((listdiff (\ (\ ?\)) [(v,Bot). v\fst3 e]) @ [(v,Top). v\thd3 e]))) \')" (is "_ = cCons _ _ ?\'") using mk_ccons by auto from yketi hnqdb have "(Inr e) \ set \" by auto with aqxbk have "e \ set E" by auto with joven [OF this] tbdcm[OF this] have rodmt: "set (fst3 e) \ set V" and bjcek: "distinct (fst3 e)" and ptyhv: "set (thd3 e) \ set V" and nyneq: "distinct (thd3 e)" by auto let ?\' = "listdiff ?\ [(v,Bot). v\fst3 e]" have bjmwl: "set (fst3 e) \ set S" proof (intro subsetI) fix v assume nloqn: "v \ set (fst3 e)" with rodmt have xhrjc: "v \ set V" by auto show "v \ set S" proof (rule ccontr) assume "v \ set S" with xhrjc have "v \ set V - set S" by auto with aqxbk have "Inl v \ set \" by auto then obtain i where "\!i = Inl v" and "i < length \" unfolding in_set_conv_nth by auto moreover from yketi hnqdb have "\!0 = Inr e" and "0 < length \" by auto ultimately have "i<0" using nloqn myqpt by metis thus False by auto qed qed let ?V' = "listdiff V (fst3 e)" let ?E' = "listdiff E [e]" let ?S' = "listdiff S (fst3 e)" from Suc.prems(1) have cuztr: "distinct (?S')" unfolding listdiff_def by auto have fthcv: "set (?S') \ set (initials (Graph ?V' \ ?E'))" proof (intro subsetI) fix v assume "v \ set (listdiff S (fst3 e))" hence "v \ set S - set (fst3 e)" by (unfold set_listdiff, auto) hence biyvo: "v \ set S" and mpyux: "v \ set (fst3 e)" by auto from biyvo have "v \ set (initials (Graph V \ E))" using Suc.prems(2) by auto hence "v \ set V" and dnwmt: "v \ set (concat (map thd3 E))" by auto from this(1) and mpyux have "v \ set V - set (fst3 e)" by auto hence sdrkm: "v \ set (listdiff V (fst3 e))" by (unfold set_listdiff, auto) have uyyio: "v \ set (concat (map thd3 (listdiff E [e])))" proof (rule ccontr) assume "\ v \ set (concat (map thd3 (listdiff E [e])))" hence "v \ set (concat (map thd3 (listdiff E [e])))" by auto then obtain f where "f \ set (listdiff E [e])" and gopfu: "v \ set (thd3 f)" by auto from this(1) have "f \ set E" and "f\e" by (unfold set_listdiff, auto) with gopfu have "v \ set (concat (map thd3 E))" by auto with dnwmt show False by auto qed from sdrkm uyyio show "v \ set (initials (Graph (listdiff V (fst3 e)) \ (listdiff E [e])))" by auto qed from fivyp have brrov: "distinct E" and rwiiv: "\e f.\ e\set E; f\set E; e \ f \ \ set (fst3 e) \ set (fst3 f) = {} \ set (thd3 e) \ set (thd3 f) = {}" unfolding linearity_def by auto have shifk: "wf_dia (Graph ?V' \ ?E')" proof (intro wf_dia) show "distinct (listdiff V (fst3 e))" unfolding listdiff_def using nsckf by auto next show "acyclicity (listdiff E [e])" using xfrmj unfolding acyclicity_def listdiff_def proof (elim acyclic_subset) have "set [x\E . x \ set [e]] \ set E" by auto from bigunion_subset[OF this] show "(\e\set [x\E . x \ set [e]]. \v\set (fst3 e). \w\set (thd3 e). {(v, w)}) \ (\e\set E. \v\set (fst3 e). \w\set (thd3 e). {(v, w)})" by auto qed next show "linearity (listdiff E [e])" by (unfold linearity_def, intro conjI, unfold listdiff_def, simp add: brrov, intro ballI impI conjI, (simp add: rwiiv)+) next fix f assume "f \ set (listdiff E [e])" hence "f \ set E" and "f \ e" unfolding listdiff_def by auto from joven[OF this(1)] have "set (fst3 f) \ set V" and bqbem: "distinct (fst3 f)" by auto moreover have "set (fst3 f) \ set (fst3 e) = {}" using rwiiv[OF `f \ set E` `e \ set E` `f \ e`] by auto ultimately have "set (fst3 f) \ (set V - set (fst3 e))" by auto also have "... = (set (listdiff V (fst3 e)))" unfolding listdiff_def by auto finally have "(set (fst3 f)) \ (set (listdiff V (fst3 e)))" by auto thus "distinct (fst3 f) \ (set (fst3 f)) \ (set (listdiff V (fst3 e)))" using bqbem by auto next fix f assume "f \ set (listdiff E [e])" hence "f \ set E" and "f \ e" unfolding listdiff_def by auto from tbdcm[OF this(1)] have "set (thd3 f) \ set V" and nxvti: "distinct (thd3 f)" by auto moreover have "set (thd3 f) \ set (fst3 e) = {}" proof (rule ccontr) assume "set (thd3 f) \ set (fst3 e) \ {}" then obtain w where "w \ set (thd3 f)" and lghfv: "w \ set (fst3 e)" by auto from this(1) have "w \ set (initials (Graph V \ E))" using `f \ set E` by auto moreover from bjmwl lghfv Suc.prems(2) have "w \ set (initials (Graph V \ E))" by auto ultimately show False by auto qed ultimately have "set (thd3 f) \ (set V - set (fst3 e))" by auto also have "... = (set (listdiff V (fst3 e)))" unfolding listdiff_def by auto finally have "(set (thd3 f)) \ (set (listdiff V (fst3 e)))" by auto thus "distinct (thd3 f) \ (set (thd3 f)) \ (set (listdiff V (fst3 e)))" using nxvti by auto qed have "((listdiff (\ (\ ([(w,Top). w \ initials (Graph V \ E), w \ set S] @ [(w,Bot). w \ S]))) [(v, Bot). v\fst3 e]) @ [(v, Top). v\thd3 e]) <~~> ([(w,Top). w \ initials (Graph ?V' \ ?E'), w \ set ?S'] @ [(w,Bot). w \ ?S'])" (is "?lhs <~~> ?rhs") proof - have wargt: "\a. inj (\w. (w, a))" by (metis (no_types) Pair_inject injI) have ohruf: "set (map (\w. (w, Top)) (filter (\w. w \ set S \ w \ set (fst3 e)) (initials (Graph (listdiff V (fst3 e)) \ (listdiff E [e]))))) \ set (map (\w. (w, Bot)) (fst3 e)) = {}" by auto have jxzvk: "set (map (\v. (v, Top)) (thd3 e)) \ set (map (\v. (v, Bot)) (fst3 e)) = {}" by auto have "?rhs = map (\w. (w, Top)) (filter (\w. w \ set (listdiff S (fst3 e))) (initials (Graph (listdiff V (fst3 e)) \ (listdiff E [e])))) @ map (\w. (w, Bot)) (listdiff S (fst3 e))" unfolding map_filter_is_concat_map by auto also have "... = map (\w. (w, Top)) (filter (\w. w \ (set S - set (fst3 e))) (initials (Graph (listdiff V (fst3 e)) \ (listdiff E [e])))) @ map (\w. (w, Bot)) (listdiff S (fst3 e))" unfolding listdiff_def by auto also have "... = map (\w. (w, Top)) (filter (\w. w \ set S \ w \ set (fst3 e)) (initials (Graph (listdiff V (fst3 e)) \ (listdiff E [e])))) @ map (\w. (w, Bot)) (listdiff S (fst3 e))" by auto also have "... = map (\w. (w, Top)) (filter (\w. w \ set S \ w \ set (fst3 e)) (initials (Graph (listdiff V (fst3 e)) \ (listdiff E [e])))) @ listdiff (map (\w. (w, Bot)) S) (map (\w. (w, Bot)) (fst3 e))" using map_listdiff_inj[OF wargt[of "Bot"]] by auto also have "... = listdiff (map (\w. (w, Top)) (filter (\w. w \ set S \ w \ set (fst3 e)) (initials (Graph (listdiff V (fst3 e)) \ (listdiff E [e]))))) (map (\w. (w, Bot)) (fst3 e)) @ listdiff (map (\w. (w, Bot)) S) (map (\w. (w, Bot)) (fst3 e))" unfolding listdiff_id[OF ohruf] by auto also have "... = listdiff ((map (\w. (w, Top)) (filter (\w. w \ set S \ w \ set (fst3 e)) (initials (Graph (listdiff V (fst3 e)) \ (listdiff E [e]))))) @ (map (\w. (w, Bot)) S)) (map (\w. (w, Bot)) (fst3 e))" unfolding listdiff_append by auto also have "... <~~> listdiff (((map (\w. (w,Top)) (filter (\w. w\set S) (initials (Graph V \ E)))) @ map (\w. (w, Bot)) S) @ (map (\v. (v, Top)) (thd3 e))) (map (\v. (v, Bot)) (fst3 e))" proof (intro listdiff_perm) have "map (\w. (w, Top)) [w\initials (Graph (listdiff V (fst3 e)) \ (listdiff E [e])) . w \ set S \ w \ set (fst3 e)] @ map (\w. (w, Bot)) S <~~> (map (\w. (w, Top)) [w\initials (Graph V \ E) . w \ set S] @ map (\v. (v, Top)) (thd3 e)) @ map (\w. (w, Bot)) S" proof (intro perm_append2) have "map (\w. (w, Top)) [w\initials (Graph (listdiff V (fst3 e)) \ (listdiff E [e])) . w \ set S \ w \ set (fst3 e)] <~~> map (\w. (w, Top)) ([w\initials (Graph V \ E) . w \ set S] @ (thd3 e))" proof (intro map_perm) let ?lhs = "[w\initials (Graph (listdiff V (fst3 e)) \ (listdiff E [e])) . w \ set S \ w \ set (fst3 e)]" let ?rhs = "[w\initials (Graph V \ E) . w \ set S] @ thd3 e" have "?lhs = [w\listdiff V (fst3 e) . (\f\set (listdiff E [e]). w \ set (thd3 f)) \ (w \ set S \ w \ set (fst3 e))]" by auto also have "... = [w\V . w \ set (fst3 e) \ (\f. f \ set E \ f \ e \ w \ set (thd3 f)) \ (w \ set S \ w \ set (fst3 e))]" unfolding listdiff_def by auto also have "... <~~> [w\V . (\a\set E. w \ set (thd3 a)) \ w \ set S] @ thd3 e" proof (intro permI) show "set [w\V . w \ set (fst3 e) \ (\f. f \ set E \ f \ e \ w \ set (thd3 f)) \ (w \ set S \ w \ set (fst3 e))] = set ([w\V . (\a\set E. w \ set (thd3 a)) \ w \ set S] @ thd3 e)" unfolding set_append set_filter proof (auto) fix v assume "v \ set S" and "v \ set (fst3 e)" thus "False" using `set (fst3 e) \ set S` by auto next fix v assume "v \ set (thd3 e)" thus "v \ set V" by (metis ptyhv subsetD) next fix v assume "v \ set (thd3 e)" "v \ set (fst3 e)" with `e \ set E` have "(v,v) \ (\e\set E. \v\set (fst3 e). \w\set (thd3 e). {(v, w)})" by auto hence "(v,v) \ (\e\set E. \v\set (fst3 e). \w\set (thd3 e). {(v, w)})^+" by auto with xfrmj show "False" unfolding acyclicity_def acyclic_def by auto next fix v vs c ws assume "v \ set (thd3 e)" and "(vs, c, ws) \ set E" and "(vs, c, ws) \ e" and "v \ set (thd3 (vs, c, ws))" thus "False" by (metis (no_types) Collect_conj_eq Collect_def Int_absorb Int_def `e \ set E` `v \ set (thd3 (vs, c, ws))` `v \ set (thd3 e)` bot_empty_eq bot_fun_def emptyE inf1I rwiiv) next fix v assume uewqy: "v \ set (thd3 e)" assume "v \ set S" hence "v \ set (initials (Graph V \ E))" by (metis Suc.prems(2) subsetD) hence "\a\set E. v \ set (thd3 a)" by auto with uewqy `e \ set E` have False by auto thus "v \ set (fst3 e)" by auto qed next show "distinct [w\V . w \ set (fst3 e) \ (\f. f \ set E \ f \ e \ w \ set (thd3 f)) \ (w \ set S \ w \ set (fst3 e))]" using `distinct V` by auto next show "distinct ([w\V . (\a\set E. w \ set (thd3 a)) \ w \ set S] @ thd3 e)" apply (unfold distinct_append, intro conjI, auto simp add: `distinct V`) apply (metis nyneq) proof - fix w assume "w \ set (thd3 e)" and "\a\set E. w \ set (thd3 a)" with `e \ set E` show "False" by auto qed qed also have "... = ?rhs" by auto finally show "?lhs <~~> ?rhs" by auto qed moreover have "map (\w. (w, Top)) ([w\initials (Graph V \ E) . w \ set S] @ (thd3 e)) <~~> map (\w. (w, Top)) [w\initials (Graph V \ E) . w \ set S] @ map (\v. (v, Top)) (thd3 e)" by auto ultimately show "map (\w. (w, Top)) [w\initials (Graph (listdiff V (fst3 e)) \ (listdiff E [e])) . w \ set S \ w \ set (fst3 e)] <~~> map (\w. (w, Top)) [w\initials (Graph V \ E) . w \ set S] @ map (\v. (v, Top)) (thd3 e)" by auto qed moreover have "(map (\w. (w, Top)) [w\initials (Graph V \ E) . w \ set S] @ map (\v. (v, Top)) (thd3 e)) @ map (\w. (w, Bot)) S <~~> (map (\w. (w, Top)) [w\initials (Graph V \ E) . w \ set S] @ map (\w. (w, Bot)) S) @ map (\v. (v, Top)) (thd3 e)" by (metis append_assoc perm_append1 perm_append_swap) ultimately show "map (\w. (w, Top)) [w\initials (Graph (listdiff V (fst3 e)) \ (listdiff E [e])) . w \ set S \ w \ set (fst3 e)] @ map (\w. (w, Bot)) S <~~> (map (\w. (w, Top)) [w\initials (Graph V \ E) . w \ set S] @ map (\w. (w, Bot)) S) @ map (\v. (v, Top)) (thd3 e)" by auto next have vqyuv: "distinct (initials (Graph (listdiff V (fst3 e)) \ (listdiff E [e])))" by (unfold initials.simps, intro distinct_filter, unfold listdiff_def, intro distinct_filter, rule `distinct V`) show "distinct (map (\w. (w, Top)) [w\initials (Graph (listdiff V (fst3 e)) \ (listdiff E [e])) . w \ set S \ w \ set (fst3 e)] @ map (\w. (w, Bot)) S)" proof (unfold distinct_append, intro conjI) show "distinct (map (\w. (w, Top)) [w\initials (Graph (listdiff V (fst3 e)) \ (listdiff E [e])) . w \ set S \ w \ set (fst3 e)])" proof (unfold distinct_map, intro conjI) show "distinct [w\initials (Graph (listdiff V (fst3 e)) \ (listdiff E [e])) . w \ set S \ w \ set (fst3 e)]" using vqyuv by (metis (no_types) distinct_filter) next show "inj_on (\w. (w, Top)) (set [w\initials (Graph (listdiff V (fst3 e)) \ (listdiff E [e])) . w \ set S \ w \ set (fst3 e)])" using inj_imp_inj_on[OF wargt[of "Top"]] by auto qed next show "distinct (map (\w. (w, Bot)) S)" by (metis Suc(2) distinct_zipI1 map_fst_pair zip_map_fst_snd) qed (auto) next show "distinct ((map (\w. (w, Top)) [w\initials (Graph V \ E) . w \ set S] @ map (\w. (w, Bot)) S) @ map (\v. (v, Top)) (thd3 e))" proof (unfold distinct_append, intro conjI, auto) show "distinct (map (\w. (w, Top)) [x\V . (\a\set E. x \ set (thd3 a)) \ x \ set S])" proof (unfold distinct_map, intro conjI) show "distinct [x\V . (\a\set E. x \ set (thd3 a)) \ x \ set S]" by (auto simp add: `distinct V`) next show "inj_on (\w. (w, Top)) (set [x\V . (\a\set E. x \ set (thd3 a)) \ x \ set S])" using inj_imp_inj_on[OF wargt[of "Top"]] by auto qed next show "distinct (map (\w. (w, Bot)) S)" by (unfold distinct_map, intro conjI, rule `distinct S`, rule inj_imp_inj_on[OF wargt[of "Bot"]]) next show "distinct (map (\v. (v, Top)) (thd3 e))" by (unfold distinct_map, intro conjI, rule `distinct (thd3 e)`, rule inj_imp_inj_on[OF wargt[of "Top"]]) next fix w assume "w \ set (thd3 e)" and "\a\set E. w \ set (thd3 a)" with `e \ set E` show "False" by auto qed qed also have "... = listdiff ((map (\w. (w,Top)) (filter (\w. w\set S) (initials (Graph V \ E)))) @ map (\w. (w, Bot)) S) (map (\v. (v, Bot)) (fst3 e)) @ listdiff (map (\v. (v, Top)) (thd3 e)) (map (\v. (v, Bot)) (fst3 e))" unfolding listdiff_append by auto also have "... = listdiff ((map (\w. (w,Top)) (filter (\w. w\set S) (initials (Graph V \ E)))) @ map (\w. (w, Bot)) S) (map (\v. (v, Bot)) (fst3 e)) @ map (\v. (v, Top)) (thd3 e)" unfolding listdiff_id[OF jxzvk] by auto also have "... = listdiff (concat (map (\w. if w \ set S then [(w, Top)] else []) (initials (Graph V \ E))) @ map (\w. (w, Bot)) S) (map (\v. (v, Bot)) (fst3 e)) @ map (\v. (v, Top)) (thd3 e)" unfolding map_filter_is_concat_map by auto finally have "?rhs <~~> listdiff (concat (map (\w. if w \ set S then [(w, Top)] else []) (initials (Graph V \ E))) @ map (\w. (w, Bot)) S) (map (\v. (v, Bot)) (fst3 e)) @ map (\v. (v, Top)) (thd3 e)" by auto moreover have "listdiff (concat (map (\w. if w \ set S then [(w, Top)] else []) (initials (Graph V \ E))) @ map (\w. (w, Bot)) S) (map (\v. (v, Bot)) (fst3 e)) @ map (\v. (v, Top)) (thd3 e) <~~> ?lhs" proof (intro perm_append2 listdiff_perm) have "concat (map (\w. if w \ set S then [(w, Top)] else []) (initials (Graph V \ E))) @ map (\w. (w, Bot)) S = (map (\x. (x, Top)) [x\initials (Graph V \ E) . x \ set S]) @ map (\w. (w, Bot)) S" unfolding map_filter_is_concat_map by auto moreover have "(map (\x. (x, Top)) [x\initials (Graph V \ E) . x \ set S]) @ map (\w. (w, Bot)) S <~~> \ (\ ((map (\x. (x, Top)) [x\initials (Graph V \ E) . x \ set S]) @ map (\w. (w, Bot)) S))" by (rule perm_sym[OF conc_abs]) moreover have "\ (\ ((map (\x. (x, Top)) [x\initials (Graph V \ E) . x \ set S]) @ map (\w. (w, Bot)) S)) = \ (\ (concat (map (\w. if w \ set S then [(w, Top)] else []) (initials (Graph V \ E))) @ map (\w. (w, Bot)) S))" unfolding map_filter_is_concat_map by auto ultimately show "concat (map (\w. if w \ set S then [(w, Top)] else []) (initials (Graph V \ E))) @ map (\w. (w, Bot)) S <~~> \ (\ (concat (map (\w. if w \ set S then [(w, Top)] else []) (initials (Graph V \ E))) @ map (\w. (w, Bot)) S))" by auto next show "distinct (concat (map (\w. if w \ set S then [(w, Top)] else []) (initials (Graph V \ E))) @ map (\w. (w, Bot)) S)" by (metis tklgv) next show "distinct (\ (\ (concat (map (\w. if w \ set S then [(w, Top)] else []) (initials (Graph V \ E))) @ map (\w. (w, Bot)) S)))" by (metis (no_types) conc_abs listdiff_def map_filter_is_concat_map maps_def perm_distinct_iff tklgv) qed ultimately have "?rhs <~~> ?lhs" by auto thus ?thesis by (rule perm_sym) qed hence jtgmn: "\ ((listdiff (\ (\ ([(w,Top). w \ initials (Graph V \ E), w \ set S] @ [(w,Bot). w \ S]))) [(v, Bot). v\fst3 e]) @ [(v, Top). v\thd3 e]) = \ ([(w,Top). w \ initials (Graph ?V' \ ?E'), w \ set ?S'] @ [(w,Bot). w \ ?S'])" using abs_equiv by auto have jvlal: "?\' \ rawchains2 (?S') (Graph ?V' \ ?E')" unfolding rawchains2_def unfolding jtgmn proof (intro CollectI exI[of _ \'] conjI, simp, unfold lins2.simps(1), intro CollectI conjI) from ujyes yketi show "distinct \'" by auto next show "set \' = Inl ` (set ?V' - set ?S') \ Inr ` set ?E'" (is "?lhs = ?rhs") proof - have "?rhs = Inl ` (set V - set (fst3 e) - (set S - set (fst3 e))) \ Inr ` set ?E'" by (metis set_listdiff) also have "... = Inl ` (set V - set (fst3 e) - (set S - set (fst3 e))) \ Inr ` ((set E) - {e})" by (unfold set_listdiff, auto) also have "... = Inl ` (set V - set S) \ Inr ` (set E) - {Inr e}" using hfgey bjmwl by auto also have "... = set \ - {Inr e}" using aqxbk by auto also have "... = set (removeAll (Inr e) \)" unfolding set_removeAll by auto also have "... = set (remove1 (Inr e) \)" using distinct_remove1_removeAll[OF ujyes] by auto also have "... = set (remove1 (Inr e) ((Inr e)#\'))" using yketi hnqdb by auto also have "... = ?lhs" by auto finally show ?thesis by auto qed next show "\i j v e. i < length \' \ j < length \' \ \' ! i = Inl v \ \' ! j = Inr e \ v \ set (fst3 e) \ i < j" proof (intro allI impI, (erule conjE)+) fix i j v e assume "i < length \'" and "j < length \'" and "\' ! i = Inl v" and "\' ! j = Inr e" hence "i+1 < length \" "j+1 < length \" "\!(i+1) = Inl v" "\!(j+1) = Inr e" using yketi by auto moreover assume "v \ set (fst3 e)" ultimately have "i+1 < j+1" using myqpt by metis thus "i < j" by auto qed next show "\j k w e. j < length \' \ k < length \' \ \' ! j = Inr e \ \' ! k = Inl w \ w \ set (thd3 e) \ j < k" proof (intro allI impI, (erule conjE)+) fix j k w e assume "j < length \'" and "k < length \'" and "\' ! j = Inr e" and "\' ! k = Inl w" hence "j+1 < length \" "k+1 < length \" "\!(j+1) = Inr e" "\!(k+1) = Inl w" using yketi by auto moreover assume "w \ set (thd3 e)" ultimately have "j+1 < k+1" using zjtlg by metis thus "j < k" by auto qed qed from `e \ set E` have bnrxu: "distinct [e]" "set [e] \ set E" by auto have favzl: "length ?V' + length ?E' = k + length ?S'" (is "?lhs = ?rhs") proof - have "?lhs = length V - length (fst3 e) + length E - length [e]" using length_listdiff[OF `distinct V` bjcek rodmt] using length_listdiff[OF `distinct E` bnrxu] by (metis add_diff_assoc2 bnrxu(2) distinct_singleton list_subseteq nat_add_commute) also have "... = length V - length (fst3 e) + length E - 1" by auto also have "... = k + length S - length (fst3 e)" using Suc.prems(5) and list_subseteq[OF bjcek rodmt] by arith also have "... = k + length (listdiff S (fst3 e))" using length_listdiff[OF `distinct S` bjcek bjmwl] by (metis bjcek bjmwl diff_add_assoc list_subseteq) finally show "?lhs = ?rhs" by auto qed have cwzgj: "terminals (Graph V \ E) = terminals (Graph ?V' \ ?E')" proof (unfold terminals.simps, auto) let ?lhs = "[v\V . \a\set E. v \ set (fst3 a)]" let ?rhs = "[v\listdiff V (fst3 e) . \f\set (listdiff E [e]). v \ set (fst3 f)]" have "?rhs = [v\[v\V . v \ set (fst3 e)] . \f\set [f\E . f \ set [e]]. v \ set (fst3 f)]" unfolding listdiff_def by auto also have "... = [x\V . x \ set (fst3 e) \ (\f\set [f\E . f \ set [e]]. x \ set (fst3 f))]" unfolding filter_filter by auto also have "... = [x\V . x \ set (fst3 e) \ (\f. f \ set [f\E . f\e] \ x \ set (fst3 f))]" by auto also have "... = [x\V . x \ set (fst3 e) \ (\f. f \ set E \ f\e \ x \ set (fst3 f))]" by auto also have "... = [x\V . x \ set (fst3 e) \ (\f. f \ set E \ f\e \ x \ set (fst3 f))]" unfolding imp_conjL by auto also have "... = [x\V . x \ set (fst3 e) \ (\f \ set E. f\e \ x \ set (fst3 f))]" by metis also have "... = ?lhs" proof (intro filter_cong, simp) fix x assume "x \ set V" show "(x \ set (fst3 e) \ (\f\set E. f \ e \ x \ set (fst3 f))) = (\f\set E. x \ set (fst3 f))" using all_but_one[OF `e \ set E`, of "\e. x \ set (fst3 e)"] by auto qed finally show "?lhs = ?rhs" by auto qed from Suc.hyps[OF cuztr fthcv shifk jvlal favzl] have mapkz: "wf_rawchain ?\'" and "\ (post ?\') <~~> [(v,Bot). v \ terminals (Graph ?V' \ ?E')]" by auto from this(2) and cwzgj have uzlwq: "\ (post ?\') <~~> [(v,Bot). v \ terminals (Graph V \ E)]" by auto have ppefa: "?\ <~~> [(v, Bot). v\fst3 e] @ ?\'" apply (intro diff_then_append, rule tklgv) defer apply (unfold distinct_map, intro conjI bjcek) apply (metis (no_types) Pair_eq inj_on_def) proof (intro subsetI, auto) fix v assume "v \ set (fst3 e)" hence "v \ set S" by (metis bjmwl subsetD) moreover assume "(v, Bot) \ (\v. (v, Bot)) ` set S" ultimately show "False" by (metis imageI) qed from tklgv have zuuso: "distinct (\ (\ ?\))" by (metis (no_types) conc_abs perm_distinct_iff) have vpcvj: "pre ?\' = \ ((listdiff (\ (\ ?\)) [(v,Bot). v\fst3 e]) @ [(v,Top). v\thd3 e])" using pre_mk by auto have ejtrd: "\X Y. \ distinct X ; X <~~> Y \ \ distinct Y" using perm_distinct_iff by auto have "listdiff (\ (\ ?\)) [(v,Bot). v \ fst3 e] <~~> listdiff ?\ [(v,Bot). v \ fst3 e]" apply (intro listdiff_perm conc_abs, rule ejtrd) prefer 2 apply (rule perm_sym[OF conc_abs]) apply (metis tklgv)+ done hence "listdiff (\ (\ ?\)) [(v,Bot). v \ fst3 e] @ [(v,Top). v \ thd3 e] <~~> ?\' @ [(v,Top). v \ thd3 e]" by auto from abs_equiv[OF this] have "\ (listdiff (\ (\ ?\)) [(v,Bot). v \ fst3 e] @ [(v,Top). v \ thd3 e]) = \ (?\' @ [(v,Top). v \ thd3 e])" by auto with vpcvj have "pre ?\' = \ (?\' @ [(v,Top). v \ thd3 e])" by auto hence "\ (pre ?\') <~~> ?\' @ [(v,Top). v \ thd3 e]" using conc_abs by auto moreover have "?\' @ [(v,Top). v \ thd3 e] <~~> [(v,Top). v \ thd3 e] @ ?\'" by (metis perm_append_swap) ultimately have otqat: "\ (pre ?\') <~~> [(v,Top). v \ thd3 e] @ ?\'" by (rule perm.trans) from wf_rawchain_ccons_inr[OF ppefa otqat mapkz] lmkbq have "wf_rawchain \" by auto moreover from lmkbq have "post \ = post ?\'" by auto with uzlwq have "\ (post \) <~~> [(v,Bot). v \ terminals (Graph V \ E)]" by auto ultimately show ?thesis by auto qed qed qed corollary wf_chains: fixes V \ E \ assumes "wf_dia (Graph V \ E)" assumes "\ \ rawchains (Graph V \ E)" shows "wf_rawchain \ \ \ (post \) <~~> [(v,Bot). v \ terminals (Graph V \ E)]" proof (intro wf_chains2) show "distinct []" by auto next show "set [] \ set (initials (Graph V \ E))" by auto next show "wf_dia (Graph V \ E)" using assms(1) by auto next show "\ \ rawchains2 [] (Graph V \ E)" using assms(2) and rawchains_is_rawchains2_with_empty_S by auto next show "length V + length E = length V + length E + length []" by auto qed lemma nth_suc: fixes X i shows "Suc i < length X \ X ! Suc i = tl X ! i" by (induct X, auto) lemma pre_chainmap: fixes f g \ shows "pre (chainmap f g \) = f (pre \)" by (induct \, auto) lemma post_chainmap: fixes f g \ shows "post (chainmap f g \) = f (post \)" by (induct \, auto) lemma ass_fold_hcomp: fixes Ps shows "ass (foldl (op \) Emp_int Ps) = foldl (op \) Emp (map ass Ps)" proof - have "\Q. ass (foldl (op \) Q Ps) = foldl (op \) (ass Q) (map ass Ps)" proof (induct Ps) case Nil show ?case by auto next case (Cons P Ps) hence "\Q. ass (foldl op \ Q Ps) = foldl op \ (ass Q) (map ass Ps)" by auto let ?lhs = "ass (foldl op \ Q (P # Ps))" let ?rhs = "foldl op \ (ass Q) (map ass (P # Ps))" have "?lhs = ass (foldl op \ (Q \ P) Ps)" by auto also have "... = foldl op \ (ass (Q \ P)) (map ass Ps)" using Cons.hyps by auto also have "... = foldl op \ (ass Q \ ass P) (map ass Ps)" by auto also have "... = foldl op \ (ass Q) ((ass P) # (map ass Ps))" by auto also have "... = ?rhs" by auto finally show ?case by auto qed thus ?thesis by auto qed lemma ass_perm: fixes ps Qs assumes "ps <~~> qs" shows "foldl (op \) Emp ps = foldl (op \) Emp qs" using assms proof (induct rule:perm.induct) case swap thus ?case by (metis emp_star foldl_Cons star_comm) next case Cons thus ?case by (metis (no_types) foldl_Cons foldl_fun_comm star_assoc star_comm) qed (auto) lemma ass_foldl_foldr: fixes Ps shows "ass (foldl (op \) Emp_int Ps) = ass (foldr (op \) Ps Emp_int)" proof - have "\Q R. ass (R \ (foldr (op \) Ps Q)) = ass ((foldl (op \) R Ps) \ Q)" proof (induct Ps) case Nil thus ?case by auto next case (Cons P Ps) thus ?case by (metis equiv_int_sound foldl_Cons foldr.simps(2) hcomp_assoc) qed from this[of Emp_int Emp_int] show ?thesis using emp_star star_emp by auto qed lemma ass_perm_int: fixes Ps Qs assumes "Ps <~~> Qs" shows "ass (foldr (op \) Ps Emp_int) = ass (foldr (op \) Qs Emp_int)" by (metis ass_fold_hcomp ass_foldl_foldr ass_perm assms map_perm) lemma nthtriple_chainmap: fixes f g \ shows "\i. i < chainlen \ \ nthtriple (chainmap f g \) i = (\(\1,x,\2). (f \1, g x, f \2)) (nthtriple \ i)" proof (induct \) case (cNil P) thus ?case by auto next case (cCons P c \) thus ?case by (induct i, auto simp add: pre_chainmap) qed lemma seq_fold: fixes cs shows "\\. \ length cs = chainlen \ ; \i < chainlen \. prov_triple (ass (fst3 (nthtriple \ i)), cs ! i, ass (thd3 (nthtriple \ i))) \ \ prov_triple (ass (pre \), foldr (op ;;) cs Skip, ass (post \))" proof (induct cs) case Nil hence "chainlen \ = 0" by auto then obtain p where "\ = cNil p" by (cases \, auto) show ?case unfolding `\ = cNil p` by (auto simp add: prov_triple.skip) next case (Cons c cs) from Cons.prems(1) have "length (c # cs) = chainlen \" by assumption from Cons.prems(2) have ozniy: "\i. i \ prov_triple (ass (fst3 (nthtriple \ i)), (c # cs) ! i, ass (thd3 (nthtriple \ i)))" by auto from Cons.prems(1) obtain p x \' where hnsvs: "\ = cCons p x \'" by (metis chain.exhaust chainlen.simps(1) impossible_Cons le0) with Cons.prems(1) have "length cs = chainlen \'" by auto from Cons.hyps[OF this] have tnlzn: "\i'. prov_triple (ass (fst3 (nthtriple \' i)), cs ! i, ass (thd3 (nthtriple \' i))) \ prov_triple (ass (pre \'), foldr op ;; cs Skip, ass (post \'))" by auto from Cons.prems(1) have "0 < chainlen \" by auto from ozniy[OF this] have zyaiu: "prov_triple (ass p, c, ass (pre \'))" unfolding hnsvs by (auto, unfold fst3_simp thd3_simp) from hnsvs have uqmba: "post \' = post \" by auto have lkgap: "prov_triple (ass (pre \), c, ass (pre \'))" using zyaiu hnsvs by auto have pehot: "prov_triple (ass (pre \'), foldr op ;; cs Skip, ass (post \))" proof (fold uqmba, intro tnlzn, intro allI impI) fix i assume "i < chainlen \'" hence "i+1 < chainlen \" using hnsvs by auto from ozniy[OF this] show "prov_triple (ass (fst3 (nthtriple \' i)), cs ! i, ass (thd3 (nthtriple \' i)))" by (unfold hnsvs, auto) qed from prov_triple.seq[OF lkgap pehot] show ?case by auto qed lemma foldr_hcomp: fixes Ps Q shows "ass (foldr op \ Ps Q) = ass ((foldr op \ Ps Emp_int) \ Q)" proof (induct Ps) case Nil show ?case by (auto simp add: emp_star) next case (Cons P Ps) hence "ass (foldr op \ Ps Q) = ass (foldr op \ Ps Emp_int \ Q)" by metis show "ass (foldr op \ (P # Ps) Q) = ass (foldr op \ (P # Ps) Emp_int \ Q)" apply auto apply (unfold Cons.hyps) apply (auto simp add: star_assoc) done qed lemma var_soundness_helper: assumes no_var_interference: "\c. wr_com c = {}" shows "(prov_dia G P Q \ (P = top_dia G \ Q = bot_dia G \ (\c \ coms_dia G. prov_triple (ass P, c, ass Q)))) \ (prov_com C P Q \ (\c \ coms_com C. prov_triple (ass P, c, ass Q))) \ (prov_ass A \ (\c \ coms_ass A. prov_triple (ass (top_ass A), c, ass (bot_ass A))))" proof (induct rule: prov_dia_prov_com_prov_ass.induct) case (Skip p) thus ?case proof (intro ballI) fix c assume "c \ coms_ass (Rib p)" hence "coms_ass (Rib p) c" by (metis mem_def) from coms_skip_inv[OF this] have "c = Skip" by auto moreover have "ass (top_ass (Rib p)) = p" by auto moreover have "ass (bot_ass (Rib p)) = p" by auto ultimately show "prov_triple (ass (top_ass (Rib p)), c, ass (bot_ass (Rib p)))" using prov_triple.skip by auto qed next case (Exists G P Q x) thus ?case proof (intro ballI) fix c assume "c \ coms_ass (Exists_dia x G)" hence ldqxz: "coms_ass (Exists_dia x G) c" by (metis mem_def) assume wflao: "P = top_dia G \ Q = bot_dia G \ (\c\coms_dia G. prov_triple (ass P, c, ass Q))" have "c \ coms_dia G" using coms_exists_inv[OF ldqxz] by (metis mem_def) with wflao have fsree: "prov_triple (ass P, c, ass Q)" by auto have "ass (top_ass (Exists_dia x G)) = Exists x (ass P)" using wflao by auto moreover have "ass (bot_ass (Exists_dia x G)) = Exists x (ass Q)" using wflao by auto moreover have "prov_triple (Exists x (ass P), c, Exists x (ass Q))" by (rule prov_triple.exists, rule fsree) ultimately show "prov_triple (ass (top_ass (Exists_dia x G)), c, ass (bot_ass (Exists_dia x G)))" by auto qed next case (Basic P c Q) thus ?case proof (intro ballI) fix ca assume lxkin: "prov_triple (ass P, c, ass Q)" assume "ca \ coms_com (Com c)" hence "coms_com (Com c) ca" by (metis mem_def) from coms_basic_inv [OF this] have "ca = c" by auto with lxkin show "prov_triple (ass P, ca, ass Q)" by auto qed next case (Choice G P Q H) thus ?case apply (intro ballI) apply (elim conjE) proof - fix c assume ydhfk: "\c\coms_dia G. prov_triple (ass P, c, ass Q)" assume bbzsd: "\c\coms_dia H. prov_triple (ass P, c, ass Q)" assume "c \ coms_com (Choose_dia G H)" hence "coms_com (Choose_dia G H) c" by (metis mem_def) from coms_choice_inv[OF this] obtain c1 c2 where pehfc: "c = Choose c1 c2" and "coms_dia G c1" and "coms_dia H c2" by auto hence "c1 \ coms_dia G" and "c2 \ coms_dia H" by (metis mem_def)+ with ydhfk bbzsd have "prov_triple (ass P, c1, ass Q)" "prov_triple (ass P, c2, ass Q)" by auto from prov_triple.choose[OF this] and pehfc show "prov_triple (ass P, c, ass Q)" by auto qed next case (Loop G P) thus ?case apply (intro ballI) apply (elim conjE) proof - fix c assume gchsd: "\c\coms_dia G. prov_triple (ass P, c, ass P)" assume "c \ coms_com (Loop_dia G)" hence "coms_com (Loop_dia G) c" by (metis mem_def) from coms_loop_inv[OF this] obtain c1 where vxvnb: "c = Loop c1" and "coms_dia G c1" by auto hence "c1 \ coms_dia G" by (metis mem_def) with gchsd have "prov_triple (ass P, c1, ass P)" by auto from prov_triple.loop[OF this] and vxvnb show "prov_triple (ass P, c, ass P)" by auto qed next case (Main V \ E) thus ?case apply (intro conjI, simp, simp) apply (intro ballI) proof - let ?G = "Graph V \ E" fix c assume sexqd: "\v. v \ set V \ \c\coms_ass (\ v). prov_triple (ass (top_ass (\ v)), c, ass (bot_ass (\ v)))" assume aprie: "\e. e \ set E \ \c\coms_com (snd3 e). prov_triple (ass (foldl op \ Emp_int (map (\v. bot_ass (\ v)) (fst3 e))), c, ass (foldl op \ Emp_int (map (\v. top_ass (\ v)) (thd3 e))))" assume quitc: "wf_dia ?G" assume "c \ coms_dia (Graph V \ E)" hence "coms_dia (Graph V \ E) c" by (metis mem_def) from coms_main_inv[OF this] obtain \ cs where "\ \ lins (Graph V \ E) \ length cs = length \ \ (\i. (\v. \ ! i = Inl v) \ coms_ass (\ (Sum_Type.Projl (\ ! i))) (cs ! i)) \ (\i. (\e. \ ! i = Inr e) \ coms_com (snd3 (Sum_Type.Projr (\ ! i))) (cs ! i)) \ c = foldr op ;; cs Skip" by auto hence ovuqv: "\ \ lins (Graph V \ E)" and ipvoy: "length cs = length \" and "\i. (\v. \ ! i = Inl v) \ coms_ass (\ (Sum_Type.Projl (\ ! i))) (cs ! i)" and "\i. (\e. \ ! i = Inr e) \ coms_com (snd3 (Sum_Type.Projr (\ ! i))) (cs ! i)" and zkhmj: "c = foldr op ;; cs Skip" by (metis)+ from this(3) this(4) have yqvfp: "\i v. \ i < length \ ; \!i = Inl v \ \ coms_ass (\ (Sum_Type.Projl (\ ! i))) (cs ! i)" and dnhoi: "\i e. \ i < length \ ; \!i = Inr e \ \ coms_com (snd3 (Sum_Type.Projr (\ ! i))) (cs ! i)" by auto from ovuqv have pwlee: "distinct \" and eagbg: "set \ = Inl ` set V \ Inr ` set E" and "\i j v e. i < length \ \ j < length \ \ \ ! i = Inl v \ \ ! j = Inr e \ v \ set (fst3 e) \ i < j" and "\j k w e. j < length \ \ k < length \ \ \ ! j = Inr e \ \ ! k = Inl w \ w \ set (thd3 e) \ j < k" apply (unfold lins.simps) apply (elim CollectE conjE, assumption)+ done from this(3) this(4) have qfgbz: "\i j v e. \ i < length \ ; j < length \ ; \ ! i = Inl v ; \ ! j = Inr e ; v \ set (fst3 e) \ \ i < j" and zyzev: "\j k w e. \ j < length \ ; k < length \ ; \ ! j = Inr e ; \ ! k = Inl w ; w \ set (thd3 e) \ \ j < k" by metis+ let ?\ = "mk (cNil (\ [(v, Top) . v \ initials ?G])) \" have nuksb: "?\ \ rawchains ?G" by (unfold rawchains_def, intro CollectI, metis ovuqv) have distinct_perm: "\X Y. \ distinct X ; X <~~> Y \ \ distinct Y" by (metis perm_distinct_iff) from pre_mk have "pre ?\ = \ [(v, Top) . v \ initials ?G]" by auto hence "map fst (\ (pre ?\)) = map fst (\ (\ [(v, Top) . v \ initials ?G]))" by auto also have "... <~~> map fst [(v, Top) . v \ initials ?G]" by (intro map_perm, rule conc_abs) also have "... = initials ?G" by (metis map_fst_pair) finally have "map fst (\ (pre ?\)) <~~> initials ?G" by auto from wf_chains [OF quitc nuksb] have mdajx: "wf_rawchain ?\" and lisdi: "\ (post ?\) <~~> [(v,Bot). v \ terminals ?G]" by auto have rxqbt: "\ \i. i < chainlen ?\ \ prov_triple ((\(P,_,Q). (ass P, cs!i, ass Q)) (nthtriple (cook ?G ?\) i)) \ \ prov_triple (ass (pre (cook ?G ?\)), c, ass (post (cook ?G ?\)))" proof - assume mboea: "\i. i < chainlen ?\ \ prov_triple ((\(P,_,Q). (ass P, cs!i, ass Q)) (nthtriple (cook ?G ?\) i))" from ipvoy have "length cs = length \" by auto moreover from mk_preserves_length have "length \ = chainlen ?\" by auto moreover from chainmap_preserves_length have ywrwb: "chainlen (cook ?G ?\) = chainlen ?\" unfolding cook.simps by auto ultimately have zoejd: "length cs = chainlen (cook ?G ?\)" by auto have vuzmq: "\i < chainlen (cook ?G ?\). prov_triple (ass (fst3 (nthtriple (cook ?G ?\) i)), cs ! i, ass (thd3 (nthtriple (cook ?G ?\) i)))" proof(intro allI impI) fix i assume "i < chainlen (cook ?G ?\)" hence "i < chainlen ?\" using ywrwb by auto hence "prov_triple ((\(P,_,Q). (ass P, cs!i, ass Q)) (nthtriple (cook ?G ?\) i))" using mboea by auto moreover have "prov_triple ((\(P,_,Q). (ass P, cs!i, ass Q)) (nthtriple (cook ?G ?\) i)) = prov_triple (ass (fst3 (nthtriple (cook ?G ?\) i)), cs ! i, ass (thd3 (nthtriple (cook ?G ?\) i)))" apply (intro arg_cong[of _ _ "prov_triple"], intro tripleI) apply (unfold fst3_comp fst3_simp, simp) apply (unfold snd3_comp snd3_simp, simp) apply (unfold thd3_comp thd3_simp, simp) done ultimately show "prov_triple (ass (fst3 (nthtriple (cook ?G ?\) i)), cs ! i, ass (thd3 (nthtriple (cook ?G ?\) i)))" by auto qed from seq_fold[OF zoejd vuzmq] and zkhmj show "prov_triple (ass (pre (cook ?G ?\)), c, ass (post (cook ?G ?\)))" by auto qed have "prov_triple (ass (pre (cook ?G ?\)), c, ass (post (cook ?G ?\)))" proof (intro rxqbt) fix i assume iyuyo: "i < chainlen ?\" also have "... = length \" unfolding mk_preserves_length by auto finally have aktjb: "i < length \" by auto show "prov_triple ((\(P,_,Q). (ass P, cs!i, ass Q)) (nthtriple (cook ?G ?\) i))" proof (cases "\!i") case (Inl v) from wf_rawchain_def mdajx iyuyo obtain \' where mzkbx: "(\v. nthtriple ?\ i = (\ ([(v, Top)] @ \'), Inl v, \ ([(v, Bot)] @ \'))) \ (\e. nthtriple ?\ i = (\ (map (\v. (v, Bot)) (fst3 e) @ \'), Inr e, \ (map (\v. (v, Top)) (thd3 e) @ \')))" by metis have zyxtr: "snd3 (nthtriple ?\ i) = Inl v" proof - from snds_of_triples_form_comlist[OF iyuyo] have "snd3 (nthtriple ?\ i) = \!i" unfolding mk_comlist by auto thus ?thesis using Inl by auto qed have "\ (\e. nthtriple ?\ i = (\ (map (\v. (v, Bot)) (fst3 e) @ \'), Inr e, \ (map (\v. (v, Top)) (thd3 e) @ \')))" proof (intro notI) assume "\e. nthtriple ?\ i = (\ (map (\v. (v, Bot)) (fst3 e) @ \'), Inr e, \ (map (\v. (v, Top)) (thd3 e) @ \'))" then obtain e where "nthtriple ?\ i = (\ (map (\v. (v, Bot)) (fst3 e) @ \'), Inr e, \ (map (\v. (v, Top)) (thd3 e) @ \'))" by auto hence "snd3 (nthtriple ?\ i) = snd3 (\ (map (\v. (v, Bot)) (fst3 e) @ \'), Inr e, \ (map (\v. (v, Top)) (thd3 e) @ \'))" by auto hence "Inl v = Inr e" using zyxtr unfolding snd3_def by auto thus False by auto qed with mzkbx have "\v. nthtriple ?\ i = (\ ([(v, Top)] @ \'), Inl v, \ ([(v, Bot)] @ \'))" by auto then obtain v' where wvjxe: "nthtriple ?\ i = (\ ([(v', Top)] @ \'), Inl v', \ ([(v', Bot)] @ \'))" by auto hence "snd3 (nthtriple ?\ i) = Inl v'" unfolding snd3_def by auto with zyxtr have "v = v'" by auto with wvjxe have rraei: "nthtriple ?\ i = (\ ([(v, Top)] @ \'), Inl v, \ ([(v, Bot)] @ \'))" by auto let ?f = "ass ((foldl op \ Emp_int \ map (\(v, z). topbot_case top_ass bot_ass z (\ v)) \ \) (\ \'))" from Inl and yqvfp[OF aktjb Inl] have "coms_ass (\ v) (cs ! i)" by auto hence nrmyv: "(cs ! i) \ coms_ass (\ v)" by (metis mem_def) from Inl aktjb have "Inl v \ set \" by (metis nth_mem) with eagbg have "v \ set V" by auto from sexqd[OF this] nrmyv have "prov_triple (ass (top_ass (\ v)), cs!i, ass (bot_ass (\ v)))" by auto hence "prov_triple (ass (top_ass (\ v)) \ ?f, cs!i, ass (bot_ass (\ v)) \ ?f)" using prov_triple.frame and no_var_interference by auto moreover have "((\(P,_,Q). (ass P, cs!i, ass Q)) (nthtriple (cook ?G ?\) i)) = (ass (top_ass (\ v)) \ ?f, cs!i, ass (bot_ass (\ v)) \ ?f)" proof (intro tripleI) have "fst3 ((\(P,_,Q). (ass P, cs!i, ass Q)) (nthtriple (cook ?G ?\) i)) = ass (fst3 (nthtriple (cook ?G ?\) i))" unfolding split_def fst3_def by auto also have "... = ass (foldl op \ Emp_int (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (\ (fst3 (nthtriple ?\ i)))))" unfolding cook.simps nthtriple_chainmap[OF iyuyo] fst3_comp by auto also have "... = ass (foldl op \ Emp_int (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (\ (\ ((v, Top) # \')))))" unfolding rraei fst3_def by auto also have "... = ass (foldr op \ (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (\ (\ ((v, Top) # \')))) Emp_int)" using ass_foldl_foldr by auto also have "... = ass (((foldr (op \) (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) ((v,Top) # \ (\ \'))) Emp_int)))" apply (intro ass_perm_int map_perm) apply (metis Quotient_proofstate perm.Cons perm_refl rep_abs_rsp rep_abs_rsp_left) done also have "... = ass (((foldr (op \) (top_ass (\ v) # map (\(v, z). topbot_case top_ass bot_ass z (\ v)) ( \ (\ \'))) Emp_int)))" by auto also have "... = ass (top_ass (\ v) \ ((foldr (op \) (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) ( \ (\ \'))) Emp_int)))" by auto also have "... = ass (top_ass (\ v) \ ((foldl (op \) Emp_int (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) ( \ (\ \'))))))" using ass_foldl_foldr by auto also have "... = ass (top_ass (\ v)) \ ?f" by auto finally have "fst3 ((\(P,_,Q). (ass P, cs!i, ass Q)) (nthtriple (cook ?G ?\) i)) = ass (top_ass (\ v)) \ ?f" by auto thus "fst3 ((\(P, _, Q). (ass P, cs ! i, ass Q)) (nthtriple (cook ?G ?\) i)) = fst3 (ass (top_ass (\ v)) \ ?f, cs ! i, ass (bot_ass (\ v)) \ ?f)" unfolding fst3_def by auto next have cojiq: "\X Y. snd3 ((\(P,_,Q). (ass P, Y, ass Q)) X) = Y" unfolding snd3_def by auto have "snd3 ((\(P,_,Q). (ass P, cs!i, ass Q)) (nthtriple (cook ?G ?\) i)) = cs!i" unfolding cojiq by auto thus "snd3 ((\(P, _, Q). (ass P, cs ! i, ass Q)) (nthtriple (cook ?G ?\) i)) = snd3 (ass (top_ass (\ v)) \ ?f, cs ! i, ass (bot_ass (\ v)) \ ?f)" unfolding snd3_def by auto next have "thd3 ((\(P,_,Q). (ass P, cs!i, ass Q)) (nthtriple (cook ?G ?\) i)) = ass (thd3 (nthtriple (cook ?G ?\) i))" unfolding split_def thd3_def by auto also have "... = ass (foldl op \ Emp_int (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (\ (thd3 (nthtriple ?\ i)))))" unfolding cook.simps nthtriple_chainmap[OF iyuyo] thd3_comp by auto also have "... = ass (foldl op \ Emp_int (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (\ (\ ((v, Bot) # \')))))" unfolding rraei thd3_def by auto also have "... = ass (foldr op \ (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (\ (\ ((v, Bot) # \')))) Emp_int)" using ass_foldl_foldr by auto also have "... = ass (((foldr (op \) (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) ((v,Bot) # \ (\ \'))) Emp_int)))" apply (intro ass_perm_int map_perm) apply (metis Quotient_proofstate perm.Cons perm_refl rep_abs_rsp rep_abs_rsp_left) done also have "... = ass (((foldr (op \) (bot_ass (\ v) # map (\(v, z). topbot_case top_ass bot_ass z (\ v)) ( \ (\ \'))) Emp_int)))" by auto also have "... = ass (bot_ass (\ v) \ ((foldr (op \) (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) ( \ (\ \'))) Emp_int)))" by auto also have "... = ass (bot_ass (\ v) \ ((foldl (op \) Emp_int (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) ( \ (\ \'))))))" using ass_foldl_foldr by auto also have "... = ass (bot_ass (\ v)) \ ?f" by auto finally have "thd3 ((\(P,_,Q). (ass P, cs!i, ass Q)) (nthtriple (cook ?G ?\) i)) = ass (bot_ass (\ v)) \ ?f" by auto thus "thd3 ((\(P, _, Q). (ass P, cs ! i, ass Q)) (nthtriple (cook ?G ?\) i)) = thd3 (ass (top_ass (\ v)) \ ?f, cs ! i, ass (bot_ass (\ v)) \ ?f)" unfolding thd3_def by auto qed ultimately show ?thesis by auto next case (Inr e) from wf_rawchain_def mdajx iyuyo obtain \' where mzkbx: "(\v. nthtriple ?\ i = (\ ([(v, Top)] @ \'), Inl v, \ ([(v, Bot)] @ \'))) \ (\e. nthtriple ?\ i = (\ (map (\v. (v, Bot)) (fst3 e) @ \'), Inr e, \ (map (\v. (v, Top)) (thd3 e) @ \')))" by metis have zyxtr: "snd3 (nthtriple ?\ i) = Inr e" proof - from snds_of_triples_form_comlist[OF iyuyo] have "snd3 (nthtriple ?\ i) = \!i" unfolding mk_comlist by auto thus ?thesis using Inr by auto qed have "\ (\v. nthtriple ?\ i = (\ ([(v, Top)] @ \'), Inl v, \ ([(v, Bot)] @ \')))" proof (intro notI) assume "\v. nthtriple ?\ i = (\ ([(v, Top)] @ \'), Inl v, \ ([(v, Bot)] @ \'))" then obtain v where "nthtriple ?\ i = (\ ([(v, Top)] @ \'), Inl v, \ ([(v, Bot)] @ \'))" by auto hence "snd3 (nthtriple ?\ i) = snd3 (\ ([(v, Top)] @ \'), Inl v, \ ([(v, Bot)] @ \'))" by auto hence "Inl e = Inr v" using zyxtr unfolding snd3_def by auto thus False by auto qed with mzkbx have "\e. nthtriple ?\ i = (\ (map (\v. (v, Bot)) (fst3 e) @ \'), Inr e, \ (map (\v. (v, Top)) (thd3 e) @ \'))" by auto then obtain e' where wvjxe: "nthtriple ?\ i = (\ (map (\v. (v, Bot)) (fst3 e') @ \'), Inr e', \ (map (\v. (v, Top)) (thd3 e') @ \'))" by auto hence "snd3 (nthtriple ?\ i) = Inr e'" unfolding snd3_def by auto with zyxtr have "e = e'" by auto with wvjxe have rraei: "nthtriple ?\ i = (\ (map (\v. (v, Bot)) (fst3 e) @ \'), Inr e, \ (map (\v. (v, Top)) (thd3 e) @ \'))" by auto let ?f = "ass ((foldl op \ Emp_int \ map (\(v, z). topbot_case top_ass bot_ass z (\ v)) \ \) (\ \'))" from Inr and dnhoi[OF aktjb Inr] have "coms_com (snd3 e) (cs ! i)" by auto hence nrmyv: "(cs ! i) \ coms_com (snd3 e)" by (metis mem_def) from Inr aktjb have "Inr e \ set \" by (metis nth_mem) with eagbg have "e \ set E" by auto from aprie[OF this] nrmyv have "prov_triple (ass (foldl op \ Emp_int (map (\v. bot_ass (\ v)) (fst3 e))), cs ! i, ass (foldl op \ Emp_int (map (\v. top_ass (\ v)) (thd3 e))))" by auto hence "prov_triple (ass (foldl op \ Emp_int (map (\v. bot_ass (\ v)) (fst3 e))) \ ?f, cs!i, ass (foldl op \ Emp_int (map (\v. top_ass (\ v)) (thd3 e))) \ ?f)" using prov_triple.frame and no_var_interference by auto moreover have kqrdm: "map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (map (\v. (v, Bot)) (fst3 e)) = map (\v. bot_ass (\ v)) (fst3 e)" by auto have jrlxz: "map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (map (\v. (v, Top)) (thd3 e)) = map (\v. top_ass (\ v)) (thd3 e)" by auto have "((\(P,_,Q). (ass P, cs!i, ass Q)) (nthtriple (cook ?G ?\) i)) = (ass (foldl op \ Emp_int (map (\v. bot_ass (\ v)) (fst3 e))) \ ?f, cs!i, ass (foldl op \ Emp_int (map (\v. top_ass (\ v)) (thd3 e))) \ ?f)" proof (intro tripleI) have "fst3 ((\(P,_,Q). (ass P, cs!i, ass Q)) (nthtriple (cook ?G ?\) i)) = ass (fst3 (nthtriple (cook ?G ?\) i))" unfolding split_def fst3_def by auto also have "... = ass (foldl op \ Emp_int (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (\ (fst3 (nthtriple ?\ i)))))" unfolding cook.simps nthtriple_chainmap[OF iyuyo] fst3_comp by auto also have "... = ass (foldl op \ Emp_int (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (\ (\ ([(v, Bot). v \ fst3 e] @ \')))))" unfolding rraei fst3_def by auto also have "... = ass (foldr op \ (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (\ (\ ([(v, Bot). v \ fst3 e] @ \')))) Emp_int)" using ass_foldl_foldr by auto also have "... = ass (((foldr (op \) (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) ([(v, Bot). v \ fst3 e] @ \ (\ \'))) Emp_int)))" apply (intro ass_perm_int map_perm) apply (metis Quotient_proofstate perm_append1 perm_refl rep_abs_rsp rep_abs_rsp_left) done also have "... = ass (foldr op \ (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (map (\v. (v, Bot)) (fst3 e)) @ map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (\ (\ \'))) Emp_int)" unfolding map_append by auto also have "... = ass (((foldr (op \) ((map (\v. bot_ass (\ v)) (fst3 e)) @ map (\(v, z). topbot_case top_ass bot_ass z (\ v)) ( \ (\ \'))) Emp_int)))" unfolding kqrdm by auto also have "... = ass (foldr op \ (map (\v. bot_ass (\ v)) (fst3 e)) ((foldr (op \) (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) ( \ (\ \'))) Emp_int)))" by auto also have "... = ass ((foldr op \ (map (\v. bot_ass (\ v)) (fst3 e)) Emp_int) \ (foldr op \ (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (\ (\ \'))) Emp_int))" unfolding foldr_hcomp by auto also have "... = ass ((foldl op \ Emp_int (map (\v. bot_ass (\ v)) (fst3 e))) \ ((foldl (op \) Emp_int (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) ( \ (\ \'))))))" using ass_foldl_foldr by auto also have "... = ass (foldl op \ Emp_int (map (\v. bot_ass (\ v)) (fst3 e))) \ ?f" by auto finally have "fst3 ((\(P,_,Q). (ass P, cs!i, ass Q)) (nthtriple (cook ?G ?\) i)) = ass (foldl op \ Emp_int (map (\v. bot_ass (\ v)) (fst3 e))) \ ?f" by auto thus "fst3 ((\(P, _, Q). (ass P, cs ! i, ass Q)) (nthtriple (cook ?G ?\) i)) = fst3 (ass (foldl op \ Emp_int (map (\v. bot_ass (\ v)) (fst3 e))) \ ?f, cs ! i, ass (foldl op \ Emp_int (map (\v. top_ass (\ v)) (thd3 e))) \ ?f)" unfolding fst3_def by auto next have cojiq: "\X Y. snd3 ((\(P,_,Q). (ass P, Y, ass Q)) X) = Y" unfolding snd3_def by auto have "snd3 ((\(P,_,Q). (ass P, cs!i, ass Q)) (nthtriple (cook ?G ?\) i)) = cs!i" unfolding cojiq by auto thus "snd3 ((\(P, _, Q). (ass P, cs ! i, ass Q)) (nthtriple (cook ?G ?\) i)) = snd3 (ass (foldl op \ Emp_int (map (\v. bot_ass (\ v)) (fst3 e))) \ ?f, cs ! i, ass (foldl op \ Emp_int (map (\v. top_ass (\ v)) (thd3 e))) \ ?f)" unfolding snd3_def by auto next have "thd3 ((\(P,_,Q). (ass P, cs!i, ass Q)) (nthtriple (cook ?G ?\) i)) = ass (thd3 (nthtriple (cook ?G ?\) i))" unfolding split_def thd3_def by auto also have "... = ass (foldl op \ Emp_int (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (\ (thd3 (nthtriple ?\ i)))))" unfolding cook.simps nthtriple_chainmap[OF iyuyo] thd3_comp by auto also have "... = ass (foldl op \ Emp_int (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (\ (\ ([(v, Top). v \ thd3 e] @ \')))))" unfolding rraei thd3_def by auto also have "... = ass (foldr op \ (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (\ (\ ([(v, Top). v \ thd3 e] @ \')))) Emp_int)" using ass_foldl_foldr by auto also have "... = ass (((foldr (op \) (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) ([(v, Top). v \ thd3 e] @ \ (\ \'))) Emp_int)))" apply (intro ass_perm_int map_perm) apply (metis Quotient_proofstate perm_append1 perm_refl rep_abs_rsp rep_abs_rsp_left) done also have "... = ass (foldr op \ (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (map (\v. (v, Top)) (thd3 e)) @ map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (\ (\ \'))) Emp_int)" unfolding map_append by auto also have "... = ass (((foldr (op \) ((map (\v. top_ass (\ v)) (thd3 e)) @ map (\(v, z). topbot_case top_ass bot_ass z (\ v)) ( \ (\ \'))) Emp_int)))" unfolding jrlxz by auto also have "... = ass (foldr op \ (map (\v. top_ass (\ v)) (thd3 e)) ((foldr (op \) (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) ( \ (\ \'))) Emp_int)))" by auto also have "... = ass ((foldr op \ (map (\v. top_ass (\ v)) (thd3 e)) Emp_int) \ (foldr op \ (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (\ (\ \'))) Emp_int))" unfolding foldr_hcomp by auto also have "... = ass ((foldl op \ Emp_int (map (\v. top_ass (\ v)) (thd3 e))) \ ((foldl (op \) Emp_int (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) ( \ (\ \'))))))" using ass_foldl_foldr by auto also have "... = ass (foldl op \ Emp_int (map (\v. top_ass (\ v)) (thd3 e))) \ ?f" by auto finally have "thd3 ((\(P,_,Q). (ass P, cs!i, ass Q)) (nthtriple (cook ?G ?\) i)) = ass (foldl op \ Emp_int (map (\v. top_ass (\ v)) (thd3 e))) \ ?f" by auto thus "thd3 ((\(P, _, Q). (ass P, cs ! i, ass Q)) (nthtriple (cook ?G ?\) i)) = thd3 (ass (foldl op \ Emp_int (map (\v. bot_ass (\ v)) (fst3 e))) \ ?f, cs ! i, ass (foldl op \ Emp_int (map (\v. top_ass (\ v)) (thd3 e))) \ ?f)" unfolding thd3_def by auto qed ultimately show ?thesis by auto qed qed moreover have "ass (top_dia ?G) = ass (pre (cook ?G ?\))" proof - let ?lhs = "ass (top_dia ?G)" let ?rhs = "ass (pre (cook ?G ?\))" have "?lhs = ass (foldl op \ Emp_int (map (\v. top_ass (\ v)) (initials ?G)))" by auto also have "... = foldl op \ Emp (map ass (map (\v. top_ass (\ v)) (initials ?G)))" using ass_fold_hcomp by auto also have "... = foldl op \ Emp (map (\v. ass (top_ass (\ v))) (initials ?G))" unfolding map_map comp_def by auto also have "... = foldl op \ Emp (map (\(v,z). ass (top_ass (\ v))) [(v,Top) . v \ initials ?G])" unfolding map_map comp_def by auto also have "... = foldl op \ Emp (map (\(v, z). ass (topbot_case top_ass bot_ass z (\ v))) [(v,Top) . v \ initials ?G])" unfolding map_map comp_def by auto also have "... = foldl op \ Emp ( (map (\(v, z). ass (topbot_case top_ass bot_ass z (\ v))) (\ (pre ?\))))" by (intro ass_perm map_perm, metis conc_abs perm_sym pre.simps(1) pre_mk) also have "... = foldl op \ Emp (map ass ( (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (\ (pre ?\)))))" unfolding map_map comp_def split_def by auto also have "... = ass (foldl op \ Emp_int (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (\ (pre ?\))))" using ass_fold_hcomp by auto also have "... = ?rhs" by (auto simp add: pre_chainmap) finally show "?lhs = ?rhs" by auto qed moreover have "ass (bot_dia ?G) = ass (post (cook ?G ?\))" proof - let ?lhs = "ass (bot_dia ?G)" let ?rhs = "ass (post (cook ?G ?\))" have "?lhs = ass (foldl op \ Emp_int (map (\v. bot_ass (\ v)) (terminals ?G)))" by auto also have "... = foldl op \ Emp (map ass (map (\v. bot_ass (\ v)) (terminals ?G)))" using ass_fold_hcomp by auto also have "... = foldl op \ Emp (map (\v. ass (bot_ass (\ v))) (terminals ?G))" unfolding map_map comp_def by auto also have "... = foldl op \ Emp (map (\(v,z). ass (bot_ass (\ v))) [(v,Bot) . v \ terminals ?G])" unfolding map_map comp_def by auto also have "... = foldl op \ Emp (map (\(v, z). ass (topbot_case top_ass bot_ass z (\ v))) [(v,Bot) . v \ terminals ?G])" unfolding map_map comp_def by auto also have "... = foldl op \ Emp ( (map (\(v, z). ass (topbot_case top_ass bot_ass z (\ v))) (\ (post ?\))))" apply (intro ass_perm map_perm) apply (metis perm_sym lisdi) done also have "... = foldl op \ Emp (map ass ( (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (\ (post ?\)))))" unfolding map_map comp_def split_def by auto also have "... = ass (foldl op \ Emp_int (map (\(v, z). topbot_case top_ass bot_ass z (\ v)) (\ (post ?\))))" using ass_fold_hcomp by auto also have "... = ?rhs" by (auto simp add: post_chainmap) finally show "?lhs = ?rhs" by auto qed ultimately show "prov_triple (ass (top_dia ?G), c, ass (bot_dia ?G))" by auto qed qed theorem var_soundness: assumes "\c. wr_com c = {}" assumes "prov_dia G P Q" shows "\c \ coms_dia G. prov_triple (ass P, c, ass Q)" using var_soundness_helper[OF assms(1)] and assms(2) by auto end