(* 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‹ The type of finite sets is created by a quotient construction over lists. The definition of the equivalence: ›
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)
quotient_type
'a fset = "'a list" / "list_eq" by (rule list_eq_equivp)
text‹ Definitions for sublist, cardinality, intersection, difference and respectful fold over lists. ›
definition
sub_list :: "'a list ==> 'a list ==> bool" where
[simp]: "sub_list xs ys ⟷ set xs ⊆ set ys"
definition
card_list :: "'a list ==> nat" where
[simp]: "card_list xs = card (set xs)"
definition
inter_list :: "'a list ==> 'a list ==> 'a list" where
[simp]: "inter_list xs ys = [x ← xs. x ∈ set xs ∧ x ∈ set ys]"
definition
diff_list :: "'a list ==> 'a list ==> 'a list" where
[simp]: "diff_list xs ys = [x ← xs. x ∉ set ys]"
definition
rsp_fold :: "('a ==> 'b ==> 'b) ==> bool" where "rsp_fold f ⟷ (∀u v. f u ∘ f v = f v ∘ f u)"
lemma rsp_foldI: "(∧u v. f u ∘ f v = f v ∘ f u) ==> rsp_fold f" by (simp add: rsp_fold_def)
lemma rsp_foldE: assumes"rsp_fold f" obtains"f u ∘ f v = f v ∘ f u" using assms by (simp add: rsp_fold_def)
definition
fold_once :: "('a ==> 'b ==> 'b) ==> 'a list ==> 'b ==> 'b" where "fold_once f xs = (if rsp_fold f then fold f (remdups xs) else id)"
lemma fold_once_default [simp]: "¬ rsp_fold f ==> fold_once f xs = id" by (simp add: fold_once_def)
lemma fold_once_fold_remdups: "rsp_fold f ==> fold_once f xs = fold f (remdups xs)" by (simp add: fold_once_def)
section‹Quotient composition lemmas›
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 ∘ (map Abs)) ((map Rep) ∘ 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 (≈)) s s ∧ 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 ∧ 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‹Other constants for fsets›
quotient_definition "insert_fset :: 'a ==> 'a fset ==> 'a fset" is"Cons"by auto
syntax "_fset" :: "args => 'a fset" (‹(‹indent=2 notation=‹mixfix finite set enumeration›\›{|_|})›)
syntax_consts "_fset"⇌ 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‹Other constants on the Quotient Type›
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‹Compositional respectfulness and preservation lemmas›
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 ==> '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‹concat_fset›
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‹filter_fset›
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 |⊂| filter_fset Q xs" unfolding less_fset_def by (auto simp add: subset_filter_fset eq_filter_fset)
subsection‹fold_fset›
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 then if a |∈| A then fold_fset f A else fold_fset f A ∘ 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‹rsp_fold f›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‹Choice in fsets›
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‹Induction and Cases rules for fsets›
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 {||} {||} ==> (∧x xs. x |∉| xs ==> P (insert_fset x xs) {||}) ==> (∧y ys. y |∉| ys ==> P {||} (insert_fset y ys)) ==> (∧x xs y ys. [P xs ys; x |∉| xs; y |∉| ys]==> P (insert_fset x xs) (insert_fset y ys)) ==> 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‹Extensionality›
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‹alternate formulation with a different decomposition principle and a proof of equivalence›
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‹l ≈ r›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; ∧a b xs. [a1 = insert_fset a (insert_fset b xs); a2 = insert_fset b (insert_fset a xs)]==> P; [a1 = {||}; a2 = {||}]==> P; ∧xs ys. [a1 = ys; a2 = xs; xs = ys]==> P; ∧a xs. [a1 = insert_fset a (insert_fset a xs); a2 = insert_fset a xs]==> P; ∧xs ys a. [a1 = insert_fset a xs; a2 = insert_fset a ys; xs = ys]==> P; ∧xs1 xs2 xs3. [a1 = xs1; a2 = xs3; xs1 = xs2; xs2 = xs3]==> P] ==> 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‹≈› 50) and list_eq2 (infix‹≈2› 50)
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.20 Sekunden
(vorverarbeitet am 2026-04-28)
¤
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 und die Messung sind noch experimentell.