(* Title: HOL/Quotient_Examples/Quotient_FSet.thy Author: Cezary Kaliszyk, TU Munich Author: Christian Urban, TU Munich
Type of finite sets.
*)
(******************************************************************** WARNING: There is a formalization of 'a fset as a subtype of sets in HOL/Library/FSet.thy using Lifting/Transfer. The user should use that file rather than this file unless there are some very specific reasons.
*********************************************************************)
theory Quotient_FSet imports"HOL-Library.Multiset""HOL-Library.Quotient_List" begin
text\<open>
The type of finite sets is created by a quotient construction
over lists. The definition of the equivalence: \<close>
definition
list_eq :: "'a list \ 'a list \ bool" (infix \\\ 50) where
[simp]: "xs \ ys \ set xs = set ys"
lemma list_eq_reflp: "reflp list_eq" by (auto intro: reflpI)
lemma list_eq_symp: "symp list_eq" by (auto intro: sympI)
lemma list_eq_transp: "transp list_eq" by (auto intro: transpI)
lemma list_all2_refl': assumes q: "equivp R" shows"(list_all2 R) r r" by (rule list_all2_refl) (metis equivp_def q)
lemma compose_list_refl: assumes q: "equivp R" shows"(list_all2 R OOO (\)) r r" proof have *: "r \ r" by (rule equivp_reflp[OF fset_equivp]) show"list_all2 R r r"by (rule list_all2_refl'[OF q]) with * show"((\) OO list_all2 R) r r" .. qed
lemma map_list_eq_cong: "b \ ba \ map f b \ map f ba" by (simp only: list_eq_def set_map)
lemma quotient_compose_list_g: assumes q: "Quotient3 R Abs Rep" and e: "equivp R" shows"Quotient3 ((list_all2 R) OOO (\))
(abs_fset \<circ> (map Abs)) ((map Rep) \<circ> rep_fset)" unfolding Quotient3_def comp_def proof (intro conjI allI) fix a r s show"abs_fset (map Abs (map Rep (rep_fset a))) = a" by (simp add: abs_o_rep[OF q] Quotient3_abs_rep[OF Quotient3_fset] List.map.id) have b: "list_all2 R (map Rep (rep_fset a)) (map Rep (rep_fset a))" by (rule list_all2_refl'[OF e]) have c: "((\) OO list_all2 R) (map Rep (rep_fset a)) (map Rep (rep_fset a))" by (rule, rule equivp_reflp[OF fset_equivp]) (rule b) show"(list_all2 R OOO (\)) (map Rep (rep_fset a)) (map Rep (rep_fset a))" by (rule, rule list_all2_refl'[OF e]) (rule c) show"(list_all2 R OOO (\)) r s = ((list_all2 R OOO (\)) r r \
(list_all2 R OOO (\<approx>)) s s \<and> abs_fset (map Abs r) = abs_fset (map Abs s))" proof (intro iffI conjI) show"(list_all2 R OOO (\)) r r" by (rule compose_list_refl[OF e]) show"(list_all2 R OOO (\)) s s" by (rule compose_list_refl[OF e]) next assume a: "(list_all2 R OOO (\)) r s" thenhave b: "map Abs r \ map Abs s" proof (elim relcomppE) fix b ba assume c: "list_all2 R r b" assume d: "b \ ba" assume e: "list_all2 R ba s" have f: "map Abs r = map Abs b" using Quotient3_rel[OF list_quotient3[OF q]] c by blast have"map Abs ba = map Abs s" using Quotient3_rel[OF list_quotient3[OF q]] e by blast thenhave g: "map Abs s = map Abs ba"by simp thenshow"map Abs r \ map Abs s" using d f map_list_eq_cong by simp qed thenshow"abs_fset (map Abs r) = abs_fset (map Abs s)" using Quotient3_rel[OF Quotient3_fset] by blast next assume a: "(list_all2 R OOO (\)) r r \ (list_all2 R OOO (\)) s s \<and> abs_fset (map Abs r) = abs_fset (map Abs s)" thenhave s: "(list_all2 R OOO (\)) s s" by simp have d: "map Abs r \ map Abs s" by (subst Quotient3_rel [OF Quotient3_fset, symmetric]) (simp add: a) have b: "map Rep (map Abs r) \ map Rep (map Abs s)" by (rule map_list_eq_cong[OF d]) have y: "list_all2 R (map Rep (map Abs s)) s" by (fact rep_abs_rsp_left[OF list_quotient3[OF q], OF list_all2_refl'[OF e, of s]]) have c: "((\) OO list_all2 R) (map Rep (map Abs r)) s" by (rule relcomppI) (rule b, rule y) have z: "list_all2 R r (map Rep (map Abs r))" by (fact rep_abs_rsp[OF list_quotient3[OF q], OF list_all2_refl'[OF e, of r]]) thenshow"(list_all2 R OOO (\)) r s" using a c relcomppI by simp qed qed
quotient_definition "minus :: 'a fset \ 'a fset \ 'a fset" is"diff_list :: 'a list \ 'a list \ 'a list" by fastforce
instance proof fix x y z :: "'a fset" show"x |\| y \ x |\| y \ \ y |\| x" by (unfold less_fset_def, descending) auto show"x |\| x" by (descending) (simp) show"{||} |\| x" by (descending) (simp) show"x |\| x |\| y" by (descending) (simp) show"y |\| x |\| y" by (descending) (simp) show"x |\| y |\| x" by (descending) (auto) show"x |\| y |\| y" by (descending) (auto) show"x |\| (y |\| z) = x |\| y |\| (x |\| z)" by (descending) (auto) next fix x y z :: "'a fset" assume a: "x |\| y" assume b: "y |\| z" show"x |\| z" using a b by (descending) (simp) next fix x y :: "'a fset" assume a: "x |\| y" assume b: "y |\| x" show"x = y"using a b by (descending) (auto) next fix x y z :: "'a fset" assume a: "y |\| x" assume b: "z |\| x" show"y |\| z |\| x" using a b by (descending) (simp) next fix x y z :: "'a fset" assume a: "x |\| y" assume b: "x |\| z" show"x |\| y |\| z" using a b by (descending) (auto) qed
end
subsection \<open>Other constants for fsets\<close>
quotient_definition "insert_fset :: 'a \ 'a fset \ 'a fset" is"Cons"by auto
syntax "_fset" :: "args => 'a fset" (\<open>(\<open>indent=2 notation=\<open>mixfix finite set enumeration\<close>\<close>{|_|})\<close>)
syntax_consts "_fset"\<rightleftharpoons> insert_fset translations "{|x, xs|}" == "CONST insert_fset x {|xs|}" "{|x|}" == "CONST insert_fset x {||}"
quotient_definition
fset_member where "fset_member :: 'a fset \ 'a \ bool" is "List.member" by fastforce
abbreviation
in_fset :: "'a \ 'a fset \ bool" (infix \|\|\ 50) where "x |\| S \ fset_member S x"
abbreviation
notin_fset :: "'a \ 'a fset \ bool" (infix \|\|\ 50) where "x |\| S \ \ (x |\| S)"
subsection \<open>Other constants on the Quotient Type\<close>
quotient_definition "card_fset :: 'a fset \ nat" is card_list by simp
quotient_definition "map_fset :: ('a \ 'b) \ 'a fset \ 'b fset" is map by simp
quotient_definition "remove_fset :: 'a \ 'a fset \ 'a fset" is removeAll by simp
quotient_definition "fset :: 'a fset \ 'a set" is"set"by simp
lemma fold_once_set_equiv: assumes"xs \ ys" shows"fold_once f xs = fold_once f ys" proof (cases "rsp_fold f") case False thenshow ?thesis by simp next case True thenhave"\x y. x \ set (remdups xs) \ y \ set (remdups xs) \ f x \ f y = f y \ f x" by (rule rsp_foldE) moreoverfrom assms have"mset (remdups xs) = mset (remdups ys)" by (simp add: set_eq_iff_mset_remdups_eq) ultimatelyhave"fold f (remdups xs) = fold f (remdups ys)" by (rule fold_multiset_equiv) with True show ?thesis by (simp add: fold_once_fold_remdups) qed
quotient_definition "fold_fset :: ('a \ 'b \ 'b) \ 'a fset \ 'b \ 'b" is fold_once by (rule fold_once_set_equiv)
lemma concat_rsp_pre: assumes a: "list_all2 (\) x x'" and b: "x' \ y'" and c: "list_all2 (\) y' y" and d: "\x\set x. xa \ set x" shows"\x\set y. xa \ set x" proof - obtain xb where e: "xb \ set x" and f: "xa \ set xb" using d by auto have"\y. y \ set x' \ xb \ y" by (rule list_all2_find_element[OF e a]) thenobtain ya where h: "ya \ set x'" and i: "xb \ ya" by auto have"ya \ set y'" using b h by simp thenhave"\yb. yb \ set y \ ya \ yb" using c by (rule list_all2_find_element) thenshow ?thesis using f i by auto qed
quotient_definition "concat_fset :: ('a fset) fset \ 'a fset" is concat proof (elim relcomppE) fix a b ba bb assume a: "list_all2 (\) a ba" with list_symp [OF list_eq_symp] have a': "list_all2 (\) ba a" by (rule sympE) assume b: "ba \ bb" with list_eq_symp have b': "bb \ ba" by (rule sympE) assume c: "list_all2 (\) bb b" with list_symp [OF list_eq_symp] have c': "list_all2 (\) b bb" by (rule sympE) have"\x. (\xa\set a. x \ set xa) = (\xa\set b. x \ set xa)" proof fix x show"(\xa\set a. x \ set xa) = (\xa\set b. x \ set xa)" proof assume d: "\xa\set a. x \ set xa" show"\xa\set b. x \ set xa" by (rule concat_rsp_pre[OF a b c d]) next assume e: "\xa\set b. x \ set xa" show"\xa\set a. x \ set xa" by (rule concat_rsp_pre[OF c' b' a' e]) qed qed thenshow"concat a \ concat b" by auto qed
quotient_definition "filter_fset :: ('a \ bool) \ 'a fset \ 'a fset" is filter by force
subsection \<open>Compositional respectfulness and preservation lemmas\<close>
lemma list_all2_app_l: assumes a: "reflp R" and b: "list_all2 R l r" shows"list_all2 R (z @ l) (z @ r)" using a b by (induct z) (auto elim: reflpE)
lemma append_rsp2_pre0: assumes"list_all2 (\) x x'" shows"list_all2 (\) (x @ z) (x' @ z)" using assms proof (induct x x' rule: list_induct2') case 1 thenshow ?case using list_all2_refl' list_eq_equivp by blast qed auto
lemma append_rsp2_pre1: assumes"list_all2 (\) x x'" shows"list_all2 (\) (z @ x) (z @ x')" using assms proof (induct x x' arbitrary: z rule: list_induct2') case 1 thenshow ?case using list_all2_refl' list_eq_equivp by blast next case (4 x xs y ys) thenshow ?case using list_all2_app_l list_eq_reflp by blast qed auto
lemma append_rsp2_pre: assumes"list_all2 (\) x x'" and"list_all2 (\) z z'" shows"list_all2 (\) (x @ z) (x' @ z')" using assms list_all2_appendI by blast
lemma compositional_rsp3: assumes"(R1 ===> R2 ===> R3) C C"and"(R4 ===> R5 ===> R6) C C" shows"(R1 OOO R4 ===> R2 OOO R5 ===> R3 OOO R6) C C" using assms by (simp add: OO_def rel_fun_def) metis
lemma map_rsp2 [quot_respect]: "(((\) ===> (\)) ===> list_all2 (\) OOO (\) ===> list_all2 (\) OOO (\)) map map" proof (auto intro!: rel_funI) fix f f' :: "'a list \<Rightarrow> 'b list" fix xa ya x y :: "'a list list" assume fs: "((\) ===> (\)) f f'" and x: "list_all2 (\) xa x" and xy: "set x = set y" and y: "list_all2 (\) y ya" have a: "(list_all2 (\)) (map f xa) (map f x)" using x by (induct xa x rule: list_induct2')
(simp_all, metis fs rel_funE list_eq_def) have b: "set (map f x) = set (map f y)" using xy fs by (induct x y rule: list_induct2')
(simp_all, metis image_insert) have c: "(list_all2 (\)) (map f y) (map f' ya)" using y fs by (induct y ya rule: list_induct2')
(simp_all, metis apply_rsp' list_eq_def) show"(list_all2 (\) OOO (\)) (map f xa) (map f' ya)" by (metis a b c list_eq_def relcomppI) qed
lemma card_insert_fset_iff [simp]: shows"card_fset (insert_fset x S) = (if x |\| S then card_fset S else Suc (card_fset S))" by (descending) (simp add: insert_absorb)
lemma card_fset_0[simp]: shows"card_fset S = 0 \ S = {||}" by (descending) (simp)
lemma card_empty_fset[simp]: shows"card_fset {||} = 0" by (simp add: card_fset)
lemma card_fset_1: shows"card_fset S = 1 \ (\x. S = {|x|})" by (descending) (auto simp add: card_Suc_eq)
lemma card_fset_gt_0: shows"x \ fset S \ 0 < card_fset S" by (descending) (auto simp add: card_gt_0_iff)
lemma card_notin_fset: shows"(x |\| S) = (card_fset (insert_fset x S) = Suc (card_fset S))" by simp
lemma card_fset_Suc: shows"card_fset S = Suc n \ \x T. x |\| T \ S = insert_fset x T \ card_fset T = n" by (metis Suc_inject card_fset_0 card_notin_fset nat.simps(3) notin_remove_fset
remove_fset_cases)
lemma card_remove_fset_iff [simp]: shows"card_fset (remove_fset y S) = (if y |\| S then card_fset S - 1 else card_fset S)" by (descending) (simp)
lemma card_Suc_exists_in_fset: shows"card_fset S = Suc n \ \a. a |\| S" using remove_fset_cases by force
lemma in_card_fset_not_0: shows"a |\| A \ card_fset A \ 0" by (descending) (auto)
lemma card_map_fset_le: shows"card_fset (map_fset f xs) \ card_fset xs" unfolding card_fset map_fset_image by (rule card_image_le[OF finite_fset])
lemma card_minus_insert_fset[simp]: assumes"a |\| A" and "a |\| B" shows"card_fset (A - insert_fset a B) = card_fset (A - B) - 1" using assms by (simp add: in_fset card_fset)
lemma card_minus_subset_fset: assumes"B |\| A" shows"card_fset (A - B) = card_fset A - card_fset B" using assms by (simp add: subset_fset card_fset card_Diff_subset)
lemma card_minus_fset: shows"card_fset (A - B) = card_fset A - card_fset (A |\| B)" by (simp add: card_fset card_Diff_subset_Int)
subsection \<open>concat_fset\<close>
lemma concat_empty_fset [simp]: shows"concat_fset {||} = {||}" by descending simp
lemma concat_insert_fset [simp]: shows"concat_fset (insert_fset x S) = x |\| concat_fset S" by descending simp
lemma map_concat_fset: shows"map_fset f (concat_fset xs) = concat_fset (map_fset (map_fset f) xs)" by (lifting map_concat)
subsection \<open>filter_fset\<close>
lemma subset_filter_fset: "filter_fset P xs |\| filter_fset Q xs = (\ x. x |\| xs \ P x \ Q x)" by descending auto
lemma eq_filter_fset: "(filter_fset P xs = filter_fset Q xs) = (\x. x |\| xs \ P x = Q x)" by descending auto
lemma psubset_filter_fset: "(\x. x |\| xs \ P x \ Q x) \ (x |\| xs & \ P x & Q x) \
filter_fset P xs |\<subset>| filter_fset Q xs" unfolding less_fset_def by (auto simp add: subset_filter_fset eq_filter_fset)
subsection \<open>fold_fset\<close>
lemma fold_empty_fset: "fold_fset f {||} = id" by descending (simp add: fold_once_def)
lemma fold_insert_fset: "fold_fset f (insert_fset a A) =
(if rsp_fold f thenif a |\<in>| A then fold_fset f A else fold_fset f A \<circ> f a else id)" by descending (simp add: fold_once_fold_remdups)
lemma remdups_removeAll: "remdups (removeAll x xs) = remove1 x (remdups xs)" by (induct xs) auto
lemma member_commute_fold_once: assumes"rsp_fold f" and"x \ set xs" shows"fold_once f xs = fold_once f (removeAll x xs) \ f x" proof - from assms have"fold f (remdups xs) = fold f (remove1 x (remdups xs)) \ f x" by (auto intro!: fold_remove1_split elim: rsp_foldE) thenshow ?thesis using\<open>rsp_fold f\<close> by (simp add: fold_once_fold_remdups remdups_removeAll) qed
lemma in_commute_fold_fset: "rsp_fold f \ h |\| b \ fold_fset f b = fold_fset f (remove_fset h b) \ f h" by descending (simp add: member_commute_fold_once)
subsection \<open>Choice in fsets\<close>
lemma fset_choice: assumes"\x. x |\| A \ (\y. P x y)" shows"\f. \x. x |\| A \ P x (f x)" using assms by metis
section \<open>Induction and Cases rules for fsets\<close>
lemma fset_exhaust [case_names empty insert, cases type: fset]: assumes empty_fset_case: "S = {||} \ P" and insert_fset_case: "\x S'. S = insert_fset x S' \ P" shows"P" using assms by (lifting list.exhaust)
lemma fset_induct [case_names empty insert]: assumes empty_fset_case: "P {||}" and insert_fset_case: "\x S. P S \ P (insert_fset x S)" shows"P S" using assms by (descending) (blast intro: list.induct)
lemma fset_induct_stronger [case_names empty insert, induct type: fset]: assumes empty_fset_case: "P {||}" and insert_fset_case: "\x S. \x |\| S; P S\ \ P (insert_fset x S)" shows"P S" proof(induct S rule: fset_induct) case empty show"P {||}"using empty_fset_case by simp next case (insert x S) have"P S"by fact thenshow"P (insert_fset x S)"using insert_fset_case by (cases "x |\| S") (simp_all) qed
lemma fset_card_induct: assumes empty_fset_case: "P {||}" and card_fset_Suc_case: "\S T. Suc (card_fset S) = (card_fset T) \ P S \ P T" shows"P S" proof (induct S) case empty show"P {||}"by (rule empty_fset_case) next case (insert x S) have h: "P S"by fact have"x |\| S" by fact thenhave"Suc (card_fset S) = card_fset (insert_fset x S)" using card_fset_Suc by auto thenshow"P (insert_fset x S)" using h card_fset_Suc_case by simp qed
lemma fset_raw_strong_cases: obtains"xs = []" | ys x where"\ List.member ys x" and "xs \ x # ys" proof (induct xs) case Nil thenshow thesis by simp next case (Cons a xs) show ?case proof (cases "xs=[]") case True thenshow ?thesis using Cons.prems by auto (metis empty_iff empty_subsetI list.set(1)) next case False have"\\ List.member ys x; xs \ x # ys\ \ thesis" for x ys using Cons.prems by auto thenshow ?thesis using Cons.hyps False by blast qed qed
lemma fset_strong_cases: obtains"xs = {||}"
| ys x where"x |\| ys" and "xs = insert_fset x ys" by (lifting fset_raw_strong_cases)
lemma fset_induct2: "P {||} {||} \
(\<And>x xs. x |\<notin>| xs \<Longrightarrow> P (insert_fset x xs) {||}) \<Longrightarrow>
(\<And>y ys. y |\<notin>| ys \<Longrightarrow> P {||} (insert_fset y ys)) \<Longrightarrow>
(\<And>x xs y ys. \<lbrakk>P xs ys; x |\<notin>| xs; y |\<notin>| ys\<rbrakk> \<Longrightarrow> P (insert_fset x xs) (insert_fset y ys)) \<Longrightarrow>
P xsa ysa" proof (induct xsa arbitrary: ysa) case empty thenshow ?case by (meson fset_induct_stronger) next case (insert x xsa) thenshow ?case by (metis fset_strong_cases) qed
text\<open>Extensionality\<close>
lemma fset_eqI: assumes"\x. x \ fset A \ x \ fset B" shows"A = B" using assms proof (induct A arbitrary: B) case empty thenshow ?case by (auto simp add: in_fset none_in_empty_fset [symmetric] sym) next case (insert x A) from insert.prems insert.hyps(1) have"\z. z \ fset A \ z \ fset (B - {|x|})" by (auto simp add: in_fset) thenhave A: "A = B - {|x|}"by (rule insert.hyps(2)) with insert.prems [symmetric, of x] have"x |\| B" by (simp add: in_fset) with A show ?caseby (metis in_fset_mdef) qed
subsection \<open>alternate formulation with a different decomposition principle and a proof of equivalence\<close>
inductive
list_eq2 :: "'a list \ 'a list \ bool" (infix \\2\ 50) where "(a # b # xs) \2 (b # a # xs)"
| "[] \2 []"
| "xs \2 ys \ ys \2 xs"
| "(a # a # xs) \2 (a # xs)"
| "xs \2 ys \ (a # xs) \2 (a # ys)"
| "xs1 \2 xs2 \ xs2 \2 xs3 \ xs1 \2 xs3"
lemma cons_delete_list_eq2: shows"(a # (removeAll a xs)) \2 (if List.member xs a then xs else a # xs)" proof (induct xs) case Nil thenshow ?case by (simp add: list_eq2_refl) next case (Cons x xs) show ?case proof (cases "a=x") case True with Cons show ?thesis apply (simp add: split: if_splits) by (metis list_eq2.simps) next case False with Cons show ?thesis apply (simp add: ) by (smt (verit, ccfv_SIG) list_eq2.intros) qed qed
lemma member_delete_list_eq2: assumes a: "List.member r e" shows"(e # removeAll e r) \2 r" using a cons_delete_list_eq2[of e r] by simp
lemma list_eq2_equiv: "l \ r \ l \2 r" proof show"l \2 r \ l \ r" by (induct rule: list_eq2.induct) auto have"card_list l = n \ l \ r \ l \2 r" for n proof (induct n arbitrary: l r) case 0 have"card_list l = 0"by fact thenhave"\x. \ List.member l x" by auto thenhave z: "l = []"by auto thenhave"r = []"using\<open>l \<approx> r\<close> by simp thenshow ?caseusing z list_eq2_refl by simp next case (Suc m) have b: "l \ r" by fact have d: "card_list l = Suc m"by fact thenhave"\a. List.member l a" by (auto dest: card_eq_SucD) thenobtain a where e: "List.member l a"by auto thenhave e': "List.member r a" using list_eq_def [of l r] b by simp have f: "card_list (removeAll a l) = m"using e d by (simp) have g: "removeAll a l \ removeAll a r" using remove_fset.rsp b by simp have"(removeAll a l) \2 (removeAll a r)" by (rule Suc.hyps[OF f g]) thenhave h: "(a # removeAll a l) \2 (a # removeAll a r)" by (rule list_eq2.intros(5)) have i: "l \2 (a # removeAll a l)" by (rule list_eq2.intros(3)[OF member_delete_list_eq2[OF e]]) have"l \2 (a # removeAll a r)" by (rule list_eq2.intros(6)[OF i h]) thenshow ?caseusing list_eq2.intros(6)[OF _ member_delete_list_eq2[OF e']] by simp qed thenshow"l \ r \ l \2 r" by blast qed
(* We cannot write it as "assumes .. shows" since Isabelle changes the quantifiers to schematic variables and reintroduces them in
a different order *) lemma fset_eq_cases: "\a1 = a2; \<And>a b xs. \<lbrakk>a1 = insert_fset a (insert_fset b xs); a2 = insert_fset b (insert_fset a xs)\<rbrakk> \<Longrightarrow> P; \<lbrakk>a1 = {||}; a2 = {||}\<rbrakk> \<Longrightarrow> P; \<And>xs ys. \<lbrakk>a1 = ys; a2 = xs; xs = ys\<rbrakk> \<Longrightarrow> P; \<And>a xs. \<lbrakk>a1 = insert_fset a (insert_fset a xs); a2 = insert_fset a xs\<rbrakk> \<Longrightarrow> P; \<And>xs ys a. \<lbrakk>a1 = insert_fset a xs; a2 = insert_fset a ys; xs = ys\<rbrakk> \<Longrightarrow> P; \<And>xs1 xs2 xs3. \<lbrakk>a1 = xs1; a2 = xs3; xs1 = xs2; xs2 = xs3\<rbrakk> \<Longrightarrow> P\<rbrakk> \<Longrightarrow> P" by (lifting list_eq2.cases[simplified list_eq2_equiv[symmetric]])
lemma fset_eq_induct: assumes"x1 = x2" and"\a b xs. P (insert_fset a (insert_fset b xs)) (insert_fset b (insert_fset a xs))" and"P {||} {||}" and"\xs ys. \xs = ys; P xs ys\ \ P ys xs" and"\a xs. P (insert_fset a (insert_fset a xs)) (insert_fset a xs)" and"\xs ys a. \xs = ys; P xs ys\ \ P (insert_fset a xs) (insert_fset a ys)" and"\xs1 xs2 xs3. \xs1 = xs2; P xs1 xs2; xs2 = xs3; P xs2 xs3\ \ P xs1 xs3" shows"P x1 x2" using assms by (lifting list_eq2.induct[simplified list_eq2_equiv[symmetric]])
no_notation list_eq (infix\<open>\<approx>\<close> 50) and list_eq2 (infix \<open>\<approx>2\<close> 50)
end
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.