(* Title: HOL/Library/Countable_Set.thy Author: Johannes Hölzl Author: Andrei Popescu
*)
section \<open>Countable sets\<close>
theory Countable_Set imports Countable Infinite_Set begin
subsection \<open>Predicate for countable sets\<close>
definition countable :: "'a set \ bool" where "countable S \ (\f::'a \ nat. inj_on f S)"
lemma countable_as_injective_image_subset: "countable S \ (\f. \K::nat set. S = f ` K \ inj_on f K)" by (metis countable_def inj_on_the_inv_into the_inv_into_onto)
lemma countableE: assumes S: "countable S"obtains f :: "'a \ nat" where "inj_on f S" using S by (auto simp: countable_def)
lemma countableI: "inj_on (f::'a \ nat) S \ countable S" by (auto simp: countable_def)
lemma countableI': "inj_on (f::'a \<Rightarrow> 'b::countable) S \<Longrightarrow> countable S" using comp_inj_on[of f S to_nat] by (auto intro: countableI)
lemma countableE_bij: assumes S: "countable S"obtains f :: "nat \ 'a" and C :: "nat set" where "bij_betw f C S" using S by (blast elim: countableE dest: inj_on_imp_bij_betw bij_betw_inv)
lemma countableI_bij: "bij_betw f (C::nat set) S \ countable S" by (blast intro: countableI bij_betw_inv_into bij_betw_imp_inj_on)
lemma countable_finite: "finite S \ countable S" by (blast dest: finite_imp_inj_to_nat_seg countableI)
lemma countableI_bij1: "bij_betw f A B \ countable A \ countable B" by (blast elim: countableE_bij intro: bij_betw_trans countableI_bij)
lemma countableI_bij2: "bij_betw f B A \ countable A \ countable B" by (blast elim: countableE_bij intro: bij_betw_trans bij_betw_inv_into countableI_bij)
lemma countable_iff_bij[simp]: "bij_betw f A B \ countable A \ countable B" by (blast intro: countableI_bij1 countableI_bij2)
lemma countable_subset: "A \ B \ countable B \ countable A" by (auto simp: countable_def intro: inj_on_subset)
lemma countableI_type[intro, simp]: "countable (A:: 'a :: countable set)" using countableI[of to_nat A] by auto
subsection \<open>Enumerate a countable set\<close>
lemma countableE_infinite: assumes"countable S""infinite S" obtains e :: "'a \ nat" where "bij_betw e S UNIV" proof - obtain f :: "'a \ nat" where "inj_on f S" using\<open>countable S\<close> by (rule countableE) thenhave"bij_betw f S (f`S)" unfolding bij_betw_def by simp moreover from\<open>inj_on f S\<close> \<open>infinite S\<close> have inf_fS: "infinite (f`S)" by (auto dest: finite_imageD) thenhave"bij_betw (the_inv_into UNIV (enumerate (f`S))) (f`S) UNIV" by (intro bij_betw_the_inv_into bij_enumerate) ultimatelyhave"bij_betw (the_inv_into UNIV (enumerate (f`S)) \ f) S UNIV" by (rule bij_betw_trans) thenshow thesis .. qed
lemma countable_infiniteE': assumes"countable A""infinite A" obtains g where"bij_betw g (UNIV :: nat set) A" by (meson assms bij_betw_inv countableE_infinite)
lemma countable_enum_cases: assumes"countable S" obtains (finite) f :: "'a \ nat" where "finite S" "bij_betw f S {..
| (infinite) f :: "'a \ nat" where "infinite S" "bij_betw f S UNIV" using ex_bij_betw_finite_nat[of S] countableE_infinite \<open>countable S\<close> by (cases "finite S") (auto simp add: atLeast0LessThan)
definition to_nat_on :: "'a set \ 'a \ nat" where "to_nat_on S = (SOME f. if finite S then bij_betw f S {..< card S} else bij_betw f S UNIV)"
definition from_nat_into :: "'a set \ nat \ 'a" where "from_nat_into S n = (if n \ to_nat_on S ` S then inv_into S (to_nat_on S) n else SOME s. s\S)"
lemma to_nat_on_finite: "finite S \ bij_betw (to_nat_on S) S {..< card S}" using ex_bij_betw_finite_nat unfolding to_nat_on_def by (intro someI2_ex[where Q="\f. bij_betw f S {..
lemma to_nat_on_infinite: "countable S \ infinite S \ bij_betw (to_nat_on S) S UNIV" using countableE_infinite unfolding to_nat_on_def by (intro someI2_ex[where Q="\f. bij_betw f S UNIV"]) auto
lemma bij_betw_from_nat_into: "countable S \ infinite S \ bij_betw (from_nat_into S) UNIV S" unfolding from_nat_into_def[abs_def] using to_nat_on_infinite[of S, unfolded bij_betw_def] by (auto cong: bij_betw_cong intro: bij_betw_inv_into to_nat_on_infinite)
text\<open>
The sum/product over the enumeration of a finite set equals simply the sum/product over the set \<close> context comm_monoid_set begin
lemma card_from_nat_into: "F (\i. h (from_nat_into A i)) {.. proof (cases "finite A") case True have"F (\i. h (from_nat_into A i)) {.. by (metis True bij_betw_def bij_betw_from_nat_into_finite reindex_cong) alsohave"... = F h A" by (metis True bij_betw_def bij_betw_from_nat_into_finite) finallyshow ?thesis . qed auto
end
lemma countable_as_injective_image: assumes"countable A""infinite A" obtains f :: "nat \ 'a" where "A = range f" "inj f" by (metis bij_betw_def bij_betw_from_nat_into [OF assms])
lemma inj_on_to_nat_on[intro]: "countable A \ inj_on (to_nat_on A) A" using to_nat_on_infinite[of A] to_nat_on_finite[of A] by (cases "finite A") (auto simp: bij_betw_def)
lemma to_nat_on_inj[simp]: "countable A \ a \ A \ b \ A \ to_nat_on A a = to_nat_on A b \ a = b" using inj_on_to_nat_on[of A] by (auto dest: inj_onD)
lemma from_nat_into_to_nat_on[simp]: "countable A \ a \ A \ from_nat_into A (to_nat_on A a) = a" by (auto simp: from_nat_into_def intro!: inv_into_f_f)
lemma subset_range_from_nat_into: "countable A \ A \ range (from_nat_into A)" by (auto intro: from_nat_into_to_nat_on[symmetric])
lemma from_nat_into: "A \ {} \ from_nat_into A n \ A" unfolding from_nat_into_def by (metis equals0I inv_into_into someI_ex)
lemma range_from_nat_into_subset: "A \ {} \ range (from_nat_into A) \ A" using from_nat_into[of A] by auto
lemma range_from_nat_into[simp]: "A \ {} \ countable A \ range (from_nat_into A) = A" by (metis equalityI range_from_nat_into_subset subset_range_from_nat_into)
lemma image_to_nat_on: "countable A \ infinite A \ to_nat_on A ` A = UNIV" using to_nat_on_infinite[of A] by (simp add: bij_betw_def)
lemma to_nat_on_surj: "countable A \ infinite A \ \a\A. to_nat_on A a = n" by (metis (no_types) image_iff iso_tuple_UNIV_I image_to_nat_on)
lemma to_nat_on_from_nat_into[simp]: "n \ to_nat_on A ` A \ to_nat_on A (from_nat_into A n) = n" by (simp add: f_inv_into_f from_nat_into_def)
lemma to_nat_on_from_nat_into_infinite[simp]: "countable A \ infinite A \ to_nat_on A (from_nat_into A n) = n" by (metis image_iff to_nat_on_surj to_nat_on_from_nat_into)
lemma from_nat_into_inj: "countable A \ m \ to_nat_on A ` A \ n \ to_nat_on A ` A \
from_nat_into A m = from_nat_into A n \<longleftrightarrow> m = n" by (subst to_nat_on_inj[symmetric, of A]) auto
lemma from_nat_into_inj_infinite[simp]: "countable A \ infinite A \ from_nat_into A m = from_nat_into A n \ m = n" using image_to_nat_on[of A] from_nat_into_inj[of A m n] by simp
lemma eq_from_nat_into_iff: "countable A \ x \ A \ i \ to_nat_on A ` A \ x = from_nat_into A i \ i = to_nat_on A x" by auto
lemma from_nat_into_surj: "countable A \ a \ A \ \n. from_nat_into A n = a" by (rule exI[of _ "to_nat_on A a"]) simp
lemma from_nat_into_inject[simp]: "A \ {} \ countable A \ B \ {} \ countable B \ from_nat_into A = from_nat_into B \ A = B" by (metis range_from_nat_into)
lemma inj_on_from_nat_into: "inj_on from_nat_into ({A. A \ {} \ countable A})" unfolding inj_on_def by auto
subsection \<open>Closure properties of countability\<close>
lemma countable_SIGMA[intro, simp]: "countable I \ (\i. i \ I \ countable (A i)) \ countable (SIGMA i : I. A i)" by (intro countableI'[of "\(i, a). (to_nat_on I i, to_nat_on (A i) a)"]) (auto simp: inj_on_def)
lemma countable_image[intro, simp]: assumes"countable A" shows"countable (f`A)" proof - obtain g :: "'a \ nat" where "inj_on g A" using assms by (rule countableE) moreoverhave"inj_on (inv_into A f) (f`A)""inv_into A f ` f ` A \ A" by (auto intro: inj_on_inv_into inv_into_into) ultimatelyshow ?thesis by (blast dest: comp_inj_on inj_on_subset intro: countableI) qed
lemma countable_image_inj_on: "countable (f ` A) \ inj_on f A \ countable A" by (metis countable_image the_inv_into_onto)
lemma countable_image_inj_Int_vimage: "\inj_on f S; countable A\ \ countable (S \ f -` A)" by (meson countable_image_inj_on countable_subset image_subset_iff_subset_vimage inf_le2 inj_on_Int)
lemma countable_image_inj_gen: "\inj_on f S; countable A\ \ countable {x \ S. f x \ A}" using countable_image_inj_Int_vimage by (auto simp: vimage_def Collect_conj_eq)
lemma countable_image_inj_eq: "inj_on f S \ countable(f ` S) \ countable S" using countable_image_inj_on by blast
lemma countable_image_inj: "\countable A; inj f\ \ countable {x. f x \ A}" by (metis (mono_tags, lifting) countable_image_inj_eq countable_subset image_Collect_subsetI inj_on_inverseI the_inv_f_f)
lemma countable_UN[intro, simp]: fixes I :: "'i set"and A :: "'i => 'a set" assumes I: "countable I" assumes A: "\i. i \ I \ countable (A i)" shows"countable (\i\I. A i)" proof - have"(\i\I. A i) = snd ` (SIGMA i : I. A i)" by (auto simp: image_iff) thenshow ?thesis by (simp add: assms) qed
lemma countable_Un[intro]: "countable A \ countable B \ countable (A \ B)" by (rule countable_UN[of "{True, False}""\True \ A | False \ B", simplified])
(simp split: bool.split)
lemma countable_Un_iff[simp]: "countable (A \ B) \ countable A \ countable B" by (metis countable_Un countable_subset inf_sup_ord(3,4))
lemma countable_Plus[intro, simp]: "countable A \ countable B \ countable (A <+> B)" by (simp add: Plus_def)
lemma countable_empty[intro, simp]: "countable {}" by (blast intro: countable_finite)
lemma countable_insert[intro, simp]: "countable A \ countable (insert a A)" using countable_Un[of "{a}" A] by (auto simp: countable_finite)
lemma countable_Int1[intro, simp]: "countable A \ countable (A \ B)" by (force intro: countable_subset)
lemma countable_Int2[intro, simp]: "countable B \ countable (A \ B)" by (blast intro: countable_subset)
lemma countable_INT[intro, simp]: "i \ I \ countable (A i) \ countable (\i\I. A i)" by (blast intro: countable_subset)
lemma countable_Diff[intro, simp]: "countable A \ countable (A - B)" by (blast intro: countable_subset)
lemma countable_insert_eq [simp]: "countable (insert x A) = countable A" by auto (metis Diff_insert_absorb countable_Diff insert_absorb)
lemma countable_vimage: "B \ range f \ countable (f -` B) \ countable B" by (metis Int_absorb2 countable_image image_vimage_eq)
lemma surj_countable_vimage: "surj f \ countable (f -` B) \ countable B" by (metis countable_vimage top_greatest)
lemma countable_Collect[simp]: "countable A \ countable {a \ A. \ a}" by (metis Collect_conj_eq Int_absorb Int_commute Int_def countable_Int1)
lemma countable_Image: assumes"\y. y \ Y \ countable (X `` {y})" assumes"countable Y" shows"countable (X `` Y)" proof - have"countable (X `` (\y\Y. {y}))" unfolding Image_UN by (intro countable_UN assms) thenshow ?thesis by simp qed
lemma countable_relpow: fixes X :: "'a rel" assumes Image_X: "\Y. countable Y \ countable (X `` Y)" assumes Y: "countable Y" shows"countable ((X ^^ i) `` Y)" using Y by (induct i arbitrary: Y) (auto simp: relcomp_Image Image_X)
lemma countable_funpow: fixes f :: "'a set \ 'a set" assumes"\A. countable A \ countable (f A)" and"countable A" shows"countable ((f ^^ n) A)" by(induction n)(simp_all add: assms)
lemma countable_rtrancl: "(\Y. countable Y \ countable (X `` Y)) \ countable Y \ countable (X\<^sup>* `` Y)" unfolding rtrancl_is_UN_relpow UN_Image by (intro countable_UN countableI_type countable_relpow)
lemma countable_lists[intro, simp]: assumes A: "countable A"shows"countable (lists A)" proof - have"countable (lists (range (from_nat_into A)))" by (auto simp: lists_image) with A show ?thesis by (auto dest: subset_range_from_nat_into countable_subset lists_mono) qed
lemma Collect_finite_eq_lists: "Collect finite = set ` lists UNIV" using finite_list by auto
lemma countable_Collect_finite: "countable (Collect (finite::'a::countable set\bool))" by (simp add: Collect_finite_eq_lists)
lemma countable_int: "countable \" unfolding Ints_def by auto
lemma countable_rat: "countable \" unfolding Rats_def by auto
lemma Collect_finite_subset_eq_lists: "{A. finite A \ A \ T} = set ` lists T" using finite_list by (auto simp: lists_eq_set)
lemma countable_Collect_finite_subset: "countable T \ countable {A. finite A \ A \ T}" unfolding Collect_finite_subset_eq_lists by auto
lemma countable_Fpow: "countable S \ countable (Fpow S)" using countable_Collect_finite_subset by (force simp add: Fpow_def conj_commute)
lemma countable_set_option [simp]: "countable (set_option x)" by (cases x) auto
subsection \<open>Misc lemmas\<close>
lemma countable_subset_image: "countable B \ B \ (f ` A) \ (\A'. countable A' \ A' \ A \ (B = f ` A'))"
(is"?lhs = ?rhs") proof assume ?lhs show ?rhs by (rule exI [where x="inv_into A f ` B"])
(use\<open>?lhs\<close> in \<open>auto simp: f_inv_into_f subset_iff image_inv_into_cancel inv_into_into\<close>) next assume ?rhs thenshow ?lhs by force qed
lemma ex_subset_image_inj: "(\T. T \ f ` S \ P T) \ (\T. T \ S \ inj_on f T \ P (f ` T))" by (auto simp: subset_image_inj)
lemma all_subset_image_inj: "(\T. T \ f ` S \ P T) \ (\T. T \ S \ inj_on f T \ P(f ` T))" by (metis subset_image_inj)
lemma ex_countable_subset_image_inj: "(\T. countable T \ T \ f ` S \ P T) \
(\<exists>T. countable T \<and> T \<subseteq> S \<and> inj_on f T \<and> P (f ` T))" by (metis countable_image_inj_eq subset_image_inj)
lemma all_countable_subset_image_inj: "(\T. countable T \ T \ f ` S \ P T) \ (\T. countable T \ T \ S \ inj_on f T \P(f ` T))" by (metis countable_image_inj_eq subset_image_inj)
lemma ex_countable_subset_image: "(\T. countable T \ T \ f ` S \ P T) \ (\T. countable T \ T \ S \ P (f ` T))" by (metis countable_subset_image)
lemma all_countable_subset_image: "(\T. countable T \ T \ f ` S \ P T) \ (\T. countable T \ T \ S \ P(f ` T))" by (metis countable_subset_image)
lemma countable_image_eq: "countable(f ` S) \ (\T. countable T \ T \ S \ f ` S = f ` T)" by (metis countable_image countable_image_inj_eq order_refl subset_image_inj)
lemma countable_image_eq_inj: "countable(f ` S) \ (\T. countable T \ T \ S \ f ` S = f ` T \ inj_on f T)" by (metis countable_image_inj_eq order_refl subset_image_inj)
lemma infinite_countable_subset': assumes X: "infinite X"shows"\C\X. countable C \ infinite C" proof - obtain f :: "nat \ 'a" where "inj f" "range f \ X" using infinite_countable_subset [OF X] by blast thenshow ?thesis by (intro exI[of _ "range f"]) (auto simp: range_inj_infinite) qed
lemma countable_all: assumes S: "countable S" shows"(\s\S. P s) \ (\n::nat. from_nat_into S n \ S \ P (from_nat_into S n))" using S[THEN subset_range_from_nat_into] by auto
lemma finite_sequence_to_countable_set: assumes"countable X" obtains F where"\i. F i \ X" "\i. F i \ F (Suc i)" "\i. finite (F i)" "(\i. F i) = X" proof - show thesis apply (rule that[of "\i. if X = {} then {} else from_nat_into X ` {..i}"]) apply (auto simp add: image_iff intro: from_nat_into split: if_splits) using assms from_nat_into_surj by (fastforce cong: image_cong) qed
lemma transfer_countable[transfer_rule]: "bi_unique R \ rel_fun (rel_set R) (=) countable countable" by (rule rel_funI, erule (1) bi_unique_rel_set_lemma)
(auto dest: countable_image_inj_on)
subsection \<open>Uncountable\<close>
abbreviation uncountable where "uncountable A \ \ countable A"
lemma uncountable_def: "uncountable A \ A \ {} \ \ (\f::(nat \ 'a). range f = A)" by (auto intro: inj_on_inv_into simp: countable_def)
(metis all_not_in_conv inj_on_iff_surj subset_UNIV)
lemma uncountable_bij_betw: "bij_betw f A B \ uncountable B \ uncountable A" unfolding bij_betw_def by (metis countable_image)
lemma uncountable_infinite: "uncountable A \ infinite A" by (metis countable_finite)
lemma uncountable_minus_countable: "uncountable A \ countable B \ uncountable (A - B)" using countable_Un[of B "A - B"] by auto
lemma countable_Diff_eq [simp]: "countable (A - {x}) = countable A" by (meson countable_Diff countable_empty countable_insert uncountable_minus_countable)
text\<open>Every infinite set can be covered by a pairwise disjoint family of infinite sets.
This version doesn't achieve equality, as it only covers a countable subset\ lemma infinite_infinite_partition: assumes"infinite A" obtains C :: "nat \ 'a set" where"pairwise (\i j. disjnt (C i) (C j)) UNIV" "(\i. C i) \ A" "\i. infinite (C i)" proof - obtain f :: "nat\'a" where "range f \ A" "inj f" using assms infinite_countable_subset by blast let ?C = "\i. range (\j. f (prod_encode (i,j)))" show thesis proof show"pairwise (\i j. disjnt (?C i) (?C j)) UNIV" by (auto simp: pairwise_def disjnt_def inj_on_eq_iff [OF \<open>inj f\<close>] inj_on_eq_iff [OF inj_prod_encode, of _ UNIV]) show"(\i. ?C i) \ A" using\<open>range f \<subseteq> A\<close> by blast have"infinite (range (\j. f (prod_encode (i, j))))" for i by (rule range_inj_infinite) (meson Pair_inject \<open>inj f\<close> inj_def prod_encode_eq) thenshow"\i. infinite (?C i)" using that by auto qed qed
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.