diff --git a/thys/Stateful_Protocol_Composition_and_Typing/Miscellaneous.thy b/thys/Stateful_Protocol_Composition_and_Typing/Miscellaneous.thy --- a/thys/Stateful_Protocol_Composition_and_Typing/Miscellaneous.thy +++ b/thys/Stateful_Protocol_Composition_and_Typing/Miscellaneous.thy @@ -1,747 +1,747 @@ (* Title: Miscellaneous.thy Author: Andreas Viktor Hess, DTU SPDX-License-Identifier: BSD-3-Clause *) section \Miscellaneous Lemmata\ theory Miscellaneous imports Main "HOL-Library.Sublist" "HOL-Library.Infinite_Set" "HOL-Library.While_Combinator" begin subsection \List: zip, filter, map\ lemma zip_arg_subterm_split: assumes "(x,y) \ set (zip xs ys)" obtains xs' xs'' ys' ys'' where "xs = xs'@x#xs''" "ys = ys'@y#ys''" "length xs' = length ys'" proof - from assms have "\zs zs' vs vs'. xs = zs@x#zs' \ ys = vs@y#vs' \ length zs = length vs" proof (induction ys arbitrary: xs) case (Cons y' ys' xs) then obtain x' xs' where x': "xs = x'#xs'" by (metis empty_iff list.exhaust list.set(1) set_zip_leftD) show ?case by (cases "(x, y) \ set (zip xs' ys')", metis \xs = x'#xs'\ Cons.IH[of xs'] Cons_eq_appendI list.size(4), use Cons.prems x' in fastforce) qed simp thus ?thesis using that by blast qed lemma zip_arg_index: assumes "(x,y) \ set (zip xs ys)" obtains i where "xs ! i = x" "ys ! i = y" "i < length xs" "i < length ys" proof - obtain xs1 xs2 ys1 ys2 where "xs = xs1@x#xs2" "ys = ys1@y#ys2" "length xs1 = length ys1" using zip_arg_subterm_split[OF assms] by blast thus ?thesis using nth_append_length[of xs1 x xs2] nth_append_length[of ys1 y ys2] that by simp qed lemma in_set_zip_swap: "(x,y) \ set (zip xs ys) \ (y,x) \ set (zip ys xs)" unfolding in_set_zip by auto lemma filter_nth: "i < length (filter P xs) \ P (filter P xs ! i)" using nth_mem by force lemma list_all_filter_eq: "list_all P xs \ filter P xs = xs" by (metis list_all_iff filter_True) lemma list_all_filter_nil: assumes "list_all P xs" and "\x. P x \ \Q x" shows "filter Q xs = []" using assms by (induct xs) simp_all lemma list_all_concat: "list_all (list_all f) P \ list_all f (concat P)" by (induct P) auto lemma list_all2_in_set_ex: assumes P: "list_all2 P xs ys" and x: "x \ set xs" shows "\y \ set ys. P x y" proof - obtain i where i: "i < length xs" "xs ! i = x" by (meson x in_set_conv_nth) have "i < length ys" "P (xs ! i) (ys ! i)" using P i(1) by (simp_all add: list_all2_iff list_all2_nthD) thus ?thesis using i(2) by auto qed lemma list_all2_in_set_ex': assumes P: "list_all2 P xs ys" and y: "y \ set ys" shows "\x \ set xs. P x y" proof - obtain i where i: "i < length ys" "ys ! i = y" by (meson y in_set_conv_nth) have "i < length xs" "P (xs ! i) (ys ! i)" using P i(1) by (simp_all add: list_all2_iff list_all2_nthD) thus ?thesis using i(2) by auto qed lemma list_all2_sym: assumes "\x y. P x y \ P y x" and "list_all2 P xs ys" shows "list_all2 P ys xs" using assms(2) by (induct rule: list_all2_induct) (simp_all add: assms(1)) lemma map_upt_index_eq: assumes "j < length xs" shows "(map (\i. xs ! is i) [0..(i,p) \ insert x (set xs). \(i',p') \ insert x (set xs). p = p' \ i = i'" shows "map snd (List.insert x xs) = List.insert (snd x) (map snd xs)" using assms proof (induction xs rule: List.rev_induct) case (snoc y xs) hence IH: "map snd (List.insert x xs) = List.insert (snd x) (map snd xs)" by fastforce obtain iy py where y: "y = (iy,py)" by (metis surj_pair) obtain ix px where x: "x = (ix,px)" by (metis surj_pair) have "(ix,px) \ insert x (set (y#xs))" "(iy,py) \ insert x (set (y#xs))" using y x by auto hence *: "iy = ix" when "py = px" using that snoc.prems by auto show ?case proof (cases "px = py") case True hence "y = x" using * y x by auto thus ?thesis using IH by simp next case False hence "y \ x" using y x by simp have "List.insert x (xs@[y]) = (List.insert x xs)@[y]" proof - have 1: "insert y (set xs) = set (xs@[y])" by simp have 2: "x \ insert y (set xs) \ x \ set xs" using \y \ x\ by blast show ?thesis using 1 2 by (metis (no_types) List.insert_def append_Cons insertCI) qed thus ?thesis using IH y x False by (auto simp add: List.insert_def) qed qed simp lemma map_append_inv: "map f xs = ys@zs \ \vs ws. xs = vs@ws \ map f vs = ys \ map f ws = zs" proof (induction xs arbitrary: ys zs) case (Cons x xs') note prems = Cons.prems note IH = Cons.IH show ?case proof (cases ys) case (Cons y ys') then obtain vs' ws where *: "xs' = vs'@ws" "map f vs' = ys'" "map f ws = zs" using prems IH[of ys' zs] by auto hence "x#xs' = (x#vs')@ws" "map f (x#vs') = y#ys'" using Cons prems by force+ thus ?thesis by (metis Cons *(3)) qed (use prems in simp) qed simp lemma map2_those_Some_case: assumes "those (map2 f xs ys) = Some zs" and "(x,y) \ set (zip xs ys)" shows "\z. f x y = Some z" using assms proof (induction xs arbitrary: ys zs) case (Cons x' xs') obtain y' ys' where ys: "ys = y'#ys'" using Cons.prems(2) by (cases ys) simp_all obtain z where z: "f x' y' = Some z" using Cons.prems(1) ys by fastforce obtain zs' where zs: "those (map2 f xs' ys') = Some zs'" using z Cons.prems(1) ys by auto show ?case proof (cases "(x,y) = (x',y')") case False hence "(x,y) \ set (zip xs' ys')" using Cons.prems(2) unfolding ys by force thus ?thesis using Cons.IH[OF zs] by blast qed (use ys z in fast) qed simp lemma those_Some_Cons_ex: assumes "those (x#xs) = Some ys" shows "\y ys'. ys = y#ys' \ those xs = Some ys' \ x = Some y" using assms by (cases x) auto lemma those_Some_iff: "those xs = Some ys \ ((\x' \ set xs. \x. x' = Some x) \ ys = map the xs)" (is "?A xs ys \ ?B xs ys") proof show "?A xs ys \ ?B xs ys" proof (induction xs arbitrary: ys) case (Cons x' xs') obtain y' ys' where ys: "ys = y'#ys'" "those xs' = Some ys'" and x: "x' = Some y'" using Cons.prems those_Some_Cons_ex by blast show ?case using Cons.IH[OF ys(2)] unfolding x ys by simp qed simp show "?B xs ys \ ?A xs ys" by (induct xs arbitrary: ys) (simp, fastforce) qed lemma those_map2_SomeD: assumes "those (map2 f ts ss) = Some \" and "\ \ set \" shows "\(t,s) \ set (zip ts ss). f t s = Some \" using those_Some_iff[of "map2 f ts ss" \] assms by fastforce lemma those_map2_SomeI: assumes "\i. i < length xs \ f (xs ! i) (ys ! i) = Some (g i)" and "length xs = length ys" shows "those (map2 f xs ys) = Some (map g [0..z \ set (map2 f xs ys). \z'. z = Some z'" proof fix z assume z: "z \ set (map2 f xs ys)" then obtain i where i: "i < length xs" "i < length ys" "z = f (xs ! i) (ys ! i)" using in_set_conv_nth[of z "map2 f xs ys"] by auto thus "\z'. z = Some z'" using assms(1) by blast qed moreover have "map Some (map g [0..i. f (xs ! i) (ys ! i)) [0.. Some) (map g [0..List: subsequences\ lemma subseqs_set_subset: assumes "ys \ set (subseqs xs)" shows "set ys \ set xs" using assms subseqs_powset[of xs] by auto lemma subset_sublist_exists: "ys \ set xs \ \zs. set zs = ys \ zs \ set (subseqs xs)" proof (induction xs arbitrary: ys) case Cons thus ?case by (metis (no_types, lifting) Pow_iff imageE subseqs_powset) qed simp lemma map_subseqs: "map (map f) (subseqs xs) = subseqs (map f xs)" proof (induct xs) case (Cons x xs) have "map (Cons (f x)) (map (map f) (subseqs xs)) = map (map f) (map (Cons x) (subseqs xs))" by (induct "subseqs xs") auto thus ?case by (simp add: Let_def Cons) qed simp lemma subseqs_Cons: assumes "ys \ set (subseqs xs)" shows "ys \ set (subseqs (x#xs))" by (metis assms Un_iff set_append subseqs.simps(2)) lemma subseqs_subset: assumes "ys \ set (subseqs xs)" shows "set ys \ set xs" using assms by (metis Pow_iff image_eqI subseqs_powset) subsection \List: prefixes, suffixes\ lemma suffix_Cons': "suffix [x] (y#ys) \ suffix [x] ys \ (y = x \ ys = [])" using suffix_Cons[of "[x]"] by auto lemma prefix_Cons': "prefix (x#xs) (x#ys) \ prefix xs ys" by simp lemma prefix_map: "prefix xs (map f ys) \ \zs. prefix zs ys \ map f zs = xs" using map_append_inv unfolding prefix_def by fast lemma concat_mono_prefix: "prefix xs ys \ prefix (concat xs) (concat ys)" unfolding prefix_def by fastforce lemma concat_map_mono_prefix: "prefix xs ys \ prefix (concat (map f xs)) (concat (map f ys))" by (rule map_mono_prefix[THEN concat_mono_prefix]) lemma length_prefix_ex: assumes "n \ length xs" shows "\ys zs. xs = ys@zs \ length ys = n" using assms proof (induction n) case (Suc n) then obtain ys zs where IH: "xs = ys@zs" "length ys = n" by atomize_elim auto hence "length zs > 0" using Suc.prems(1) by auto then obtain v vs where v: "zs = v#vs" by (metis Suc_length_conv gr0_conv_Suc) hence "length (ys@[v]) = Suc n" using IH(2) by simp thus ?case using IH(1) v by (metis append.assoc append_Cons append_Nil) qed simp lemma length_prefix_ex': assumes "n < length xs" shows "\ys zs. xs = ys@xs ! n#zs \ length ys = n" proof - obtain ys zs where xs: "xs = ys@zs" "length ys = n" using assms length_prefix_ex[of n xs] by atomize_elim auto hence "length zs > 0" using assms by auto then obtain v vs where v: "zs = v#vs" by (metis Suc_length_conv gr0_conv_Suc) hence "(ys@zs) ! n = v" using xs by auto thus ?thesis using v xs by auto qed lemma length_prefix_ex2: assumes "i < length xs" "j < length xs" "i < j" shows "\ys zs vs. xs = ys@xs ! i#zs@xs ! j#vs \ length ys = i \ length zs = j - i - 1" proof - obtain xs0 vs where xs0: "xs = xs0@xs ! j#vs" "length xs0 = j" using length_prefix_ex'[OF assms(2)] by blast then obtain ys zs where "xs0 = ys@xs ! i#zs" "length ys = i" by (metis assms(3) length_prefix_ex' nth_append[of _ _ i]) thus ?thesis using xs0 by force qed lemma prefix_prefix_inv: assumes xs: "prefix xs (ys@zs)" and x: "suffix [x] xs" shows "prefix xs ys \ x \ set zs" proof - have "prefix xs ys" when "x \ set zs" using that xs proof (induction zs rule: rev_induct) case (snoc z zs) show ?case proof (rule snoc.IH) have "x \ z" using snoc.prems(1) by simp thus "prefix xs (ys@zs)" using snoc.prems(2) x by (metis append1_eq_conv append_assoc prefix_snoc suffixE) qed (use snoc.prems(1) in simp) qed simp thus ?thesis by blast qed lemma prefix_snoc_obtain: assumes xs: "prefix (xs@[x]) (ys@zs)" and ys: "\prefix (xs@[x]) ys" obtains vs where "xs@[x] = ys@vs@[x]" "prefix (vs@[x]) zs" proof - have "\vs. xs@[x] = ys@vs@[x] \ prefix (vs@[x]) zs" using xs proof (induction zs rule: List.rev_induct) case (snoc z zs) show ?case proof (cases "xs@[x] = ys@zs@[z]") case False hence "prefix (xs@[x]) (ys@zs)" using snoc.prems by (metis append_assoc prefix_snoc) thus ?thesis using snoc.IH by auto qed simp qed (simp add: ys) thus ?thesis using that by blast qed lemma prefix_snoc_in_iff: "x \ set xs \ (\B. prefix (B@[x]) xs)" by (induct xs rule: List.rev_induct) auto subsection \List: products\ lemma product_lists_Cons: "x#xs \ set (product_lists (y#ys)) \ (xs \ set (product_lists ys) \ x \ set y)" by auto lemma product_lists_in_set_nth: assumes "xs \ set (product_lists ys)" shows "\i set (ys ! i)" proof - have 0: "length ys = length xs" using assms(1) by (simp add: in_set_product_lists_length) thus ?thesis using assms proof (induction ys arbitrary: xs) case (Cons y ys) obtain x xs' where xs: "xs = x#xs'" using Cons.prems(1) by (metis length_Suc_conv) hence "xs' \ set (product_lists ys) \ \i set (ys ! i)" "length ys = length xs'" "x#xs' \ set (product_lists (y#ys))" using Cons by simp_all thus ?case using xs product_lists_Cons[of x xs' y ys] by (simp add: nth_Cons') qed simp qed lemma product_lists_in_set_nth': assumes "\i set (xs ! i)" and "length xs = length ys" shows "ys \ set (product_lists xs)" using assms proof (induction xs arbitrary: ys) case (Cons x xs) obtain y ys' where ys: "ys = y#ys'" using Cons.prems(2) by (metis length_Suc_conv) hence "ys' \ set (product_lists xs)" "y \ set x" "length xs = length ys'" using Cons by fastforce+ thus ?case using ys product_lists_Cons[of y ys' x xs] by (simp add: nth_Cons') qed simp subsection \Other Lemmata\ lemma finite_ballI: "\l \ {}. P l" "P x \ \l \ xs. P l \ \l \ insert x xs. P l" by (blast, blast) lemma list_set_ballI: "\l \ set []. P l" "P x \ \l \ set xs. P l \ \l \ set (x#xs). P l" by (simp, simp) lemma inv_set_fset: "finite M \ set (inv set M) = M" unfolding inv_def by (metis (mono_tags) finite_list someI_ex) lemma lfp_eqI': assumes "mono f" and "f C = C" and "\X \ Pow C. f X = X \ X = C" shows "lfp f = C" by (metis PowI assms lfp_lowerbound lfp_unfold subset_refl) lemma lfp_while': fixes f::"'a set \ 'a set" and M::"'a set" defines "N \ while (\A. f A \ A) f {}" assumes f_mono: "mono f" and N_finite: "finite N" and N_supset: "f N \ N" shows "lfp f = N" proof - have *: "f X \ N" when "X \ N" for X using N_supset monoD[OF f_mono that] by blast show ?thesis using lfp_while[OF f_mono * N_finite] by (simp add: N_def) qed lemma lfp_while'': fixes f::"'a set \ 'a set" and M::"'a set" defines "N \ while (\A. f A \ A) f {}" assumes f_mono: "mono f" and lfp_finite: "finite (lfp f)" shows "lfp f = N" proof - have *: "f X \ lfp f" when "X \ lfp f" for X using lfp_fixpoint[OF f_mono] monoD[OF f_mono that] by blast show ?thesis using lfp_while[OF f_mono * lfp_finite] by (simp add: N_def) qed lemma preordered_finite_set_has_maxima: assumes "finite A" "A \ {}" shows "\a::'a::{preorder} \ A. \b \ A. \(a < b)" using assms proof (induction A rule: finite_induct) case (insert a A) thus ?case by (cases "A = {}", simp, metis insert_iff order_trans less_le_not_le) qed simp lemma partition_index_bij: fixes n::nat obtains I k where "bij_betw I {0.. n" "\i. i < k \ P (I i)" "\i. k \ i \ i < n \ \(P (I i))" proof - define A where "A = filter P [0..i. \P i) [0..n. (A@B) ! n)" note defs = A_def B_def k_def I_def have k1: "k \ n" by (metis defs(1,3) diff_le_self dual_order.trans length_filter_le length_upt) have "i < k \ P (A ! i)" for i by (metis defs(1,3) filter_nth) hence k2: "i < k \ P ((A@B) ! i)" for i by (simp add: defs nth_append) have "i < length B \ \(P (B ! i))" for i by (metis defs(2) filter_nth) hence "i < length B \ \(P ((A@B) ! (k + i)))" for i using k_def by simp hence "k \ i \ i < k + length B \ \(P ((A@B) ! i))" for i by (metis add.commute add_less_imp_less_right le_add_diff_inverse2) hence k3: "k \ i \ i < n \ \(P ((A@B) ! i))" for i by (simp add: defs sum_length_filter_compl) have *: "length (A@B) = n" "set (A@B) = {0.. {0.. y \ {0.. (I x = I y) = (x = y)" by (metis *(1,3) defs(4) nth_eq_iff_index_eq atLeastLessThan_iff) next fix x show "x \ {0.. I x \ {0.. {0.. \x \ {0..x. x \ set xs \ finite {y. P x y}" shows "finite {ys. length xs = length ys \ (\y \ set ys. \x \ set xs. P x y)}" proof - define Q where "Q \ \ys. \y \ set ys. \x \ set xs. P x y" define M where "M \ {y. \x \ set xs. P x y}" have 0: "finite M" using assms unfolding M_def by fastforce have "Q ys \ set ys \ M" "(Q ys \ length ys = length xs) \ (length xs = length ys \ Q ys)" for ys unfolding Q_def M_def by auto thus ?thesis using finite_lists_length_eq[OF 0, of "length xs"] unfolding Q_def by presburger qed lemma trancl_eqI: assumes "\(a,b) \ A. \(c,d) \ A. b = c \ (a,d) \ A" shows "A = A\<^sup>+" proof show "A\<^sup>+ \ A" proof fix x assume x: "x \ A\<^sup>+" then obtain a b where ab: "x = (a,b)" by (metis surj_pair) hence "(a,b) \ A\<^sup>+" using x by metis hence "(a,b) \ A" using assms by (induct rule: trancl_induct) auto thus "x \ A" using ab by metis qed qed auto lemma trancl_eqI': assumes "\(a,b) \ A. \(c,d) \ A. b = c \ a \ d \ (a,d) \ A" and "\(a,b) \ A. a \ b" shows "A = {(a,b) \ A\<^sup>+. a \ b}" proof show "{(a,b) \ A\<^sup>+. a \ b} \ A" proof fix x assume x: "x \ {(a,b) \ A\<^sup>+. a \ b}" then obtain a b where ab: "x = (a,b)" by (metis surj_pair) hence "(a,b) \ A\<^sup>+" "a \ b" using x by blast+ hence "(a,b) \ A" proof (induction rule: trancl_induct) case base thus ?case by blast next case step thus ?case using assms(1) by force qed thus "x \ A" using ab by metis qed qed (use assms(2) in auto) lemma distinct_concat_idx_disjoint: assumes xs: "distinct (concat xs)" and ij: "i < length xs" "j < length xs" "i < j" shows "set (xs ! i) \ set (xs ! j) = {}" proof - obtain ys zs vs where ys: "xs = ys@xs ! i#zs@xs ! j#vs" "length ys = i" "length zs = j - i - 1" using length_prefix_ex2[OF ij] by atomize_elim auto thus ?thesis using xs concat_append[of "ys@xs ! i#zs" "xs ! j#vs"] distinct_append[of "concat (ys@xs ! i#zs)" "concat (xs ! j#vs)"] by auto qed lemma remdups_ex2: "length (remdups xs) > 1 \ \a \ set xs. \b \ set xs. a \ b" by (metis distinct_Ex1 distinct_remdups less_trans nth_mem set_remdups zero_less_one zero_neq_one) lemma trancl_minus_refl_idem: defines "cl \ \ts. {(a,b) \ ts\<^sup>+. a \ b}" shows "cl (cl ts) = cl ts" proof - have 0: "(ts\<^sup>+)\<^sup>+ = ts\<^sup>+" "cl ts \ ts\<^sup>+" "(cl ts)\<^sup>+ \ (ts\<^sup>+)\<^sup>+" proof - show "(ts\<^sup>+)\<^sup>+ = ts\<^sup>+" "cl ts \ ts\<^sup>+" unfolding cl_def by auto thus "(cl ts)\<^sup>+ \ (ts\<^sup>+)\<^sup>+" using trancl_mono[of _ "cl ts" "ts\<^sup>+"] by blast qed have 1: "t \ cl (cl ts)" when t: "t \ cl ts" for t using t 0 unfolding cl_def by fast have 2: "t \ cl ts" when t: "t \ cl (cl ts)" for t proof - obtain a b where ab: "t = (a,b)" by (metis surj_pair) have "t \ (cl ts)\<^sup>+" and a_neq_b: "a \ b" using t unfolding cl_def ab by force+ hence "t \ ts\<^sup>+" using 0 by blast thus ?thesis using a_neq_b unfolding cl_def ab by blast qed show ?thesis using 1 2 by blast qed lemma ex_list_obtain: assumes ts: "\t. t \ set ts \ \s. P t s" obtains ss where "length ss = length ts" "\i < length ss. P (ts ! i) (ss ! i)" proof - have "\ss. length ss = length ts \ (\i < length ss. P (ts ! i) (ss ! i))" using ts proof (induction ts rule: List.rev_induct) case (snoc t ts) obtain s ss where s: "length ss = length ts" "\i < length ss. P (ts ! i) (ss ! i)" "P t s" using snoc.IH snoc.prems by force have *: "length (ss@[s]) = length (ts@[t])" using s(1) by simp hence "P ((ts@[t]) ! i) ((ss@[s]) ! i)" when i: "i < length (ss@[s])" for i using s(2,3) i nth_append[of ts "[t]"] nth_append[of ss "[s]"] by force thus ?case using * by blast qed simp thus thesis using that by blast qed lemma length_1_conv[iff]: "(length ts = 1) = (\a. ts = [a])" by (cases ts) simp_all lemma length_2_conv[iff]: "(length ts = 2) = (\a b. ts = [a,b])" proof (cases ts) case (Cons a ts') thus ?thesis by (cases ts') simp_all qed simp lemma length_3_conv[iff]: "(length ts = 3) \ (\a b c. ts = [a,b,c])" proof (cases ts) case (Cons a ts') note * = this thus ?thesis proof (cases ts') case (Cons b ts'') thus ?thesis using * by (cases ts'') simp_all qed simp qed simp lemma Max_nat_finite_le: assumes "finite M" and "\m. m \ M \ f m \ (n::nat)" shows "Max (insert 0 (f ` M)) \ n" proof - have 0: "finite (insert 0 (f ` M))" using assms(1) by blast have 1: "insert 0 (f ` M) \ {}" by force have 2: "m \ n" when "m \ insert 0 (f ` M)" for m using assms(2) that by fastforce show ?thesis using Max.boundedI[OF 0 1 2] by blast qed lemma Max_nat_finite_lt: assumes "finite M" and "M \ {}" and "\m. m \ M \ f m < (n::nat)" shows "Max (f ` M) < n" proof - define g where "g \ \m. Suc (f m)" have 0: "finite (f ` M)" "finite (g ` M)" using assms(1) by (blast, blast) have 1: "f ` M \ {}" "g ` M \ {}" using assms(2) by (force, force) have 2: "m \ n" when "m \ g ` M" for m using assms(3) that unfolding g_def by fastforce have 3: "Max (g ` M) \ n" using Max.boundedI[OF 0(2) 1(2) 2] by blast have 4: "Max (f ` M) < Max (g ` M)" using Max_in[OF 0(1) 1(1)] Max_gr_iff[OF 0(2) 1(2), of "Max (f ` M)"] unfolding g_def by blast show ?thesis using 3 4 by linarith qed lemma ex_finite_disj_nat_inj: fixes N N'::"nat set" assumes N: "finite N" and N': "finite N'" shows "\M::nat set. \\::nat \ nat. inj \ \ \ ` N = M \ M \ N' = {}" using N proof (induction N rule: finite_induct) case empty thus ?case using injI[of "\x::nat. x"] by blast next case (insert n N) then obtain M \ where M: "inj \" "\ ` N = M" "M \ N' = {}" by blast obtain m where m: "m \ M" "m \ insert n N" "m \ N'" using M(2) finite_imageI[OF insert.hyps(1), of \] insert.hyps(1) N' by (metis finite_UnI finite_insert UnCI infinite_nat_iff_unbounded_le finite_nat_set_iff_bounded_le) define \ where "\ \ \k. if k \ insert n N then (\(n := m)) k else Suc (Max (insert m M)) + k" have "insert m M \ N' = {}" using m M(3) unfolding \_def by auto moreover have "\ ` insert n N = insert m M" using insert.hyps(2) M(2) unfolding \_def by auto moreover have "inj \" proof (intro injI) fix i j assume ij: "\ i = \ j" have 0: "finite (insert m (\ ` N))" using insert.hyps(1) by simp have 1: "Suc (Max (insert m (\ ` N))) > k" when k: "k \ insert m (\ ` N)" for k using Max_ge[OF 0 k] by linarith have 2: "(\(n := m)) k \ insert m (\ ` N)" when k: "k \ insert n N" for k using k by auto have 3: "(\(n := m)) k \ Suc (Max (insert m (\ ` N))) + k'" when k: "k \ insert n N" for k k' using 1[OF 2[OF k]] by linarith have 4: "i \ insert n N \ j \ insert n N" using ij 3 M(2) unfolding \_def by metis show "i = j" proof (cases "i \ insert n N") case True hence *: "\ i = (\(n := m)) i" "\ j = (\(n := m)) j" "i \ insert n N" "j \ insert n N" using ij iffD1[OF 4] unfolding \_def by (argo, argo, argo, argo) show ?thesis proof (cases "i = n \ j = n") case True moreover have ?thesis when "i = n" "j = n" using that by simp moreover have False when "(i = n \ j \ n) \ (i \ n \ j = n)" by (metis M(2) that ij * m(1) fun_upd_other fun_upd_same image_eqI insertE) ultimately show ?thesis by argo next case False thus ?thesis using ij injD[OF M(1), of i j] unfolding *(1,2) by simp qed next case False thus ?thesis using ij 4 unfolding \_def by force qed qed ultimately show ?case by blast qed subsection \Infinite Paths in Relations as Mappings from Naturals to States\ context begin private fun rel_chain_fun::"nat \ 'a \ 'a \ ('a \ 'a) set \ 'a" where "rel_chain_fun 0 x _ _ = x" | "rel_chain_fun (Suc i) x y r = (if i = 0 then y else SOME z. (rel_chain_fun i x y r, z) \ r)" lemma infinite_chain_intro: fixes r::"('a \ 'a) set" assumes "\(a,b) \ r. \c. (b,c) \ r" "r \ {}" shows "\f. \i::nat. (f i, f (Suc i)) \ r" proof - from assms(2) obtain a b where "(a,b) \ r" by auto let ?P = "\i. (rel_chain_fun i a b r, rel_chain_fun (Suc i) a b r) \ r" let ?Q = "\i. \z. (rel_chain_fun i a b r, z) \ r" have base: "?P 0" using \(a,b) \ r\ by auto have step: "?P (Suc i)" when i: "?P i" for i proof - have "?Q (Suc i)" using assms(1) i by auto thus ?thesis using someI_ex[OF \?Q (Suc i)\] by auto qed have "\i::nat. (rel_chain_fun i a b r, rel_chain_fun (Suc i) a b r) \ r" using base step nat_induct[of ?P] by simp thus ?thesis by fastforce qed end lemma infinite_chain_intro': fixes r::"('a \ 'a) set" assumes base: "\b. (x,b) \ r" and step: "\b. (x,b) \ r\<^sup>+ \ (\c. (b,c) \ r)" shows "\f. \i::nat. (f i, f (Suc i)) \ r" proof - let ?s = "{(a,b) \ r. a = x \ (x,a) \ r\<^sup>+}" have "?s \ {}" using base by auto have "\c. (b,c) \ ?s" when ab: "(a,b) \ ?s" for a b proof (cases "a = x") case False hence "(x,a) \ r\<^sup>+" using ab by auto hence "(x,b) \ r\<^sup>+" using \(a,b) \ ?s\ by auto thus ?thesis using step by auto qed (use ab step in auto) hence "\f. \i. (f i, f (Suc i)) \ ?s" using infinite_chain_intro[of ?s] \?s \ {}\ by blast thus ?thesis by auto qed lemma infinite_chain_mono: assumes "S \ T" "\f. \i::nat. (f i, f (Suc i)) \ S" shows "\f. \i::nat. (f i, f (Suc i)) \ T" using assms by auto end