lemma finite_induct [case_names empty insert, induct set: finite]: 🍋‹Discharging ‹x ∉ F›entails extra work.› assumes"finite F" assumes"P {}" and insert: "∧x F. finite F ==> x ∉ F ==> P F ==> P (insert x F)" shows"P F" using‹finite F› proof induct show"P {}"by fact next fix x F assume F: "finite F"and P: "P F" show"P (insert x F)" proof cases assume"x ∈ F" thenhave"insert x F = F"by (rule insert_absorb) with P show ?thesis by (simp only:) next assume"x ∉ F" from F this P show ?thesis by (rule insert) qed qed
lemma infinite_finite_induct [case_names infinite empty insert]: assumes infinite: "∧A. ¬ finite A ==> P A" and empty: "P {}" and insert: "∧x F. finite F ==> x ∉ F ==> P F ==> P (insert x F)" shows"P A" proof (cases "finite A") case False with infinite show ?thesis . next case True thenshow ?thesis by (induct A) (fact empty insert)+ qed
subsubsection ‹Choice principles›
lemma ex_new_if_finite: 🍋‹does not depend on def of finite at all› assumes"¬ finite (UNIV :: 'a set)"and"finite A" shows"∃a::'a. a ∉ A" proof - from assms have"A ≠ UNIV"by blast thenshow ?thesis by blast qed
text‹A finite choice principle. Does not need the SOME choice operator.›
lemma finite_set_choice: "finite A ==>∀x∈A. ∃y. P x y ==>∃f. ∀x∈A. P x (f x)" proof (induct rule: finite_induct) case empty thenshow ?caseby simp next case (insert a A) thenobtain f b where f: "∀x∈A. P x (f x)"and ab: "P a b" by auto show ?case (is"∃f. ?P f") proof show"?P (λx. if x = a then b else f x)" using f ab by auto qed qed
subsubsection ‹Finite sets are the images of initial segments of natural numbers›
lemma finite_imp_nat_seg_image_inj_on: assumes"finite A" shows"∃(n::nat) f. A = f ` {i. i < n} ∧ inj_on f {i. i < n}" using assms proof induct case empty show ?case proof show"∃f. {} = f ` {i::nat. i < 0} ∧ inj_on f {i. i < 0}" by simp qed next case (insert a A) have notinA: "a ∉ A"by fact from insert.hyps obtain n f where"A = f ` {i::nat. i < n}""inj_on f {i. i < n}" by blast thenhave"insert a A = f(n:=a) ` {i. i < Suc n}"and"inj_on (f(n:=a)) {i. i < Suc n}" using notinA by (auto simp add: image_def Ball_def inj_on_def less_Suc_eq) thenshow ?caseby blast qed
lemma nat_seg_image_imp_finite: "A = f ` {i::nat. i < n} ==> finite A" proof (induct n arbitrary: A) case 0 thenshow ?caseby simp next case (Suc n) let ?B = "f ` {i. i < n}" have finB: "finite ?B"by (rule Suc.hyps[OF refl]) show ?case proof (cases "∃k) case True thenhave"A = ?B" using Suc.prems by (auto simp:less_Suc_eq) thenshow ?thesis using finB by simp next case False thenhave"A = insert (f n) ?B" using Suc.prems by (auto simp:less_Suc_eq) thenshow ?thesis using finB by simp qed qed
lemma finite_conv_nat_seg_image: "finite A ⟷ (∃n f. A = f ` {i::nat. i < n})" by (blast intro: nat_seg_image_imp_finite dest: finite_imp_nat_seg_image_inj_on)
lemma finite_imp_inj_to_nat_seg: assumes"finite A" shows"∃f n. f ` A = {i::nat. i < n} ∧ inj_on f A" proof - from finite_imp_nat_seg_image_inj_on [OF ‹finite A›] obtain f and n :: nat where bij: "bij_betw f {i. i by (auto simp: bij_betw_def) let ?f = "the_inv_into {i. i have"inj_on ?f A ∧ ?f ` A = {i. i by (fold bij_betw_def) (rule bij_betw_the_inv_into[OF bij]) thenshow ?thesis by blast qed
lemma finite_Collect_less_nat [iff]: "finite {n::nat. n < k}" by (fastforce simp: finite_conv_nat_seg_image)
lemma finite_Collect_le_nat [iff]: "finite {n::nat. n ≤ k}" by (simp add: le_eq_less_or_eq Collect_disj_eq)
subsection‹Finiteness and common set operations›
lemma rev_finite_subset: "finite B ==> A ⊆ B ==> finite A" proof (induct arbitrary: A rule: finite_induct) case empty thenshow ?caseby simp next case (insert x F A) have A: "A ⊆ insert x F"and r: "A - {x} ⊆ F ==> finite (A - {x})" by fact+ show"finite A" proof cases assume x: "x ∈ A" with A have"A - {x} ⊆ F"by (simp add: subset_insert_iff) with r have"finite (A - {x})" . thenhave"finite (insert x (A - {x}))" .. alsohave"insert x (A - {x}) = A" using x by (rule insert_Diff) finallyshow ?thesis . next show ?thesis when "A ⊆ F" using that by fact assume"x ∉ A" with A show"A ⊆ F" by (simp add: subset_insert_iff) qed qed
lemma finite_subset: "A ⊆ B ==> finite B ==> finite A" by (rule rev_finite_subset)
simproc_setup finite ("finite A") = ‹ let val finite_subset = @{thm finite_subset} val Eq_TrueI = @{thm Eq_TrueI} fun is_subset A th = case Thm.prop_of th of (_ $ 🍋‹less_eq 🍋‹set _›for A' B›) => if A aconv A' then SOME(B,th) else NONE | _ => NONE; fun is_finite th = case Thm.prop_of th of (_ $ 🍋‹finite _ for A›) => SOME(A,th) | _ => NONE; fun comb (A,sub_th) (A',fin_th) ths = if A aconv A' then (sub_th,fin_th) :: ths else ths fun proc ctxt ct = (let val _ $ A = Thm.term_of ct val prems = Simplifier.prems_of ctxt val fins = map_filter is_finite prems val subsets = map_filter (is_subset A) prems in case fold_product comb subsets fins [] of (sub_th,fin_th) :: _ => SOME((fin_th RS (sub_th RS finite_subset)) RS Eq_TrueI) | _ => NONE end) in K proc end ›
(* Needs to be used with care *) declare [[simproc del: finite]]
lemma finite_UnI: assumes"finite F"and"finite G" shows"finite (F ∪ G)" using assms by induct simp_all
lemma finite_insert [simp]: "finite (insert a A) ⟷ finite A" proof - have"finite {a} ∧ finite A ⟷ finite A"by simp thenhave"finite ({a} ∪ A) ⟷ finite A"by (simp only: finite_Un) thenshow ?thesis by simp qed
lemma finite_Int [simp, intro]: "finite F ∨ finite G ==> finite (F ∩ G)" by (blast intro: finite_subset)
lemma finite_Collect_conjI [simp, intro]: "finite {x. P x} ∨ finite {x. Q x} ==> finite {x. P x ∧ Q x}" by (simp add: Collect_conj_eq)
lemma finite_Collect_disjI [simp]: "finite {x. P x ∨ Q x} ⟷ finite {x. P x} ∧ finite {x. Q x}" by (simp add: Collect_disj_eq)
lemma finite_Diff [simp, intro]: "finite A ==> finite (A - B)" by (rule finite_subset, rule Diff_subset)
lemma finite_Diff2 [simp]: assumes"finite B" shows"finite (A - B) ⟷ finite A" proof - have"finite A ⟷ finite ((A - B) ∪ (A ∩ B))" by (simp add: Un_Diff_Int) alsohave"…⟷ finite (A - B)" using‹finite B›by simp finallyshow ?thesis .. qed
lemma finite_Diff_insert [iff]: "finite (A - insert a B) ⟷ finite (A - B)" proof - have"finite (A - B) ⟷ finite (A - B - {a})"by simp moreoverhave"A - insert a B = A - B - {a}"by auto ultimatelyshow ?thesis by simp qed
lemma finite_compl [simp]: "finite (A :: 'a set) ==> finite (- A) ⟷ finite (UNIV :: 'a set)" by (simp add: Compl_eq_Diff_UNIV)
lemma finite_Collect_not [simp]: "finite {x :: 'a. P x} ==> finite {x. ¬ P x} ⟷ finite (UNIV :: 'a set)" by (simp add: Collect_neg_eq)
lemma finite_Union [simp, intro]: "finite A ==> (∧M. M ∈ A ==> finite M) ==> finite (∪A)" by (induct rule: finite_induct) simp_all
lemma finite_UN_I [intro]: "finite A ==> (∧a. a ∈ A ==> finite (B a)) ==> finite (∪a∈A. B a)" by (induct rule: finite_induct) simp_all
lemma finite_UN [simp]: "finite A ==> finite (∪(B ` A)) ⟷ (∀x∈A. finite (B x))" by (blast intro: finite_subset)
lemma finite_Inter [intro]: "∃A∈M. finite A ==> finite (∩M)" by (blast intro: Inter_lower finite_subset)
lemma finite_INT [intro]: "∃x∈I. finite (A x) ==> finite (∩x∈I. A x)" by (blast intro: INT_lower finite_subset)
lemma finite_imageI [simp, intro]: "finite F ==> finite (h ` F)" by (induct rule: finite_induct) simp_all
lemma finite_image_set [simp]: "finite {x. P x} ==> finite {f x |x. P x}" by (simp add: image_Collect [symmetric])
lemma finite_image_set2: "finite {x. P x} ==> finite {y. Q y} ==> finite {f x y |x y. P x ∧ Q y}" by (rule finite_subset [where B = "∪x ∈ {x. P x}. ∪y ∈ {y. Q y}. {f x y}"]) auto
lemma finite_imageD: assumes"finite (f ` A)"and"inj_on f A" shows"finite A" using assms proof (induct "f ` A" arbitrary: A) case empty thenshow ?caseby simp next case (insert x B) thenhave B_A: "insert x B = f ` A" by simp thenobtain y where"x = f y"and"y ∈ A" by blast from B_A ‹x ∉ B›have"B = f ` A - {x}" by blast with B_A ‹x ∉ B›‹x = f y›‹inj_on f A›‹y ∈ A›have"B = f ` (A - {y})" by (simp add: inj_on_image_set_diff) moreoverfrom‹inj_on f A›have"inj_on f (A - {y})" by (rule inj_on_diff) ultimatelyhave"finite (A - {y})" by (rule insert.hyps) thenshow"finite A" by simp qed
lemma finite_image_iff: "inj_on f A ==> finite (f ` A) ⟷ finite A" using finite_imageD by blast
lemma finite_surj: "finite A ==> B ⊆ f ` A ==> finite B" by (erule finite_subset) (rule finite_imageI)
lemma finite_range_imageI: "finite (range g) ==> finite (range (λx. f (g x)))" by (drule finite_imageI) (simp add: range_composition)
lemma finite_subset_image: assumes"finite B" shows"B ⊆ f ` A ==>∃C⊆A. finite C ∧ B = f ` C" using assms proof induct case empty thenshow ?caseby simp next case insert thenshow ?case by (clarsimp simp del: image_insert simp add: image_insert [symmetric]) blast qed
lemma all_subset_image: "(∀B. B ⊆ f ` A ⟶ P B) ⟷ (∀B. B ⊆ A ⟶ P(f ` B))" by (safe elim!: subset_imageE) (use image_mono in‹blast+›) (* slow *)
lemma all_finite_subset_image: "(∀B. finite B ∧ B ⊆ f ` A ⟶ P B) ⟷ (∀B. finite B ∧ B ⊆ A ⟶ P (f ` B))" proof safe fix B :: "'a set" assume B: "finite B""B ⊆ f ` A"and P: "∀B. finite B ∧ B ⊆ A ⟶ P (f ` B)" show"P B" using finite_subset_image [OF B] P by blast qed blast
lemma ex_finite_subset_image: "(∃B. finite B ∧ B ⊆ f ` A ∧ P B) ⟷ (∃B. finite B ∧ B ⊆ A ∧ P (f ` B))" proof safe fix B :: "'a set" assume B: "finite B""B ⊆ f ` A"and"P B" show"∃B. finite B ∧ B ⊆ A ∧ P (f ` B)" using finite_subset_image [OF B] ‹P B›by blast qed blast
lemma finite_vimage_IntI: "finite F ==> inj_on h A ==> finite (h -` F ∩ A)" proof (induct rule: finite_induct) case (insert x F) thenshow ?case by (simp add: vimage_insert [of h x F] finite_subset [OF inj_on_vimage_singleton] Int_Un_distrib2) qed simp
lemma finite_finite_vimage_IntI: assumes"finite F" and"∧y. y ∈ F ==> finite ((h -` {y}) ∩ A)" shows"finite (h -` F ∩ A)" proof - have *: "h -` F ∩ A = (∪ y∈F. (h -` {y}) ∩ A)" by blast show ?thesis by (simp only: * assms finite_UN_I) qed
lemma finite_vimageI: "finite F ==> inj h ==> finite (h -` F)" using finite_vimage_IntI[of F h UNIV] by auto
lemma finite_vimageD': "finite (f -` A) ==> A ⊆ range f ==> finite A" by (auto simp add: subset_image_iff intro: finite_subset[rotated])
lemma finite_vimageD: "finite (h -` F) ==> surj h ==> finite F" by (auto dest: finite_vimageD')
lemma finite_vimage_iff: "bij h ==> finite (h -` F) ⟷ finite F" unfolding bij_def by (auto elim: finite_vimageD finite_vimageI)
lemma finite_inverse_image_gen: assumes"finite A""inj_on f D" shows"finite {j∈D. f j ∈ A}" using finite_vimage_IntI [OF assms] by (simp add: Collect_conj_eq inf_commute vimage_def)
lemma finite_inverse_image: assumes"finite A""inj f" shows"finite {j. f j ∈ A}" using finite_inverse_image_gen [OF assms] by simp
lemma finite_Collect_bex [simp]: assumes"finite A" shows"finite {x. ∃y∈A. Q x y} ⟷ (∀y∈A. finite {x. Q x y})" proof - have"{x. ∃y∈A. Q x y} = (∪y∈A. {x. Q x y})"by auto with assms show ?thesis by simp qed
lemma finite_Collect_bounded_ex [simp]: assumes"finite {y. P y}" shows"finite {x. ∃y. P y ∧ Q x y} ⟷ (∀y. P y ⟶ finite {x. Q x y})" proof - have"{x. ∃y. P y ∧ Q x y} = (∪y∈{y. P y}. {x. Q x y})" by auto with assms show ?thesis by simp qed
lemma finite_Plus: "finite A ==> finite B ==> finite (A <+> B)" by (simp add: Plus_def)
lemma finite_PlusD: fixes A :: "'a set"and B :: "'b set" assumes fin: "finite (A <+> B)" shows"finite A""finite B" proof - have"Inl ` A ⊆ A <+> B" by auto thenhave"finite (Inl ` A :: ('a + 'b) set)" using fin by (rule finite_subset) thenshow"finite A" by (rule finite_imageD) (auto intro: inj_onI) next have"Inr ` B ⊆ A <+> B" by auto thenhave"finite (Inr ` B :: ('a + 'b) set)" using fin by (rule finite_subset) thenshow"finite B" by (rule finite_imageD) (auto intro: inj_onI) qed
lemma finite_Plus_iff [simp]: "finite (A <+> B) ⟷ finite A ∧ finite B" by (auto intro: finite_PlusD finite_Plus)
lemma finite_SigmaI [simp, intro]: "finite A ==> (∧a. a∈A ==> finite (B a)) ==> finite (SIGMA a:A. B a)" unfolding Sigma_def by blast
lemma finite_SigmaI2: assumes"finite {x∈A. B x ≠ {}}" and"∧a. a ∈ A ==> finite (B a)" shows"finite (Sigma A B)" proof - from assms have"finite (Sigma {x∈A. B x ≠ {}} B)" by auto alsohave"Sigma {x:A. B x ≠ {}} B = Sigma A B" by auto finallyshow ?thesis . qed
lemma finite_cartesian_product: "finite A ==> finite B ==> finite (A × B)" by (rule finite_SigmaI)
lemma finite_cartesian_productD1: assumes"finite (A × B)"and"B ≠ {}" shows"finite A" proof - from assms obtain n f where"A × B = f ` {i::nat. i < n}" by (auto simp add: finite_conv_nat_seg_image) thenhave"fst ` (A × B) = fst ` f ` {i::nat. i < n}" by simp with‹B ≠ {}›have"A = (fst ∘ f) ` {i::nat. i < n}" by (simp add: image_comp) thenhave"∃n f. A = f ` {i::nat. i < n}" by blast thenshow ?thesis by (auto simp add: finite_conv_nat_seg_image) qed
lemma finite_cartesian_productD2: assumes"finite (A × B)"and"A ≠ {}" shows"finite B" proof - from assms obtain n f where"A × B = f ` {i::nat. i < n}" by (auto simp add: finite_conv_nat_seg_image) thenhave"snd ` (A × B) = snd ` f ` {i::nat. i < n}" by simp with‹A ≠ {}›have"B = (snd ∘ f) ` {i::nat. i < n}" by (simp add: image_comp) thenhave"∃n f. B = f ` {i::nat. i < n}" by blast thenshow ?thesis by (auto simp add: finite_conv_nat_seg_image) qed
lemma finite_cartesian_product_iff: "finite (A × B) ⟷ (A = {} ∨ B = {} ∨ (finite A ∧ finite B))" by (auto dest: finite_cartesian_productD1 finite_cartesian_productD2 finite_cartesian_product)
lemma finite_prod: "finite (UNIV :: ('a × 'b) set) ⟷ finite (UNIV :: 'a set) ∧ finite (UNIV :: 'b set)" using finite_cartesian_product_iff[of UNIV UNIV] by simp
lemma finite_Pow_iff [iff]: "finite (Pow A) ⟷ finite A" proof assume"finite (Pow A)" thenhave"finite ((λx. {x}) ` A)" by (blast intro: finite_subset) (* somewhat slow *) thenshow"finite A" by (rule finite_imageD [unfolded inj_on_def]) simp next assume"finite A" thenshow"finite (Pow A)" by induct (simp_all add: Pow_insert) qed
corollary finite_Collect_subsets [simp, intro]: "finite A ==> finite {B. B ⊆ A}" by (simp add: Pow_def [symmetric])
lemma finite_set: "finite (UNIV :: 'a set set) ⟷ finite (UNIV :: 'a set)" by (simp only: finite_Pow_iff Pow_UNIV[symmetric])
lemma finite_bind: assumes"finite S" assumes"∀x ∈ S. finite (f x)" shows"finite (Set.bind S f)" using assms by (simp add: bind_UNION)
lemma finite_filter [simp]: "finite S ==> finite (Set.filter P S)" by (simp add:)
lemma finite_set_of_finite_funs: assumes"finite A""finite B" shows"finite {f. ∀x. (x ∈ A ⟶ f x ∈ B) ∧ (x ∉ A ⟶ f x = d)}" (is"finite ?S") proof - let ?F = "λf. {(a,b). a ∈ A ∧ b = f a}" have"?F ` ?S ⊆ Pow(A × B)" by auto from finite_subset[OF this] assms have 1: "finite (?F ` ?S)" by simp have 2: "inj_on ?F ?S" by (fastforce simp add: inj_on_def set_eq_iff fun_eq_iff) (* somewhat slow *) show ?thesis by (rule finite_imageD [OF 1 2]) qed
lemma not_finite_existsD: assumes"¬ finite {a. P a}" shows"∃a. P a" proof (rule classical) assume"¬ ?thesis" with assms show ?thesis by auto qed
lemma finite_Domain: "finite r ==> finite (Domain r)" by (induct set: finite) auto
lemma finite_Range: "finite r ==> finite (Range r)" by (induct set: finite) auto
lemma finite_Field: "finite r ==> finite (Field r)" by (simp add: Field_def finite_Domain finite_Range)
lemma finite_Image[simp]: "finite R ==> finite (R `` A)" by(rule finite_subset[OF _ finite_Range]) auto
subsection‹Further induction rules on finite sets›
lemma finite_ne_induct [case_names singleton insert, consumes 2]: assumes"finite F"and"F ≠ {}" assumes"∧x. P {x}" and"∧x F. finite F ==> F ≠ {} ==> x ∉ F ==> P F ==> P (insert x F)" shows"P F" using assms proof induct case empty thenshow ?caseby simp next case (insert x F) thenshow ?caseby cases auto qed
lemma finite_subset_induct [consumes 2, case_names empty insert]: assumes"finite F"and"F ⊆ A" and empty: "P {}" and insert: "∧a F. finite F ==> a ∈ A ==> a ∉ F ==> P F ==> P (insert a F)" shows"P F" using‹finite F›‹F ⊆ A› proof induct show"P {}"by fact next fix x F assume"finite F"and"x ∉ F"and P: "F ⊆ A ==> P F"and i: "insert x F ⊆ A" show"P (insert x F)" proof (rule insert) from i show"x ∈ A"by blast from i have"F ⊆ A"by blast with P show"P F" . show"finite F"by fact show"x ∉ F"by fact qed qed
lemma finite_empty_induct: assumes"finite A" and"P A" and remove: "∧a A. finite A ==> a ∈ A ==> P A ==> P (A - {a})" shows"P {}" proof - have"P (A - B)"if"B ⊆ A"for B :: "'a set" proof - from‹finite A› that have"finite B" by (rule rev_finite_subset) from this ‹B ⊆ A›show"P (A - B)" proof induct case empty from‹P A›show ?caseby simp next case (insert b B) have"P (A - B - {b})" proof (rule remove) from‹finite A›show"finite (A - B)" by induct auto from insert show"b ∈ A - B" by simp from insert show"P (A - B)" by simp qed alsohave"A - B - {b} = A - insert b B" by (rule Diff_insert [symmetric]) finallyshow ?case . qed qed thenhave"P (A - A)"by blast thenshow ?thesis by simp qed
lemma finite_update_induct [consumes 1, case_names const update]: assumes finite: "finite {a. f a ≠ c}" and const: "P (λa. c)" and update: "∧a b f. finite {a. f a ≠ c} ==> f a = c ==> b ≠ c ==> P f ==> P (f(a := b))" shows"P f" using finite proof (induct "{a. f a ≠ c}" arbitrary: f) case empty with const show ?caseby simp next case (insert a A) thenhave"A = {a'. (f(a := c)) a' ≠ c}"and"f a ≠ c" by auto with‹finite A›have"finite {a'. (f(a := c)) a' ≠ c}" by simp have"(f(a := c)) a = c" by simp from insert ‹A = {a'. (f(a := c)) a' ≠ c}›have"P (f(a := c))" by simp with‹finite {a'. (f(a := c)) a' ≠ c}›‹(f(a := c)) a = c›‹f a ≠ c› have"P ((f(a := c))(a := f a))" by (rule update) thenshow ?caseby simp qed
lemma finite_subset_induct' [consumes 2, case_names empty insert]: assumes"finite F"and"F ⊆ A" and empty: "P {}" and insert: "∧a F. [finite F; a ∈ A; F ⊆ A; a ∉ F; P F ]==> P (insert a F)" shows"P F" using assms(1,2) proof induct show"P {}"by fact next fix x F assume"finite F"and"x ∉ F"and
P: "F ⊆ A ==> P F"and i: "insert x F ⊆ A" show"P (insert x F)" proof (rule insert) from i show"x ∈ A"by blast from i have"F ⊆ A"by blast with P show"P F" . show"finite F"by fact show"x ∉ F"by fact show"F ⊆ A"by fact qed qed
subsection‹Class ‹finite›\ class finite = assumes finite_UNIV: "finite (UNIV :: 'a set)" begin
lemma finite [simp]: "finite (A :: 'a set)" by (rule subset_UNIV finite_UNIV finite_subset)+
lemma finite_code [code]: "finite (A :: 'a set) ⟷ True" by simp
end
instance prod :: (finite, finite) finite by standard (simp only: UNIV_Times_UNIV [symmetric] finite_cartesian_product finite)
lemma inj_graph: "inj (λf. {(x, y). y = f x})" by (rule inj_onI) (auto simp add: set_eq_iff fun_eq_iff)
instance"fun" :: (finite, finite) finite proof show"finite (UNIV :: ('a ==> 'b) set)" proof (rule finite_imageD) let ?graph = "λf::'a ==> 'b. {(x, y). y = f x}" have"range ?graph ⊆ Pow UNIV" by simp moreoverhave"finite (Pow (UNIV :: ('a * 'b) set))" by (simp only: finite_Pow_iff finite) ultimatelyshow"finite (range ?graph)" by (rule finite_subset) show"inj ?graph" by (rule inj_graph) qed qed
instance bool :: finite by standard (simp add: UNIV_bool)
instance set :: (finite) finite by standard (simp only: Pow_UNIV [symmetric] finite_Pow_iff finite)
instance unit :: finite by standard (simp add: UNIV_unit)
instance sum :: (finite, finite) finite by standard (simp only: UNIV_Plus_UNIV [symmetric] finite_Plus finite)
subsection‹A basic fold functional for finite sets›
text‹ The intended behaviour is ‹fold f z {x🪙1, …, x🪙n} = f x🪙1 (… (f x🪙n z)…)› if‹f›is ``left-commutative''.
The commutativity requirement is relativised to the carrier set ‹S›: ›
locale comp_fun_commute_on = fixes S :: "'a set" fixes f :: "'a ==> 'b ==> 'b" assumes comp_fun_commute_on: "x ∈ S ==> y ∈ S ==> f y ∘ f x = f x ∘ f y" begin
lemma fun_left_comm: "x ∈ S ==> y ∈ S ==> f y (f x z) = f x (f y z)" using comp_fun_commute_on by (simp add: fun_eq_iff)
lemma commute_left_comp: "x ∈ S ==> y ∈ S ==> f y ∘ (f x ∘ g) = f x ∘ (f y ∘ g)" by (simp add: o_assoc comp_fun_commute_on)
end
inductive fold_graph :: "('a ==> 'b ==> 'b) ==> 'b ==> 'a set ==> 'b ==> bool" for f :: "'a ==> 'b ==> 'b"and z :: 'b where
emptyI [intro]: "fold_graph f z {} z"
| insertI [intro]: "x ∉ A ==> fold_graph f z A y ==> fold_graph f z (insert x A) (f x y)"
inductive_cases empty_fold_graphE [elim!]: "fold_graph f z {} x"
lemma fold_graph_closed_lemma: "fold_graph f z A x ∧ x ∈ B" if"fold_graph g z A x" "∧a b. a ∈ A ==> b ∈ B ==> f a b = g a b" "∧a b. a ∈ A ==> b ∈ B ==> g a b ∈ B" "z ∈ B" using that(1-3) proof (induction rule: fold_graph.induct) case (insertI x A y) have"fold_graph f z A y""y ∈ B" unfolding atomize_conj by (rule insertI.IH) (auto intro: insertI.prems) thenhave"g x y ∈ B"and f_eq: "f x y = g x y" by (auto simp: insertI.prems) moreoverhave"fold_graph f z (insert x A) (f x y)" by (rule fold_graph.insertI; fact) ultimately show ?case by (simp add: f_eq) qed (auto intro!: that)
lemma fold_graph_closed_eq: "fold_graph f z A = fold_graph g z A" if"∧a b. a ∈ A ==> b ∈ B ==> f a b = g a b" "∧a b. a ∈ A ==> b ∈ B ==> g a b ∈ B" "z ∈ B" using fold_graph_closed_lemma[of f z A _ B g] fold_graph_closed_lemma[of g z A _ B f] that by auto
definition fold :: "('a ==> 'b ==> 'b) ==> 'b ==> 'a set ==> 'b" where"fold f z A = (if finite A then (THE y. fold_graph f z A y) else z)"
lemma fold_closed_eq: "fold f z A = fold g z A" if"∧a b. a ∈ A ==> b ∈ B ==> f a b = g a b" "∧a b. a ∈ A ==> b ∈ B ==> g a b ∈ B" "z ∈ B" unfolding Finite_Set.fold_def by (subst fold_graph_closed_eq[where B=B and g=g]) (auto simp: that)
text‹ A tempting alternative for the definition is 🍋‹if finite A then THE y. fold_graph f z A y else e›.
It allows the removal of finiteness assumptions from the theorems ‹fold_comm›, ‹fold_reindex›and‹fold_distrib›.
The proofs become ugly. It is not worth the effort. (???) ›
lemma finite_imp_fold_graph: "finite A ==>∃x. fold_graph f z A x" by (induct rule: finite_induct) auto
subsubsection ‹From 🍋‹fold_graph› to 🍋‹fold›\<close>
context comp_fun_commute_on begin
lemma fold_graph_finite: assumes"fold_graph f z A y" shows"finite A" using assms by induct simp_all
lemma fold_graph_insertE_aux: assumes"A ⊆ S" assumes"fold_graph f z A y""a ∈ A" shows"∃y'. y = f a y' ∧ fold_graph f z (A - {a}) y'" using assms(2-,1) proof (induct set: fold_graph) case emptyI thenshow ?caseby simp next case (insertI x A y) show ?case proof (cases "x = a") case True with insertI show ?thesis by auto next case False thenobtain y' where y: "y = f a y'"and y': "fold_graph f z (A - {a}) y'" using insertI by auto from insertI have"x ∈ S""a ∈ S"by auto thenhave"f x y = f a (f x y')" unfolding y by (intro fun_left_comm; simp) moreoverhave"fold_graph f z (insert x A - {a}) (f x y')" using y' and‹x ≠ a›and‹x ∉ A› by (simp add: insert_Diff_if fold_graph.insertI) ultimatelyshow ?thesis by fast qed qed
lemma fold_graph_insertE: assumes"insert x A ⊆ S" assumes"fold_graph f z (insert x A) v"and"x ∉ A" obtains y where"v = f x y"and"fold_graph f z A y" using assms by (auto dest: fold_graph_insertE_aux[OF ‹insert x A ⊆ S› _ insertI1])
lemma fold_graph_determ: assumes"A ⊆ S" assumes"fold_graph f z A x""fold_graph f z A y" shows"y = x" using assms(2-,1) proof (induct arbitrary: y set: fold_graph) case emptyI thenshow ?caseby fast next case (insertI x A y v) from‹insert x A ⊆ S›and‹fold_graph f z (insert x A) v›and‹x ∉ A› obtain y' where"v = f x y'"and"fold_graph f z A y'" by (rule fold_graph_insertE) from‹fold_graph f z A y'› insertI have"y' = y" by simp with‹v = f x y'›show"v = f x y" by simp qed
lemma fold_equality: "A ⊆ S ==> fold_graph f z A y ==> fold f z A = y" by (cases "finite A") (auto simp add: fold_def intro: fold_graph_determ dest: fold_graph_finite)
lemma fold_graph_fold: assumes"A ⊆ S" assumes"finite A" shows"fold_graph f z A (fold f z A)" proof - from‹finite A›have"∃x. fold_graph f z A x" by (rule finite_imp_fold_graph) moreovernote fold_graph_determ[OF ‹A ⊆ S›] ultimatelyhave"∃!x. fold_graph f z A x" by (rule ex_ex1I) thenhave"fold_graph f z A (The (fold_graph f z A))" by (rule theI') with assms show ?thesis by (simp add: fold_def) qed
text‹The base case for ‹fold›:\<close>
lemma (in -) fold_infinite [simp]: "¬ finite A ==> fold f z A = z" by (auto simp: fold_def)
lemma (in -) fold_empty [simp]: "fold f z {} = z" by (auto simp: fold_def)
text‹The various recursion equations for 🍋‹fold›:\<close>
lemma fold_insert [simp]: assumes"insert x A ⊆ S" assumes"finite A"and"x ∉ A" shows"fold f z (insert x A) = f x (fold f z A)" proof (rule fold_equality[OF ‹insert x A ⊆ S›]) fix z from‹insert x A ⊆ S›‹finite A›have"fold_graph f z A (fold f z A)" by (blast intro: fold_graph_fold) with‹x ∉ A›have"fold_graph f z (insert x A) (f x (fold f z A))" by (rule fold_graph.insertI) thenshow"fold_graph f z (insert x A) (f x (fold f z A))" by simp qed
declare (in -) empty_fold_graphE [rule del] fold_graph.intros [rule del] 🍋‹No more proofs involve these.›
lemma fold_fun_left_comm: assumes"insert x A ⊆ S""finite A" shows"f x (fold f z A) = fold f (f x z) A" using assms(2,1) proof (induct rule: finite_induct) case empty thenshow ?caseby simp next case (insert y F) thenhave"fold f (f x z) (insert y F) = f y (fold f (f x z) F)" by simp alsohave"… = f x (f y (fold f z F))" using insert by (simp add: fun_left_comm[where ?y=x]) alsohave"… = f x (fold f z (insert y F))" proof - from insert have"insert y F ⊆ S"by simp from fold_insert[OF this] insert show ?thesis by simp qed finallyshow ?case .. qed
lemma fold_insert2: "insert x A ⊆ S ==> finite A ==> x ∉ A ==> fold f z (insert x A) = fold f (f x z) A" by (simp add: fold_fun_left_comm)
lemma fold_rec: assumes"A ⊆ S" assumes"finite A"and"x ∈ A" shows"fold f z A = f x (fold f z (A - {x}))" proof - have A: "A = insert x (A - {x})" using‹x ∈ A›by blast thenhave"fold f z A = fold f z (insert x (A - {x}))" by simp alsohave"… = f x (fold f z (A - {x}))" by (rule fold_insert) (use assms in‹auto›) finallyshow ?thesis . qed
lemma fold_insert_remove: assumes"insert x A ⊆ S" assumes"finite A" shows"fold f z (insert x A) = f x (fold f z (A - {x}))" proof - from‹finite A›have"finite (insert x A)" by auto moreoverhave"x ∈ insert x A" by auto ultimatelyhave"fold f z (insert x A) = f x (fold f z (insert x A - {x}))" using‹insert x A ⊆ S›by (blast intro: fold_rec) thenshow ?thesis by simp qed
lemma fold_set_union_disj: assumes"A ⊆ S""B ⊆ S" assumes"finite A""finite B""A ∩ B = {}" shows"Finite_Set.fold f z (A ∪ B) = Finite_Set.fold f (Finite_Set.fold f z A) B" using‹finite B› assms(1,2,3,5) proof induct case (insert x F) have"fold f z (A ∪ insert x F) = f x (fold f (fold f z A) F)" using insert by auto alsohave"… = fold f (fold f z A) (insert x F)" using insert by (blast intro: fold_insert[symmetric]) finallyshow ?case . qed simp
end
text‹Other properties of 🍋‹fold›:›
lemma finite_set_fold_single [simp]: "Finite_Set.fold f z {x} = f x z" proof - have"fold_graph f z {x} (f x z)" by (auto intro: fold_graph.intros) moreover
{ fix X y have"fold_graph f z X y ==> (X = {} ⟶ y = z) ∧ (X = {x} ⟶ y = f x z)" by (induct rule: fold_graph.induct) auto
} ultimatelyhave"(THE y. fold_graph f z {x} y) = f x z" by blast thus ?thesis by (simp add: Finite_Set.fold_def) qed
lemma fold_graph_image: assumes"inj_on g A" shows"fold_graph f z (g ` A) = fold_graph (f ∘ g) z A" proof fix w show"fold_graph f z (g ` A) w = fold_graph (f o g) z A w" proof assume"fold_graph f z (g ` A) w" thenshow"fold_graph (f ∘ g) z A w" using assms proof (induct "g ` A" w arbitrary: A) case emptyI thenshow ?caseby (auto intro: fold_graph.emptyI) next case (insertI x A r B) from‹inj_on g B›‹x ∉ A›‹insert x A = image g B›obtain x' A' where"x' ∉ A'"and [simp]: "B = insert x' A'""x = g x'""A = g ` A'" by (rule inj_img_insertE) from insertI.prems have"fold_graph (f ∘ g) z A' r" by (auto intro: insertI.hyps) with‹x' ∉ A'›have"fold_graph (f ∘ g) z (insert x' A') ((f ∘ g) x' r)" by (rule fold_graph.insertI) thenshow ?case by simp qed next assume"fold_graph (f ∘ g) z A w" thenshow"fold_graph f z (g ` A) w" using assms proof induct case emptyI thenshow ?case by (auto intro: fold_graph.emptyI) next case (insertI x A r) from‹x ∉ A› insertI.prems have"g x ∉ g ` A" by auto moreoverfrom insertI have"fold_graph f z (g ` A) r" by simp ultimatelyhave"fold_graph f z (insert (g x) (g ` A)) (f (g x) r)" by (rule fold_graph.insertI) thenshow ?case by simp qed qed qed
lemma fold_image: assumes"inj_on g A" shows"fold f z (g ` A) = fold (f ∘ g) z A" proof (cases "finite A") case False with assms show ?thesis by (auto dest: finite_imageD simp add: fold_def) next case True thenshow ?thesis by (auto simp add: fold_def fold_graph_image[OF assms]) qed
lemma fold_cong: assumes"comp_fun_commute_on S f""comp_fun_commute_on S g" and"A ⊆ S""finite A" and cong: "∧x. x ∈ A ==> f x = g x" and"s = t"and"A = B" shows"fold f s A = fold g t B" proof - have"fold f s A = fold g s A" using‹finite A›‹A ⊆ S› cong proof (induct A) case empty thenshow ?caseby simp next case insert interpret f: comp_fun_commute_on S f by (fact ‹comp_fun_commute_on S f›) interpret g: comp_fun_commute_on S g by (fact ‹comp_fun_commute_on S g›) from insert show ?caseby simp qed with assms show ?thesis by simp qed
text‹A simplified version for idempotent functions:›
locale comp_fun_idem_on = comp_fun_commute_on + assumes comp_fun_idem_on: "x ∈ S ==> f x ∘ f x = f x" begin
lemma fun_left_idem: "x ∈ S ==> f x (f x z) = f x z" using comp_fun_idem_on by (simp add: fun_eq_iff)
lemma fold_insert_idem: assumes"insert x A ⊆ S" assumes fin: "finite A" shows"fold f z (insert x A) = f x (fold f z A)" proof cases assume"x ∈ A" thenobtain B where"A = insert x B"and"x ∉ B" by (rule set_insert) thenshow ?thesis using assms by (simp add: comp_fun_idem_on fun_left_idem) next assume"x ∉ A" thenshow ?thesis using assms by auto qed
lemma fold_insert_idem2: "insert x A ⊆ S ==> finite A ==> fold f z (insert x A) = fold f (f x z) A" by (simp add: fold_fun_left_comm)
end
subsubsection ‹Liftings to ‹comp_fun_commute_on›etc.›
lemma (in comp_fun_commute_on) comp_comp_fun_commute_on: "range g ⊆ S ==> comp_fun_commute_on R (f ∘ g)" by standard (force intro: comp_fun_commute_on)
lemma (in comp_fun_idem_on) comp_comp_fun_idem_on: assumes"range g ⊆ S" shows"comp_fun_idem_on R (f ∘ g)" proof interpret f_g: comp_fun_commute_on R "f o g" by (fact comp_comp_fun_commute_on[OF ‹range g ⊆ S›]) show"x ∈ R ==> y ∈ R ==> (f ∘ g) y ∘ (f ∘ g) x = (f ∘ g) x ∘ (f ∘ g) y"for x y by (fact f_g.comp_fun_commute_on) qed (use‹range g ⊆ S›in‹force intro: comp_fun_idem_on›)
lemma (in comp_fun_commute_on) comp_fun_commute_on_funpow: "comp_fun_commute_on S (λx. f x ^^ g x)" proof fix x y assume"x ∈ S""y ∈ S" show"f y ^^ g y ∘ f x ^^ g x = f x ^^ g x ∘ f y ^^ g y" proof (cases "x = y") case True thenshow ?thesis by simp next case False show ?thesis proof (induct "g x" arbitrary: g) case 0 thenshow ?caseby simp next case (Suc n g) have hyp1: "f y ^^ g y ∘ f x = f x ∘ f y ^^ g y" proof (induct "g y" arbitrary: g) case 0 thenshow ?caseby simp next case (Suc n g)
define h where"h z = g z - 1"for z with Suc have"n = h y" by simp with Suc have hyp: "f y ^^ h y ∘ f x = f x ∘ f y ^^ h y" by auto from Suc h_def have"g y = Suc (h y)" by simp with‹x ∈ S›‹y ∈ S›show ?case by (simp add: comp_assoc hyp) (simp add: o_assoc comp_fun_commute_on) qed
define h where"h z = (if z = x then g x - 1 else g z)"for z with Suc have"n = h x" by simp with Suc have"f y ^^ h y ∘ f x ^^ h x = f x ^^ h x ∘ f y ^^ h y" by auto with False h_def have hyp2: "f y ^^ g y ∘ f x ^^ h x = f x ^^ h x ∘ f y ^^ g y" by simp from Suc h_def have"g x = Suc (h x)" by simp thenshow ?case by (simp del: funpow.simps add: funpow_Suc_right o_assoc hyp2) (simp add: comp_assoc hyp1) qed qed qed
subsubsection ‹🍋‹UNIV›as carrier set›
locale comp_fun_commute = fixes f :: "'a ==> 'b ==> 'b" assumes comp_fun_commute: "f y ∘ f x = f x ∘ f y" begin
lemma (in -) comp_fun_commute_def': "comp_fun_commute f = comp_fun_commute_on UNIV f" unfolding comp_fun_commute_def comp_fun_commute_on_def by blast
text‹ We abuse the ‹rewrites›functionality of locales to remove trivial assumptions that result from instantiating the carrier set to 🍋‹UNIV›. ›
sublocale comp_fun_commute_on UNIV f
rewrites "∧X. (X ⊆ UNIV) ≡ True" and"∧x. x ∈ UNIV ≡ True" and"∧P. (True ==> P) ≡ Trueprop P" and"∧P Q. (True ==> PROP P ==> PROP Q) ≡ (PROP P ==> True ==> PROP Q)" proof - show"comp_fun_commute_on UNIV f" by standard (simp add: comp_fun_commute) qed simp_all
end
lemma (in comp_fun_commute) comp_comp_fun_commute: "comp_fun_commute (f o g)" unfolding comp_fun_commute_def' by (fact comp_comp_fun_commute_on)
lemma (in comp_fun_commute) comp_fun_commute_funpow: "comp_fun_commute (λx. f x ^^ g x)" unfolding comp_fun_commute_def' by (fact comp_fun_commute_on_funpow)
locale comp_fun_idem = comp_fun_commute + assumes comp_fun_idem: "f x o f x = f x" begin
lemma (in -) comp_fun_idem_def': "comp_fun_idem f = comp_fun_idem_on UNIV f" unfolding comp_fun_idem_on_def comp_fun_idem_def comp_fun_commute_def' unfolding comp_fun_idem_axioms_def comp_fun_idem_on_axioms_def by blast
text‹ Again, we abuse the ‹rewrites›functionality of locales to remove trivial assumptions that result from instantiating the carrier set to 🍋‹UNIV›. ›
sublocale comp_fun_idem_on UNIV f
rewrites "∧X. (X ⊆ UNIV) ≡ True" and"∧x. x ∈ UNIV ≡ True" and"∧P. (True ==> P) ≡ Trueprop P" and"∧P Q. (True ==> PROP P ==> PROP Q) ≡ (PROP P ==> True ==> PROP Q)" proof - show"comp_fun_idem_on UNIV f" by standard (simp_all add: comp_fun_idem comp_fun_commute) qed simp_all
end
lemma (in comp_fun_idem) comp_comp_fun_idem: "comp_fun_idem (f o g)" unfolding comp_fun_idem_def' by (fact comp_comp_fun_idem_on)
subsubsection ‹Expressing set operations via 🍋‹fold›\›
lemma comp_fun_commute_const: "comp_fun_commute (λ_. f)" by standard (rule refl)
lemma comp_fun_idem_insert: "comp_fun_idem insert" by standard auto
lemma comp_fun_idem_remove: "comp_fun_idem Set.remove" by standard auto
lemma (in semilattice_inf) comp_fun_idem_inf: "comp_fun_idem inf" by standard (auto simp add: inf_left_commute)
lemma (in semilattice_sup) comp_fun_idem_sup: "comp_fun_idem sup" by standard (auto simp add: sup_left_commute)
lemma union_fold_insert: assumes"finite A" shows"A ∪ B = fold insert B A" proof - interpret comp_fun_idem insert by (fact comp_fun_idem_insert) from‹finite A›show ?thesis by (induct A arbitrary: B) simp_all qed
lemma minus_fold_remove: assumes"finite A" shows"B - A = fold Set.remove B A" proof - interpret comp_fun_idem Set.remove by (fact comp_fun_idem_remove) from‹finite A›have"fold Set.remove B A = B - A" by (induct A arbitrary: B) auto (* slow *) thenshow ?thesis .. qed
lemma comp_fun_commute_filter_fold: "comp_fun_commute (λx A'. if P x then Set.insert x A' else A')" proof - interpret comp_fun_idem Set.insert by (fact comp_fun_idem_insert) show ?thesis by standard (auto simp: fun_eq_iff) qed
lemma Set_filter_fold: assumes"finite A" shows"Set.filter P A = fold (λx A'. if P x then Set.insert x A' else A') {} A" using assms proof - interpret commute_insert: comp_fun_commute "(λx A'. if P x then Set.insert x A' else A')" by (fact comp_fun_commute_filter_fold) from‹finite A›show ?thesis by induct (auto simp add: set_eq_iff) qed
lemma inter_Set_filter: assumes"finite B" shows"A ∩ B = Set.filter (λx. x ∈ A) B" using assms by (simp add: set_eq_iff ac_simps)
lemma image_fold_insert: assumes"finite A" shows"image f A = fold (λk A. Set.insert (f k) A) {} A" proof - interpret comp_fun_commute "λk A. Set.insert (f k) A" by standard auto show ?thesis using assms by (induct A) auto qed
lemma Ball_fold: assumes"finite A" shows"Ball A P = fold (λk s. s ∧ P k) True A" proof - interpret comp_fun_commute "λk s. s ∧ P k" by standard auto show ?thesis using assms by (induct A) auto qed
lemma Bex_fold: assumes"finite A" shows"Bex A P = fold (λk s. s ∨ P k) False A" proof - interpret comp_fun_commute "λk s. s ∨ P k" by standard auto show ?thesis using assms by (induct A) auto qed
lemma comp_fun_commute_Pow_fold: "comp_fun_commute (λx A. A ∪ Set.insert x ` A)" by (clarsimp simp: fun_eq_iff comp_fun_commute_def) blast
lemma Pow_fold: assumes"finite A" shows"Pow A = fold (λx A. A ∪ Set.insert x ` A) {{}} A" proof - interpret comp_fun_commute "λx A. A ∪ Set.insert x ` A" by (rule comp_fun_commute_Pow_fold) show ?thesis using assms by (induct A) (auto simp: Pow_insert) qed
lemma fold_union_pair: assumes"finite B" shows"(∪y∈B. {(x, y)}) ∪ A = fold (λy. Set.insert (x, y)) A B" proof - interpret comp_fun_commute "λy. Set.insert (x, y)" by standard auto show ?thesis using assms by (induct arbitrary: A) simp_all qed
lemma comp_fun_commute_product_fold: "finite B ==> comp_fun_commute (λx z. fold (λy. Set.insert (x, y)) z B)" by standard (auto simp: fold_union_pair [symmetric])
lemma product_fold: assumes"finite A""finite B" shows"A × B = fold (λx z. fold (λy. Set.insert (x, y)) z B) {} A" proof - interpret commute_product: comp_fun_commute "(λx z. fold (λy. Set.insert (x, y)) z B)" by (fact comp_fun_commute_product_fold[OF ‹finite B›]) from assms show ?thesis unfolding Sigma_def by (induct A) (simp_all add: fold_union_pair) qed
context complete_lattice begin
lemma inf_Inf_fold_inf: assumes"finite A" shows"inf (Inf A) B = fold inf B A" proof - interpret comp_fun_idem inf by (fact comp_fun_idem_inf) from‹finite A› fold_fun_left_comm show ?thesis by (induct A arbitrary: B) (simp_all add: inf_commute fun_eq_iff) qed
lemma sup_Sup_fold_sup: assumes"finite A" shows"sup (Sup A) B = fold sup B A" proof - interpret comp_fun_idem sup by (fact comp_fun_idem_sup) from‹finite A› fold_fun_left_comm show ?thesis by (induct A arbitrary: B) (simp_all add: sup_commute fun_eq_iff) qed
lemma Inf_fold_inf: "finite A ==> Inf A = fold inf top A" using inf_Inf_fold_inf [of A top] by (simp add: inf_absorb2)
lemma Sup_fold_sup: "finite A ==> Sup A = fold sup bot A" using sup_Sup_fold_sup [of A bot] by (simp add: sup_absorb2)
lemma inf_INF_fold_inf: assumes"finite A" shows"inf B (⊓(f ` A)) = fold (inf ∘ f) B A" (is"?inf = ?fold") proof - interpret comp_fun_idem inf by (fact comp_fun_idem_inf) interpret comp_fun_idem "inf ∘ f"by (fact comp_comp_fun_idem) from‹finite A›have"?fold = ?inf" by (induct A arbitrary: B) (simp_all add: inf_left_commute) thenshow ?thesis .. qed
lemma sup_SUP_fold_sup: assumes"finite A" shows"sup B (⊔(f ` A)) = fold (sup ∘ f) B A" (is"?sup = ?fold") proof - interpret comp_fun_idem sup by (fact comp_fun_idem_sup) interpret comp_fun_idem "sup ∘ f"by (fact comp_comp_fun_idem) from‹finite A›have"?fold = ?sup" by (induct A arbitrary: B) (simp_all add: sup_left_commute) thenshow ?thesis .. qed
lemma INF_fold_inf: "finite A ==>⊓(f ` A) = fold (inf ∘ f) top A" using inf_INF_fold_inf [of A top] by simp
lemma SUP_fold_sup: "finite A ==>⊔(f ` A) = fold (sup ∘ f) bot A" using sup_SUP_fold_sup [of A bot] by simp
lemma finite_Inf_in: assumes"finite A""A≠{}"and inf: "∧x y. [x ∈ A; y ∈ A]==> inf x y ∈ A" shows"Inf A ∈ A" proof - have"Inf B ∈ A"if"B ≤ A""B≠{}"for B using finite_subset [OF ‹B ⊆ A›‹finite A›] that by (induction B) (use inf in‹force+›) thenshow ?thesis by (simp add: assms) qed
lemma finite_Sup_in: assumes"finite A""A≠{}"and sup: "∧x y. [x ∈ A; y ∈ A]==> sup x y ∈ A" shows"Sup A ∈ A" proof - have"Sup B ∈ A"if"B ≤ A""B≠{}"for B using finite_subset [OF ‹B ⊆ A›‹finite A›] that by (induction B) (use sup in‹force+›) thenshow ?thesis by (simp add: assms) qed
end
subsubsection ‹Expressing relation operations via 🍋‹fold›\ lemma Id_on_fold: assumes"finite A" shows"Id_on A = Finite_Set.fold (λx. Set.insert (Pair x x)) {} A" proof - interpret comp_fun_commute "λx. Set.insert (Pair x x)" by standard auto from assms show ?thesis unfolding Id_on_def by (induct A) simp_all qed
lemma comp_fun_commute_Image_fold: "comp_fun_commute (λ(x,y) A. if x ∈ S then Set.insert y A else A)" proof - interpret comp_fun_idem Set.insert by (fact comp_fun_idem_insert) show ?thesis by standard (auto simp: fun_eq_iff comp_fun_commute split: prod.split) qed
lemma Image_fold: assumes"finite R" shows"R `` S = Finite_Set.fold (λ(x,y) A. if x ∈ S then Set.insert y A else A) {} R" proof - interpret comp_fun_commute "(λ(x,y) A. if x ∈ S then Set.insert y A else A)" by (rule comp_fun_commute_Image_fold) have *: "∧x F. Set.insert x F `` S = (if fst x ∈ S then Set.insert (snd x) (F `` S) else (F `` S))" by (force intro: rev_ImageI) show ?thesis using assms by (induct R) (auto simp: * ) qed
lemma insert_relcomp_union_fold: assumes"finite S" shows"{x} O S ∪ X = Finite_Set.fold (λ(w,z) A'. if snd x = w then Set.insert (fst x,z) A' else A') X S" proof - interpret comp_fun_commute "λ(w,z) A'. if snd x = w then Set.insert (fst x,z) A' else A'" proof - interpret comp_fun_idem Set.insert by (fact comp_fun_idem_insert) show"comp_fun_commute (λ(w,z) A'. if snd x = w then Set.insert (fst x,z) A' else A')" by standard (auto simp add: fun_eq_iff split: prod.split) qed have *: "{x} O S = {(x', z). x' = fst x ∧ (snd x, z) ∈ S}" by (auto simp: relcomp_unfold intro!: exI) show ?thesis unfolding * using‹finite S›by (induct S) (auto split: prod.split) qed
lemma insert_relcomp_fold: assumes"finite S" shows"Set.insert x R O S = Finite_Set.fold (λ(w,z) A'. if snd x = w then Set.insert (fst x,z) A' else A') (R O S) S" proof - have"Set.insert x R O S = ({x} O S) ∪ (R O S)" by auto thenshow ?thesis by (auto simp: insert_relcomp_union_fold [OF assms]) qed
lemma comp_fun_commute_relcomp_fold: assumes"finite S" shows"comp_fun_commute (λ(x,y) A. Finite_Set.fold (λ(w,z) A'. if y = w then Set.insert (x,z) A' else A') A S)" proof - have *: "∧a b A. Finite_Set.fold (λ(w, z) A'. if b = w then Set.insert (a, z) A' else A') A S = {(a,b)} O S ∪ A" by (auto simp: insert_relcomp_union_fold[OF assms] cong: if_cong) show ?thesis by standard (auto simp: * ) qed
lemma relcomp_fold: assumes"finite R""finite S" shows"R O S = Finite_Set.fold (λ(x,y) A. Finite_Set.fold (λ(w,z) A'. if y = w then Set.insert (x,z) A' else A') A S) {} R" proof - interpret commute_relcomp_fold: comp_fun_commute "(λ(x, y) A. Finite_Set.fold (λ(w, z) A'. if y = w then insert (x, z) A' else A') A S)" by (fact comp_fun_commute_relcomp_fold[OF ‹finite S›]) from assms show ?thesis by (induct R) (auto simp: comp_fun_commute_relcomp_fold insert_relcomp_fold cong: if_cong) qed
subsection‹Locales as mini-packages for fold operations›
subsubsection ‹The natural case›
locale folding_on = fixes S :: "'a set" fixes f :: "'a ==> 'b ==> 'b"and z :: "'b" assumes comp_fun_commute_on: "x ∈ S ==> y ∈ S ==> f y o f x = f x o f y" begin
interpretation fold?: comp_fun_commute_on S f by standard (simp add: comp_fun_commute_on)
definition F :: "'a set ==> 'b" where eq_fold: "F A = Finite_Set.fold f z A"
lemma infinite [simp]: "¬ finite A ==> F A = z" by (simp add: eq_fold)
lemma insert [simp]: assumes"insert x A ⊆ S"and"finite A"and"x ∉ A" shows"F (insert x A) = f x (F A)" proof - from fold_insert assms have"Finite_Set.fold f z (insert x A) = f x (Finite_Set.fold f z A)" by simp with‹finite A›show ?thesis by (simp add: eq_fold fun_eq_iff) qed
lemma remove: assumes"A ⊆ S"and"finite A"and"x ∈ A" shows"F A = f x (F (A - {x}))" proof - from‹x ∈ A›obtain B where A: "A = insert x B"and"x ∉ B" by (auto dest: mk_disjoint_insert) moreoverfrom‹finite A› A have"finite B"by simp ultimatelyshow ?thesis using‹A ⊆ S›by auto qed
lemma insert_remove: assumes"insert x A ⊆ S"and"finite A" shows"F (insert x A) = f x (F (A - {x}))" using assms by (cases "x ∈ A") (simp_all add: remove insert_absorb)
end
subsubsection ‹With idempotency›
locale folding_idem_on = folding_on + assumes comp_fun_idem_on: "x ∈ S ==> y ∈ S ==> f x ∘ f x = f x" begin
declare insert [simp del]
interpretation fold?: comp_fun_idem_on S f by standard (simp_all add: comp_fun_commute_on comp_fun_idem_on)
lemma insert_idem [simp]: assumes"insert x A ⊆ S"and"finite A" shows"F (insert x A) = f x (F A)" proof - from fold_insert_idem assms have"fold f z (insert x A) = f x (fold f z A)"by simp with‹finite A›show ?thesis by (simp add: eq_fold fun_eq_iff) qed
end
subsubsection ‹🍋‹UNIV›as the carrier set›
locale folding = fixes f :: "'a ==> 'b ==> 'b"and z :: "'b" assumes comp_fun_commute: "f y ∘ f x = f x ∘ f y" begin
lemma (in -) folding_def': "folding f = folding_on UNIV f" unfolding folding_def folding_on_def by blast
text‹ Again, we abuse the ‹rewrites›functionality of locales to remove trivial assumptions that result from instantiating the carrier set to 🍋‹UNIV›. ›
sublocale folding_on UNIV f
rewrites "∧X. (X ⊆ UNIV) ≡ True" and"∧x. x ∈ UNIV ≡ True" and"∧P. (True ==> P) ≡ Trueprop P" and"∧P Q. (True ==> PROP P ==> PROP Q) ≡ (PROP P ==> True ==> PROP Q)" proof - show"folding_on UNIV f" by standard (simp add: comp_fun_commute) qed simp_all
end
locale folding_idem = folding + assumes comp_fun_idem: "f x ∘ f x = f x" begin
lemma (in -) folding_idem_def': "folding_idem f = folding_idem_on UNIV f" unfolding folding_idem_def folding_def' folding_idem_on_def unfolding folding_idem_axioms_def folding_idem_on_axioms_def by blast
text‹ Again, we abuse the ‹rewrites›functionality of locales to remove trivial assumptions that result from instantiating the carrier set to 🍋‹UNIV›. ›
sublocale folding_idem_on UNIV f
rewrites "∧X. (X ⊆ UNIV) ≡ True" and"∧x. x ∈ UNIV ≡ True" and"∧P. (True ==> P) ≡ Trueprop P" and"∧P Q. (True ==> PROP P ==> PROP Q) ≡ (PROP P ==> True ==> PROP Q)" proof - show"folding_idem_on UNIV f" by standard (simp add: comp_fun_idem) qed simp_all
end
subsection‹Finite cardinality›
text‹ The traditional definition 🍋‹card A ≡ LEAST n. ∃f. A = {f i |i. i 🚫}› is ugly to work with. But now that we have 🍋‹fold›things are easy: ›
global_interpretation card: folding "λ_. Suc" 0 defines card = "folding_on.F (λ_. Suc) 0" by standard (rule refl)
lemma card_insert_disjoint: "finite A ==> x ∉ A ==> card (insert x A) = Suc (card A)" by (fact card.insert)
lemma card_insert_if: "finite A ==> card (insert x A) = (if x ∈ A then card A else Suc (card A))" by auto (simp add: card.insert_remove card.remove)
lemma card_ge_0_finite: "card A > 0 ==> finite A" by (rule ccontr) simp
lemma card_0_eq [simp]: "finite A ==> card A = 0 ⟷ A = {}" by (auto dest: mk_disjoint_insert)
lemma finite_UNIV_card_ge_0: "finite (UNIV :: 'a set) ==> card (UNIV :: 'a set) > 0" by (rule ccontr) simp
lemma card_eq_0_iff: "card A = 0 ⟷ A = {} ∨¬ finite A" by auto
lemma card_gt_0_iff: "0 < card A ⟷ A ≠ {} ∧ finite A" by (simp add: neq0_conv [symmetric] card_eq_0_iff)
lemma card_Suc_Diff1: assumes"finite A""x ∈ A"shows"Suc (card (A - {x})) = card A" proof - have"Suc (card (A - {x})) = card (insert x (A - {x}))" using assms by (simp add: card.insert_remove) alsohave"... = card A" using assms by (simp add: card_insert_if) finallyshow ?thesis . qed
lemma card_insert_le_m1: assumes"n > 0""card y ≤ n - 1"shows"card (insert x y) ≤ n" using assms by (cases "finite y") (auto simp: card_insert_if)
lemma card_Diff_singleton: assumes"x ∈ A"shows"card (A - {x}) = card A - 1" proof (cases "finite A") case True with assms show ?thesis by (simp add: card_Suc_Diff1 [symmetric]) qed auto
lemma card_Diff_singleton_if: "card (A - {x}) = (if x ∈ A then card A - 1 else card A)" by (simp add: card_Diff_singleton)
lemma card_Diff_insert[simp]: assumes"a ∈ A"and"a ∉ B" shows"card (A - insert a B) = card (A - B) - 1" proof - have"A - insert a B = (A - B) - {a}" using assms by blast thenshow ?thesis using assms by (simp add: card_Diff_singleton) qed
lemma card_insert_le: "card A ≤ card (insert x A)" proof (cases "finite A") case True thenshow ?thesis by (simp add: card_insert_if) qed auto
lemma card_Collect_less_nat[simp]: "card {i::nat. i < n} = n" by (induct n) (simp_all add:less_Suc_eq Collect_disj_eq)
lemma card_Collect_le_nat[simp]: "card {i::nat. i ≤ n} = Suc n" using card_Collect_less_nat[of "Suc n"] by (simp add: less_Suc_eq_le)
lemma card_mono: assumes"finite B"and"A ⊆ B" shows"card A ≤ card B" proof - from assms have"finite A" by (auto intro: finite_subset) thenshow ?thesis using assms proof (induct A arbitrary: B) case empty thenshow ?caseby simp next case (insert x A) thenhave"x ∈ B" by simp from insert have"A ⊆ B - {x}"and"finite (B - {x})" by auto with insert.hyps have"card A ≤ card (B - {x})" by auto with‹finite A›‹x ∉ A›‹finite B›‹x ∈ B›show ?case by simp (simp only: card.remove) qed qed
lemma card_seteq: assumes"finite B"and A: "A ⊆ B""card B ≤ card A" shows"A = B" using assms proof (induction arbitrary: A rule: finite_induct) case (insert b B) thenhave A: "finite A""A - {b} ⊆ B" by force+ thenhave"card B ≤ card (A - {b})" using insert by (auto simp add: card_Diff_singleton_if) thenhave"A - {b} = B" using A insert.IH by auto thenshow ?case using insert.hyps insert.prems by auto qed auto
lemma psubset_card_mono: "finite B ==> A < B ==> card A < card B" using card_seteq [of B A] by (auto simp add: psubset_eq)
lemma card_Un_Int: assumes"finite A""finite B" shows"card A + card B = card (A ∪ B) + card (A ∩ B)" using assms proof (induct A) case empty thenshow ?caseby simp next case insert thenshow ?case by (auto simp add: insert_absorb Int_insert_left) qed
lemma card_Un_disjoint: "finite A ==> finite B ==> A ∩ B = {} ==> card (A ∪ B) = card A + card B" using card_Un_Int [of A B] by simp
lemma card_Un_disjnt: "[finite A; finite B; disjnt A B]==> card (A ∪ B) = card A + card B" by (simp add: card_Un_disjoint disjnt_def)
lemma card_Un_le: "card (A ∪ B) ≤ card A + card B" proof (cases "finite A ∧ finite B") case True thenshow ?thesis using le_iff_add card_Un_Int [of A B] by auto qed auto
lemma card_Diff_subset: assumes"finite B" and"B ⊆ A" shows"card (A - B) = card A - card B" using assms proof (cases "finite A") case False with assms show ?thesis by simp next case True with assms show ?thesis by (induct B arbitrary: A) simp_all qed
lemma card_Diff_subset_Int: assumes"finite (A ∩ B)" shows"card (A - B) = card A - card (A ∩ B)" proof - have"A - B = A - A ∩ B"by auto with assms show ?thesis by (simp add: card_Diff_subset) qed
lemma card_Int_Diff: assumes"finite A" shows"card A = card (A ∩ B) + card (A - B)" by (simp add: assms card_Diff_subset_Int card_mono)
lemma diff_card_le_card_Diff: assumes"finite B" shows"card A - card B ≤ card (A - B)" proof - have"card A - card B ≤ card A - card (A ∩ B)" using card_mono[OF assms Int_lower2, of A] by arith alsohave"… = card (A - B)" using assms by (simp add: card_Diff_subset_Int) finallyshow ?thesis . qed
lemma card_le_sym_Diff: assumes"finite A""finite B""card A ≤ card B" shows"card(A - B) ≤ card(B - A)" proof - have"card(A - B) = card A - card (A ∩ B)"using assms(1,2) by(simp add: card_Diff_subset_Int) alsohave"…≤ card B - card (A ∩ B)"using assms(3) by linarith alsohave"… = card(B - A)"using assms(1,2) by(simp add: card_Diff_subset_Int Int_commute) finallyshow ?thesis . qed
lemma card_less_sym_Diff: assumes"finite A""finite B""card A < card B" shows"card(A - B) < card(B - A)" proof - have"card(A - B) = card A - card (A ∩ B)"using assms(1,2) by(simp add: card_Diff_subset_Int) alsohave"… < card B - card (A ∩ B)"using assms(1,3) by (simp add: card_mono diff_less_mono) alsohave"… = card(B - A)"using assms(1,2) by(simp add: card_Diff_subset_Int Int_commute) finallyshow ?thesis . qed
lemma card_Diff1_less_iff: "card (A - {x}) < card A ⟷ finite A ∧ x ∈ A" proof (cases "finite A ∧ x ∈ A") case True thenshow ?thesis by (auto simp: card_gt_0_iff intro: diff_less) qed auto
lemma card_Diff1_less: "finite A ==> x ∈ A ==> card (A - {x}) < card A" unfolding card_Diff1_less_iff by auto
lemma card_Diff2_less: assumes"finite A""x ∈ A""y ∈ A"shows"card (A - {x} - {y}) < card A" proof (cases "x = y") case True with assms show ?thesis by (simp add: card_Diff1_less del: card_Diff_insert) next case False thenhave"card (A - {x} - {y}) < card (A - {x})""card (A - {x}) < card A" using assms by (intro card_Diff1_less; simp)+ thenshow ?thesis by (blast intro: less_trans) qed
lemma card_Diff1_le: "card (A - {x}) ≤ card A" proof (cases "finite A") case True thenshow ?thesis by (cases "x ∈ A") (simp_all add: card_Diff1_less less_imp_le) qed auto
lemma card_psubset: "finite B ==> A ⊆ B ==> card A < card B ==> A < B" by (erule psubsetI) blast
lemma card_le_inj: assumes fA: "finite A" and fB: "finite B" and c: "card A ≤ card B" shows"∃f. f ` A ⊆ B ∧ inj_on f A" using fA fB c proof (induct arbitrary: B rule: finite_induct) case empty thenshow ?caseby simp next case (insert x s t) thenshow ?case proof (induct rule: finite_induct [OF insert.prems(1)]) case 1 thenshow ?caseby simp next case (2 y t) from"2.prems"(1,2,5) "2.hyps"(1,2) have cst: "card s ≤ card t" by simp from"2.prems"(3) [OF "2.hyps"(1) cst] obtain f where *: "f ` s ⊆ t""inj_on f s" by blast let ?g = "(λa. if a = x then y else f a)" have"?g ` insert x s ⊆ insert y t ∧ inj_on ?g (insert x s)" using * "2.prems"(2) "2.hyps"(2) unfolding inj_on_def by auto thenshow ?caseby (rule exI[where ?x="?g"]) qed qed
lemma card_subset_eq: assumes fB: "finite B" and AB: "A ⊆ B" and c: "card A = card B" shows"A = B" proof - from fB AB have fA: "finite A" by (auto intro: finite_subset) from fA fB have fBA: "finite (B - A)" by auto have e: "A ∩ (B - A) = {}" by blast have eq: "A ∪ (B - A) = B" using AB by blast from card_Un_disjoint[OF fA fBA e, unfolded eq c] have"card (B - A) = 0" by arith thenhave"B - A = {}" unfolding card_eq_0_iff using fA fB by simp with AB show"A = B" by blast qed
lemma insert_partition: "x ∉ F ==>∀c1 ∈ insert x F. ∀c2 ∈ insert x F. c1 ≠ c2 ⟶ c1 ∩ c2 = {} ==> x ∩∪F = {}" by auto
lemma finite_psubset_induct [consumes 1, case_names psubset]: assumes finite: "finite A" and major: "∧A. finite A ==> (∧B. B ⊂ A ==> P B) ==> P A" shows"P A" using finite proof (induct A taking: card rule: measure_induct_rule) case (less A) have fin: "finite A"by fact have ih: "card B < card A ==> finite B ==> P B"for B by fact have"P B"if"B ⊂ A"for B proof - from that have"card B < card A" using psubset_card_mono fin by blast moreover from that have"B ⊆ A" by auto thenhave"finite B" using fin finite_subset by blast ultimatelyshow ?thesis using ih by simp qed with fin show"P A"using major by blast qed
lemma finite_induct_select [consumes 1, case_names empty select]: assumes"finite S" and"P {}" and select: "∧T. T ⊂ S ==> P T ==>∃s∈S - T. P (insert s T)" shows"P S" proof - have"0 ≤ card S"by simp thenhave"∃T ⊆ S. card T = card S ∧ P T" proof (induct rule: dec_induct) case base with‹P {}› show ?case by (intro exI[of _ "{}"]) auto next case (step n) thenobtain T where T: "T ⊆ S""card T = n""P T" by auto with‹n 🚫 S›have"T ⊂ S""P T" by auto with select[of T] obtain s where"s ∈ S""s ∉ T""P (insert s T)" by auto with step(2) T ‹finite S›show ?case by (intro exI[of _ "insert s T"]) (auto dest: finite_subset) qed with‹finite S›show"P S" by (auto dest: card_subset_eq) qed
lemma remove_induct [case_names empty infinite remove]: assumes empty: "P ({} :: 'a set)" and infinite: "¬ finite B ==> P B" and remove: "∧A. finite A ==> A ≠ {} ==> A ⊆ B ==> (∧x. x ∈ A ==> P (A - {x})) ==> P A" shows"P B" proof (cases "finite B") case False thenshow ?thesis by (rule infinite) next case True
define A where"A = B" with True have"finite A""A ⊆ B" by simp_all thenshow"P A" proof (induct "card A" arbitrary: A) case 0 thenhave"A = {}"by auto with empty show ?caseby simp next case (Suc n A) from‹A ⊆ B›and‹finite B›have"finite A" by (rule finite_subset) moreoverfrom Suc.hyps have"A ≠ {}"by auto moreovernote‹A ⊆ B› moreoverhave"P (A - {x})"if x: "x ∈ A"for x using x Suc.prems ‹Suc n = card A›by (intro Suc) auto ultimatelyshow ?caseby (rule remove) qed qed
lemma finite_remove_induct [consumes 1, case_names empty remove]: fixes P :: "'a set ==> bool" assumes"finite B" and"P {}" and"∧A. finite A ==> A ≠ {} ==> A ⊆ B ==> (∧x. x ∈ A ==> P (A - {x})) ==> P A" defines"B' ≡ B" shows"P B'" by (induct B' rule: remove_induct) (simp_all add: assms)
text‹Main cardinality theorem.› lemma card_partition [rule_format]: "finite C ==> finite (∪C) ==> (∀c∈C. card c = k) ==> (∀c1 ∈ C. ∀c2 ∈ C. c1 ≠ c2 ⟶ c1 ∩ c2 = {}) ==> k * card C = card (∪C)" proof (induct rule: finite_induct) case empty thenshow ?caseby simp next case (insert x F) thenshow ?case by (simp add: card_Un_disjoint insert_partition finite_subset [of _ "∪(insert _ _)"]) qed
lemma card_eq_UNIV_imp_eq_UNIV: assumes fin: "finite (UNIV :: 'a set)" and card: "card A = card (UNIV :: 'a set)" shows"A = (UNIV :: 'a set)" proof show"A ⊆ UNIV"by simp show"UNIV ⊆ A" proof show"x ∈ A"for x proof (rule ccontr) assume"x ∉ A" thenhave"A ⊂ UNIV"by auto with fin have"card A < card (UNIV :: 'a set)" by (fact psubset_card_mono) with card show False by simp qed qed qed
text‹The form of a finite set of given cardinality›
lemma card_eq_SucD: assumes"card A = Suc k" shows"∃b B. A = insert b B ∧ b ∉ B ∧ card B = k ∧ (k = 0 ⟶ B = {})" proof - have fin: "finite A" using assms by (auto intro: ccontr) moreoverhave"card A ≠ 0" using assms by auto ultimatelyobtain b where b: "b ∈ A" by auto show ?thesis proof (intro exI conjI) show"A = insert b (A - {b})" using b by blast show"b ∉ A - {b}" by blast show"card (A - {b}) = k"and"k = 0 ⟶ A - {b} = {}" using assms b fin by (fastforce dest: mk_disjoint_insert)+ qed qed
lemma card_Suc_eq: "card A = Suc k ⟷ (∃b B. A = insert b B ∧ b ∉ B ∧ card B = k ∧ (k = 0 ⟶ B = {}))" by (auto simp: card_insert_if card_gt_0_iff elim!: card_eq_SucD)
lemma card_Suc_eq_finite: "card A = Suc k ⟷ (∃b B. A = insert b B ∧ b ∉ B ∧ card B = k ∧ finite B)" unfolding card_Suc_eq using card_gt_0_iff by fastforce
lemma card_1_singletonE: assumes"card A = 1" obtains x where"A = {x}" using assms by (auto simp: card_Suc_eq)
lemma is_singleton_iff_card_eq_Suc_0 [code]: ‹is_singleton A ⟷ card A = Suc 0› by (simp add: is_singleton_def card_Suc_eq)
lemma is_singleton_altdef: ‹is_singleton A ⟷ card A = 1› by (simp add: is_singleton_iff_card_eq_Suc_0)
lemma card_eq_Suc_0_iff_is_singleton: ‹card A = Suc 0 ⟷ is_singleton A› by (simp add: is_singleton_altdef)
lemma card_1_singleton_iff: ‹card A = Suc 0 ⟷ (∃x. A = {x})› by (simp add: card_eq_Suc_0_iff_is_singleton is_singleton_def)
lemma card_le_Suc0_iff_eq: assumes"finite A" shows"card A ≤ Suc 0 ⟷ (∀a1 ∈ A. ∀a2 ∈ A. a1 = a2)" (is"?C = ?A") proof assume ?C thus ?A using assms by (auto simp: le_Suc_eq dest: card_eq_SucD) next assume ?A show ?C proof cases assume"A = {}"thus ?C using‹?A›by simp next assume"A ≠ {}" thenobtain a where"A = {a}"using‹?A›by blast thus ?C by simp qed qed
lemma card_le_Suc_iff: "Suc n ≤ card A = (∃a B. A = insert a B ∧ a ∉ B ∧ n ≤ card B ∧ finite B)" proof (cases "finite A") case True thenshow ?thesis by (fastforce simp: card_Suc_eq less_eq_nat.simps split: nat.splits) qed auto
lemma finite_fun_UNIVD2: assumes fin: "finite (UNIV :: ('a ==> 'b) set)" shows"finite (UNIV :: 'b set)" proof - from fin have"finite (range (λf :: 'a ==> 'b. f arbitrary))"for arbitrary by (rule finite_imageI) moreoverhave"UNIV = range (λf :: 'a ==> 'b. f arbitrary)"for arbitrary by (rule UNIV_eq_I) auto ultimatelyshow"finite (UNIV :: 'b set)" by simp qed
lemma card_UNIV_unit [simp]: "card (UNIV :: unit set) = 1" unfolding UNIV_unit by simp
lemma infinite_arbitrarily_large: assumes"¬ finite A" shows"∃B. finite B ∧ card B = n ∧ B ⊆ A" proof (induction n) case 0 show ?caseby (intro exI[of _ "{}"]) auto next case (Suc n) thenobtain B where B: "finite B ∧ card B = n ∧ B ⊆ A" .. with‹¬ finite A›have"A ≠ B"by auto with B have"B ⊂ A"by auto thenhave"∃x. x ∈ A - B" by (elim psubset_imp_ex_mem) thenobtain x where x: "x ∈ A - B" .. with B have"finite (insert x B) ∧ card (insert x B) = Suc n ∧ insert x B ⊆ A" by auto thenshow"∃B. finite B ∧ card B = Suc n ∧ B ⊆ A" .. qed
corollary finite_arbitrarily_large_disj: "[¬ finite(UNIV::'a set); finite (A::'a set) ]==>∃B. finite B ∧ card B = n ∧A ∩ B = {}" using infinite_arbitrarily_large[of "UNIV - A"] by fastforce
text‹Sometimes, to prove that a set is finite, it is convenient to work with finite subsets and to show that their cardinalities are uniformly bounded. This possibility is formalized in the next criterion.›
lemma finite_if_finite_subsets_card_bdd: assumes"∧G. G ⊆ F ==> finite G ==> card G ≤ C" shows"finite F ∧ card F ≤ C" proof (cases "finite F") case False obtain n::nat where n: "n > max C 0"by auto obtain G where G: "G ⊆ F""card G = n"using infinite_arbitrarily_large[OF False] by auto hence"finite G"using‹n > max C 0›using card.infinite gr_implies_not0 by blast hence False using assms G n not_less by auto thus ?thesis .. next case True thus ?thesis using assms[of F] by auto qed
lemma obtain_subset_with_card_n: assumes"n ≤ card S" obtains T where"T ⊆ S""card T = n""finite T" proof - obtain n' where"card S = n + n'" using le_Suc_ex[OF assms] by blast with that show thesis proof (induct n' arbitrary: S) case 0 thus ?caseby (cases "finite S") auto next case Suc thus ?caseby (auto simp add: card_Suc_eq) qed qed
lemma exists_subset_between: assumes "card A ≤ n" "n ≤ card C" "A ⊆ C" "finite C" shows"∃B. A ⊆ B ∧ B ⊆ C ∧ card B = n" using assms proof (induct n arbitrary: A C) case 0 thus ?caseusing finite_subset[of A C] by (intro exI[of _ "{}"], auto) next case (Suc n A C) show ?case proof (cases "A = {}") case True from obtain_subset_with_card_n[OF Suc(3)] obtain B where"B ⊆ C""card B = Suc n"by blast thus ?thesis unfolding True by blast next case False thenobtain a where a: "a ∈ A"by auto let ?A = "A - {a}" let ?C = "C - {a}" have 1: "card ?A ≤ n"using Suc(2-) a using finite_subset by fastforce have 2: "card ?C ≥ n"using Suc(2-) a by auto from Suc(1)[OF 1 2 _ finite_subset[OF _ Suc(5)]] Suc(2-) obtain B where"?A ⊆ B""B ⊆ ?C""card B = n"by blast thus ?thesis using a Suc(2-) by (intro exI[of _ "insert a B"], auto intro!: card_insert_disjoint finite_subset[of B C]) qed qed
subsubsection ‹Cardinality of image›
lemma card_image_le: "finite A ==> card (f ` A) ≤ card A" by (induct rule: finite_induct) (simp_all add: le_SucI card_insert_if)
lemma card_image: "inj_on f A ==> card (f ` A) = card A" proof (induct A rule: infinite_finite_induct) case (infinite A) thenhave"¬ finite (f ` A)"by (auto dest: finite_imageD) with infinite show ?caseby simp qed simp_all
lemma bij_betw_same_card: "bij_betw f A B ==> card A = card B" by (auto simp: card_image bij_betw_def)
lemma endo_inj_surj: "finite A ==> f ` A ⊆ A ==> inj_on f A ==> f ` A = A" by (simp add: card_seteq card_image)
lemma eq_card_imp_inj_on: assumes"finite A""card(f ` A) = card A" shows"inj_on f A" using assms proof (induct rule:finite_induct) case empty show ?caseby simp next case (insert x A) thenshow ?case using card_image_le [of A f] by (simp add: card_insert_if split: if_splits) qed
lemma inj_on_iff_eq_card: "finite A ==> inj_on f A ⟷ card (f ` A) = card A" by (blast intro: card_image eq_card_imp_inj_on)
lemma card_inj_on_le: assumes"inj_on f A""f ` A ⊆ B""finite B" shows"card A ≤ card B" proof - have"finite A" using assms by (blast intro: finite_imageD dest: finite_subset) thenshow ?thesis using assms by (force intro: card_mono simp: card_image [symmetric]) qed
lemma inj_on_iff_card_le: "[ finite A; finite B ]==> (∃f. inj_on f A ∧ f ` A ≤ B) = (card A ≤ card B)" using card_inj_on_le[of _ A B] card_le_inj[of A B] by blast
lemma surj_card_le: "finite A ==> B ⊆ f ` A ==> card B ≤ card A" by (blast intro: card_image_le card_mono le_trans)
lemma card_bij_eq: "inj_on f A ==> f ` A ⊆ B ==> inj_on g B ==> g ` B ⊆ A ==> finite A ==> finite B ==> card A = card B" by (auto intro: le_antisym card_inj_on_le)
lemma bij_betw_finite: "bij_betw f A B ==> finite A ⟷ finite B" unfolding bij_betw_def using finite_imageD [of f A] by auto
lemma inj_on_finite: "inj_on f A ==> f ` A ≤ B ==> finite B ==> finite A" using finite_imageD finite_subset by blast
lemma card_vimage_inj_on_le: assumes"inj_on f D""finite A" shows"card (f-`A ∩ D) ≤ card A" proof (rule card_inj_on_le) show"inj_on f (f -` A ∩ D)" by (blast intro: assms inj_on_subset) qed (use assms in auto)
lemma card_vimage_inj: "inj f ==> A ⊆ range f ==> card (f -` A) = card A" by (auto 4 3 simp: subset_image_iff inj_vimage_image_eq
intro: card_image[symmetric, OF inj_on_subset])
lemma card_inverse[simp]: "card (R-1) = card R" proof - have *: "∧R. prod.swap ` R = R-1"by auto
{ assume"¬finite R" hence ?thesis by auto
} moreover { assume"finite R" with card_image_le[of R prod.swap] card_image_le[of "R-1" prod.swap] have ?thesis by (auto simp: * )
} ultimatelyshow ?thesis by blast qed
subsubsection ‹Pigeonhole Principles›
lemma pigeonhole: "card A > card (f ` A) ==>¬ inj_on f A " by (auto dest: card_image less_irrefl_nat)
lemma pigeonhole_infinite: assumes"¬ finite A"and"finite (f`A)" shows"∃a0∈A. ¬ finite {a∈A. f a = f a0}" using assms(2,1) proof (induct "f`A" arbitrary: A rule: finite_induct) case empty thenshow ?caseby simp next case (insert b F) show ?case proof (cases "finite {a∈A. f a = b}") case True with‹¬ finite A›have"¬ finite (A - {a∈A. f a = b})" by simp alsohave"A - {a∈A. f a = b} = {a∈A. f a ≠ b}" by blast finallyhave"¬ finite {a∈A. f a ≠ b}" . from insert(3)[OF _ this] insert(2,4) show ?thesis by simp (blast intro: rev_finite_subset) next case False thenhave"{a ∈ A. f a = b} ≠ {}"by force with False show ?thesis by blast qed qed
lemma pigeonhole_infinite_rel: assumes"¬ finite A" and"finite B" and"∀a∈A. ∃b∈B. R a b" shows"∃b∈B. ¬ finite {a:A. R a b}" proof - let ?F = "λa. {b∈B. R a b}" from finite_Pow_iff[THEN iffD2, OF ‹finite B›] have"finite (?F ` A)" by (blast intro: rev_finite_subset) from pigeonhole_infinite [where f = ?F, OF assms(1) this] obtain a0 where"a0 ∈ A"and infinite: "¬ finite {a∈A. ?F a = ?F a0}" .. obtain b0 where"b0 ∈ B"and"R a0 b0" using‹a0 ∈ A› assms(3) by blast have"finite {a∈A. ?F a = ?F a0}"if"finite {a∈A. R a b0}" using‹b0 ∈ B›‹R a0 b0› that by (blast intro: rev_finite_subset) with infinite ‹b0 ∈ B›show ?thesis by blast qed
subsubsection ‹Cardinality of sums›
lemma card_Plus: assumes"finite A""finite B" shows"card (A <+> B) = card A + card B" proof - have"Inl`A ∩ Inr`B = {}"by fast with assms show ?thesis by (simp add: Plus_def card_Un_disjoint card_image) qed
lemma card_Plus_conv_if: "card (A <+> B) = (if finite A ∧ finite B then card A + card B else 0)" by (auto simp add: card_Plus)
text‹Relates to equivalence classes. Based on a theorem of F. Kammüller.›
lemma dvd_partition: assumes f: "finite (∪C)" and"∀c∈C. k dvd card c""∀c1∈C. ∀c2∈C. c1 ≠ c2 ⟶ c1 ∩ c2 = {}" shows"k dvd card (∪C)" proof - have"finite C" by (rule finite_UnionD [OF f]) thenshow ?thesis using assms proof (induct rule: finite_induct) case empty show ?caseby simp next case (insert c C) thenhave"c ∩∪C = {}" by auto with insert show ?case by (simp add: card_Un_disjoint) qed qed
subsection‹Minimal and maximal elements of finite sets›
contextbegin
qualified lemma assumes"finite A"and"asymp_on A R"and"transp_on A R"and"∃x ∈ A. P x" shows
bex_min_element_with_property: "∃x ∈ A. P x ∧ (∀y ∈ A. R y x ⟶¬ P y)"and
bex_max_element_with_property: "∃x ∈ A. P x ∧ (∀y ∈ A. R x y ⟶¬ P y)" unfolding atomize_conj using assms proof (induction A rule: finite_induct) case empty hence False by simp_all thus ?case .. next case (insert x F)
from insert.prems have"asymp_on F R" using asymp_on_subset by blast
from insert.prems have"transp_on F R" using transp_on_subset by blast
show ?case proof (cases "P x") case True show ?thesis proof (cases "∃a∈F. P a") case True with insert.IH obtain min max where "min ∈ F"and"P min"and"∀z ∈ F. R z min ⟶¬ P z" "max ∈ F"and"P max"and"∀z ∈ F. R max z ⟶¬ P z" using‹asymp_on F R›‹transp_on F R›by auto
show ?thesis proof (rule conjI) show"∃y ∈ insert x F. P y ∧ (∀z ∈ insert x F. R y z ⟶¬ P z)" proof (cases "R max x") case True show ?thesis proof (intro bexI conjI ballI impI) show"x ∈ insert x F" by simp next show"P x" using‹P x›by simp next fix z assume"z ∈ insert x F"and"R x z" hence"z = x ∨ z ∈ F" by simp thus"¬ P z" proof (rule disjE) assume"z = x" hence"R x x" using‹R x z›by simp moreoverhave"¬ R x x" using‹asymp_on (insert x F) R›[THEN irreflp_on_if_asymp_on, THEN irreflp_onD] by simp ultimatelyhave False by simp thus ?thesis .. next assume"z ∈ F" moreoverhave"R max z" using‹R max x›‹R x z› using‹transp_on (insert x F) R›[THEN transp_onD, of max x z] using‹max ∈ F›‹z ∈ F›by simp ultimatelyshow ?thesis using‹∀z ∈ F. R max z ⟶¬ P z›by simp qed qed next case False show ?thesis proof (intro bexI conjI ballI impI) show"max ∈ insert x F" using‹max ∈ F›by simp next show"P max" using‹P max›by simp next fix z assume"z ∈ insert x F"and"R max z" hence"z = x ∨ z ∈ F" by simp thus"¬ P z" proof (rule disjE) assume"z = x" hence False using‹¬ R max x›‹R max z›by simp thus ?thesis .. next assume"z ∈ F" thus ?thesis using‹R max z›‹∀z∈F. R max z ⟶¬ P z›by simp qed qed qed next show"∃y ∈ insert x F. P y ∧ (∀z ∈ insert x F. R z y ⟶¬ P z)" proof (cases "R x min") case True show ?thesis proof (intro bexI conjI ballI impI) show"x ∈ insert x F" by simp next show"P x" using‹P x›by simp next fix z assume"z ∈ insert x F"and"R z x" hence"z = x ∨ z ∈ F" by simp thus"¬ P z" proof (rule disjE) assume"z = x" hence"R x x" using‹R z x›by simp moreoverhave"¬ R x x" using‹asymp_on (insert x F) R›[THEN irreflp_on_if_asymp_on, THEN irreflp_onD] by simp ultimatelyhave False by simp thus ?thesis .. next assume"z ∈ F" moreoverhave"R z min" using‹R z x›‹R x min› using‹transp_on (insert x F) R›[THEN transp_onD, of z x min] using‹min ∈ F›‹z ∈ F›by simp ultimatelyshow ?thesis using‹∀z ∈ F. R z min ⟶¬ P z›by simp qed qed next case False show ?thesis proof (intro bexI conjI ballI impI) show"min ∈ insert x F" using‹min ∈ F›by simp next show"P min" using‹P min›by simp next fix z assume"z ∈ insert x F"and"R z min" hence"z = x ∨ z ∈ F" by simp thus"¬ P z" proof (rule disjE) assume"z = x" hence False using‹¬ R x min›‹R z min›by simp thus ?thesis .. next assume"z ∈ F" thus ?thesis using‹R z min›‹∀z∈F. R z min ⟶¬ P z›by simp qed qed qed qed next case False thenshow ?thesis using‹∃a∈insert x F. P a› using‹asymp_on (insert x F) R›[THEN asymp_onD, of x] insert_iff[of _ x F] by blast qed next case False with insert.prems have"∃x ∈ F. P x" by simp with insert.IH have "∃y ∈ F. P y ∧ (∀z∈F. R z y ⟶¬ P z)" "∃y ∈ F. P y ∧ (∀z∈F. R y z ⟶¬ P z)" using‹asymp_on F R›‹transp_on F R›by auto thus ?thesis using False by auto qed qed
qualified lemma assumes"finite A"and"asymp_on A R"and"transp_on A R"and"A ≠ {}" shows
bex_min_element: "∃m ∈ A. ∀x ∈ A. x ≠ m ⟶¬ R x m"and
bex_max_element: "∃m ∈ A. ∀x ∈ A. x ≠ m ⟶¬ R m x" using‹A ≠ {}›
bex_min_element_with_property[OF assms(1,2,3), of "λ_. True", simplified]
bex_max_element_with_property[OF assms(1,2,3), of "λ_. True", simplified] by blast+
end
text‹The following alternative form might sometimes be easier to work with.›
lemma is_min_element_in_set_iff: "asymp_on A R ==> (∀y ∈ A. y ≠ x ⟶¬ R y x) ⟷ (∀y. R y x ⟶ y ∉ A)" by (auto dest: asymp_onD)
lemma is_max_element_in_set_iff: "asymp_on A R ==> (∀y ∈ A. y ≠ x ⟶¬ R x y) ⟷ (∀y. R x y ⟶ y ∉ A)" by (auto dest: asymp_onD)
contextbegin
qualified lemma assumes"finite A"and"A ≠ {}"and"transp_on A R"and"totalp_on A R" shows
bex_least_element: "∃l ∈ A. ∀x ∈ A. x ≠ l ⟶ R l x"and
bex_greatest_element: "∃g ∈ A. ∀x ∈ A. x ≠ g ⟶ R x g" unfolding atomize_conj using assms proof (induction A rule: finite_induct) case empty hence False by simp thus ?case .. next case (insert a A')
from insert.prems(2) have transp_on_A': "transp_on A' R" by (auto intro: transp_onI dest: transp_onD)
from insert.prems(3) have
totalp_on_a_A'_raw: "∀y ∈ A'. a ≠ y ⟶ R a y ∨ R y a"and
totalp_on_A': "totalp_on A' R" by (simp_all add: totalp_on_def)
show ?case proof (cases "A' = {}") case True thus ?thesis by simp next case False thenobtain least greatest where "least ∈ A'"and least_of_A': "∀x∈A'. x ≠ least ⟶ R least x"and "greatest ∈ A'"and greatest_of_A': "∀x∈A'. x ≠ greatest ⟶ R x greatest" using insert.IH[OF _ transp_on_A' totalp_on_A'] by auto
show ?thesis proof (rule conjI) show"∃l∈insert a A'. ∀x∈insert a A'. x ≠ l ⟶ R l x" proof (cases "R a least") case True show ?thesis proof (intro bexI ballI impI) show"a ∈ insert a A'" by simp next fix x show"∧x. x ∈ insert a A' ==> x ≠ a ==> R a x" using True ‹least ∈ A'› least_of_A' using insert.prems(2)[THEN transp_onD, of a least] by auto qed next case False show ?thesis proof (intro bexI ballI impI) show"least ∈ insert a A'" using‹least ∈ A'›by simp next fix x show"x ∈ insert a A' ==> x ≠ least ==> R least x" using False ‹least ∈ A'› least_of_A' totalp_on_a_A'_raw by (cases "x = a") auto qed qed next show"∃g ∈ insert a A'. ∀x ∈ insert a A'. x ≠ g ⟶ R x g" proof (cases "R greatest a") case True show ?thesis proof (intro bexI ballI impI) show"a ∈ insert a A'" by simp next fix x show"∧x. x ∈ insert a A' ==> x ≠ a ==> R x a" using True ‹greatest ∈ A'› greatest_of_A' using insert.prems(2)[THEN transp_onD, of _ greatest a] by auto qed next case False show ?thesis proof (intro bexI ballI impI) show"greatest ∈ insert a A'" using‹greatest ∈ A'›by simp next fix x show"x ∈ insert a A' ==> x ≠ greatest ==> R x greatest" using False ‹greatest ∈ A'› greatest_of_A' totalp_on_a_A'_raw by (cases "x = a") auto qed qed qed qed qed
end
subsubsection ‹Finite orders›
context order begin
lemma finite_has_maximal: assumes"finite A"and"A ≠ {}" shows"∃ m ∈ A. ∀ b ∈ A. m ≤ b ⟶ m = b" proof - obtain m where"m ∈ A"and m_is_max: "∀x∈A. x ≠ m ⟶¬ m < x" using Finite_Set.bex_max_element[OF ‹finite A› _ _ ‹A ≠ {}›, of "(<)"] by auto moreoverhave"∀b ∈ A. m ≤ b ⟶ m = b" using m_is_max by (auto simp: le_less) ultimatelyshow ?thesis by auto qed
lemma finite_has_maximal2: "[ finite A; a ∈ A ]==>∃ m ∈ A. a ≤ m ∧ (∀ b ∈ A. m ≤ b ⟶ m = b)" using finite_has_maximal[of "{b ∈ A. a ≤ b}"] by fastforce
lemma finite_has_minimal: assumes"finite A"and"A ≠ {}" shows"∃ m ∈ A. ∀ b ∈ A. b ≤ m ⟶ m = b" proof - obtain m where"m ∈ A"and m_is_min: "∀x∈A. x ≠ m ⟶¬ x < m" using Finite_Set.bex_min_element[OF ‹finite A› _ _ ‹A ≠ {}›, of "(<)"] by auto moreoverhave"∀b ∈ A. b ≤ m ⟶ m = b" using m_is_min by (auto simp: le_less) ultimatelyshow ?thesis by auto qed
lemma finite_has_minimal2: "[ finite A; a ∈ A ]==>∃ m ∈ A. m ≤ a ∧ (∀ b ∈ A. b ≤ m ⟶ m = b)" using finite_has_minimal[of "{b ∈ A. b ≤ a}"] by fastforce
end
subsubsection ‹Relating injectivity and surjectivity›
lemma finite_surj_inj: assumes"finite A""A ⊆ f ` A" shows"inj_on f A" proof - have"f ` A = A" by (rule card_seteq [THEN sym]) (auto simp add: assms card_image_le) thenshow ?thesis using assms by (simp add: eq_card_imp_inj_on) qed
lemma finite_UNIV_surj_inj: "finite(UNIV:: 'a set) ==> surj f ==> inj f" for f :: "'a ==> 'a" by (blast intro: finite_surj_inj subset_UNIV)
lemma finite_UNIV_inj_surj: "finite(UNIV:: 'a set) ==> inj f ==> surj f" for f :: "'a ==> 'a" by (fastforce simp:surj_def dest!: endo_inj_surj)
lemma surjective_iff_injective_gen: assumes fS: "finite S" and fT: "finite T" and c: "card S = card T" and ST: "f ` S ⊆ T" shows"(∀y ∈ T. ∃x ∈ S. f x = y) ⟷ inj_on f S"
(is"?lhs ⟷ ?rhs") proof assume h: "?lhs"
{ fix x y assume x: "x ∈ S" assume y: "y ∈ S" assume f: "f x = f y" from x fS have S0: "card S ≠ 0" by auto have"x = y" proof (rule ccontr) assume xy: "¬ ?thesis" have th: "card S ≤ card (f ` (S - {y}))" unfolding c proof (rule card_mono) show"finite (f ` (S - {y}))" by (simp add: fS) have"[x ≠ y; x ∈ S; z ∈ S; f x = f y] ==>∃x ∈ S. x ≠ y ∧ f z = f x"for z by (cases "z = y ⟶ z = x") auto thenshow"T ⊆ f ` (S - {y})" using h xy x y f by fastforce qed alsohave" …≤ card (S - {y})" by (simp add: card_image_le fS) alsohave"…≤ card S - 1"using y fS by simp finallyshow False using S0 by arith qed
} thenshow ?rhs unfolding inj_on_def by blast next assume h: ?rhs have"f ` S = T" by (simp add: ST c card_image card_subset_eq fT h) thenshow ?lhs by blast qed
hide_const (open) Finite_Set.fold
subsection‹Infinite Sets›
text‹ Some elementary facts about infinite sets, mostly by Stephan Merz. Beware! Because "infinite" merely abbreviates a negation, these lemmas may not work well with ‹blast›. ›
abbreviation infinite :: "'a set ==> bool" where"infinite S ≡¬ finite S"
text‹ Infinite sets are non-empty, and if we remove some elements from an infinite set, the result is still infinite. ›
lemma infinite_UNIV_nat [iff]: "infinite (UNIV :: nat set)" proof assume"finite (UNIV :: nat set)" with finite_UNIV_inj_surj [of Suc] show False by simp (blast dest: Suc_neq_Zero surjD) qed
lemma infinite_UNIV_char_0: "infinite (UNIV :: 'a::semiring_char_0 set)" proof assume"finite (UNIV :: 'a set)" with subset_UNIV have"finite (range of_nat :: 'a set)" by (rule finite_subset) moreoverhave"inj (of_nat :: nat ==> 'a)" by (simp add: inj_on_def) ultimatelyhave"finite (UNIV :: nat set)" by (rule finite_imageD) thenshow False by simp qed
lemma infinite_imp_nonempty: "infinite S ==> S ≠ {}" by auto
lemma infinite_remove: "infinite S ==> infinite (S - {a})" by simp
lemma Diff_infinite_finite: assumes"finite T""infinite S" shows"infinite (S - T)" using‹finite T› proof induct from‹infinite S›show"infinite (S - {})" by auto next fix T x assume ih: "infinite (S - T)" have"S - (insert x T) = (S - T) - {x}" by (rule Diff_insert) with ih show"infinite (S - (insert x T))" by (simp add: infinite_remove) qed
lemma Un_infinite: "infinite S ==> infinite (S ∪ T)" by simp
lemma infinite_Un: "infinite (S ∪ T) ⟷ infinite S ∨ infinite T" by simp
proposition infinite_coinduct [consumes 1, case_names infinite]: assumes"X A" and step: "∧A. X A ==>∃x∈A. X (A - {x}) ∨ infinite (A - {x})" shows"infinite A" proof assume"finite A" thenshow False using‹X A› proof (induction rule: finite_psubset_induct) case (psubset A) thenobtain x where"x ∈ A""X (A - {x}) ∨ infinite (A - {x})" usinglocal.step psubset.prems by blast thenhave"X (A - {x})" using psubset.hyps by blast show False proof (rule psubset.IH [where B = "A - {x}"]) show"A - {x} ⊂ A" using‹x ∈ A›by blast qed fact qed qed
text‹ For any function with infinite domain and finite range there is some element that is the image of infinitely many domain elements. In particular, any infinite sequence of elements from a finite set contains some element that occurs infinitely often. ›
lemma inf_img_fin_dom': assumes img: "finite (f ` A)" and dom: "infinite A" shows"∃y ∈ f ` A. infinite (f -` {y} ∩ A)" proof (rule ccontr) have"A ⊆ (∪y∈f ` A. f -` {y} ∩ A)"by auto moreoverassume"¬ ?thesis" with img have"finite (∪y∈f ` A. f -` {y} ∩ A)"by blast ultimatelyhave"finite A"by (rule finite_subset) with dom show False by contradiction qed
lemma inf_img_fin_domE': assumes"finite (f ` A)"and"infinite A" obtains y where"y ∈ f`A"and"infinite (f -` {y} ∩ A)" using assms by (blast dest: inf_img_fin_dom')
lemma inf_img_fin_dom: assumes img: "finite (f`A)"and dom: "infinite A" shows"∃y ∈ f`A. infinite (f -` {y})" using inf_img_fin_dom'[OF assms] by auto
lemma inf_img_fin_domE: assumes"finite (f`A)"and"infinite A" obtains y where"y ∈ f`A"and"infinite (f -` {y})" using assms by (blast dest: inf_img_fin_dom)
proposition finite_image_absD: "finite (abs ` S) ==> finite S" for S :: "'a::linordered_ring set" by (rule ccontr) (auto simp: abs_eq_iff vimage_def dest: inf_img_fin_dom)
subsection‹The finite powerset operator›
definition Fpow :: "'a set ==> 'a set set" where"Fpow A ≡ {X. X ⊆ A ∧ finite X}"
lemma Fpow_mono: "A ⊆ B ==> Fpow A ⊆ Fpow B" unfolding Fpow_def by auto
lemma empty_in_Fpow: "{} ∈ Fpow A" unfolding Fpow_def by auto
lemma Fpow_not_empty: "Fpow A ≠ {}" using empty_in_Fpow by blast
lemma Fpow_subset_Pow: "Fpow A ⊆ Pow A" unfolding Fpow_def by auto
lemma Fpow_Pow_finite: "Fpow A = Pow A Int {A. finite A}" unfolding Fpow_def Pow_def by blast
lemma inj_on_image_Fpow: assumes"inj_on f A" shows"inj_on (image f) (Fpow A)" using assms Fpow_subset_Pow[of A] inj_on_subset[of "image f""Pow A"]
inj_on_image_Pow by blast
lemma image_Fpow_mono: assumes"f ` A ⊆ B" shows"(image f) ` (Fpow A) ⊆ Fpow B" using assms by(unfold Fpow_def, auto)
end
Messung V0.5 in Prozent
¤ 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.0.117Bemerkung:
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-04-26)
¤
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.