Theory InfiniteSet2
section ‹Set operations with results of type enat›
theory InfiniteSet2
imports SetInterval2
begin
subsection ‹Set operations with @{typ enat}›
subsubsection ‹Basic definitions›
definition icard :: "'a set ⇒ enat"
where "icard A ≡ if finite A then enat (card A) else ∞"
subsection ‹Results for ‹icard››
lemma icard_UNIV_nat: "icard (UNIV::nat set) = ∞"
by (simp add: icard_def)
lemma icard_finite_conv: "(icard A = enat (card A)) = finite A"
by (case_tac "finite A", simp_all add: icard_def)
lemma icard_infinite_conv: "(icard A = ∞) = infinite A"
by (case_tac "finite A", simp_all add: icard_def)
corollary icard_finite: "finite A ⟹ icard A = enat (card A)"
by (rule icard_finite_conv[THEN iffD2])
corollary icard_infinite[simp]: "infinite A ⟹ icard A = ∞"
by (rule icard_infinite_conv[THEN iffD2])
lemma icard_eq_enat_imp: "icard A = enat n ⟹ finite A"
by (case_tac "finite A", simp_all)
lemma icard_eq_Infty_imp: "icard A = ∞ ⟹ infinite A"
by (rule icard_infinite_conv[THEN iffD1])
lemma icard_the_enat: "finite A ⟹ the_enat (icard A) = card A"
by (simp add: icard_def)
lemma icard_eq_enat_imp_card: "icard A = enat n ⟹ card A = n"
by (frule icard_eq_enat_imp, simp add: icard_finite)
lemma icard_eq_enat_card_conv: "0 < n ⟹ (icard A = enat n) = (card A = n)"
apply (rule iffI)
apply (simp add: icard_eq_enat_imp_card)
apply (drule sym, simp)
apply (frule card_gr0_imp_finite)
apply (rule icard_finite, assumption)
done
lemma icard_empty[simp]: "icard {} = 0"
by (simp add: icard_finite[OF finite.emptyI])
lemma icard_empty_iff: "(icard A = 0) = (A = {})"
apply (unfold zero_enat_def)
apply (rule iffI)
apply (frule icard_eq_enat_imp)
apply (simp add: icard_finite)
apply simp
done
lemmas icard_empty_iff_enat = icard_empty_iff[unfolded zero_enat_def]
lemma icard_not_empty_iff: "(0 < icard A) = (A ≠ {})"
by (simp add: icard_empty_iff[symmetric])
lemmas icard_not_empty_iff_enat = icard_not_empty_iff[unfolded zero_enat_def]
lemma icard_singleton: "icard {a} = eSuc 0"
by (simp add: icard_finite eSuc_enat)
lemmas icard_singleton_enat[simp] = icard_singleton[unfolded zero_enat_def]
lemma icard_1_imp_singleton: "icard A = eSuc 0 ⟹ ∃a. A = {a}"
apply (simp add: eSuc_enat)
apply (frule icard_eq_enat_imp)
apply (simp add: icard_finite card_1_imp_singleton)
done
lemma icard_1_singleton_conv: "(icard A = eSuc 0) = (∃a. A = {a})"
apply (rule iffI)
apply (simp add: icard_1_imp_singleton)
apply fastforce
done
lemma icard_insert_disjoint: "x ∉ A ⟹ icard (insert x A) = eSuc (icard A)"
apply (case_tac "finite A")
apply (simp add: icard_finite eSuc_enat card_insert_disjoint)
apply (simp add: infinite_insert)
done
lemma icard_insert_if: "icard (insert x A) = (if x ∈ A then icard A else eSuc (icard A))"
apply (case_tac "x ∈ A")
apply (simp add: insert_absorb)
apply (simp add: icard_insert_disjoint)
done
lemmas icard_0_eq = icard_empty_iff
lemma icard_Suc_Diff1: "x ∈ A ⟹ eSuc (icard (A - {x})) = icard A"
apply (case_tac "finite A")
apply (simp add: icard_finite eSuc_enat in_imp_not_empty not_empty_card_gr0_conv[THEN iffD1])
apply (simp add: Diff_infinite_finite[OF singleton_finite])
done
lemma icard_Diff_singleton: "x ∈ A ⟹ icard (A - {x}) = icard A - 1"
apply (rule eSuc_inject[THEN iffD1])
apply (frule in_imp_not_empty, drule icard_not_empty_iff[THEN iffD2])
apply (simp add: icard_Suc_Diff1 eSuc_pred_enat one_eSuc)
done
lemma icard_Diff_singleton_if: "icard (A - {x}) = (if x ∈ A then icard A - 1 else icard A)"
by (simp add: icard_Diff_singleton)
lemma icard_insert: "icard (insert x A) = eSuc (icard (A - {x}))"
by (metis icard_Diff_singleton_if icard_Suc_Diff1 icard_insert_disjoint insert_absorb)
lemma icard_insert_le: "icard A ≤ icard (insert x A)"
by (simp add: icard_insert_if)
lemma icard_mono: "A ⊆ B ⟹ icard A ≤ icard B"
apply (case_tac "finite B")
apply (frule subset_finite_imp_finite, simp)
apply (simp add: icard_finite card_mono)
apply simp
done
lemma not_icard_seteq: "∃(A::nat set) B. (A ⊆ B ∧ icard B ≤ icard A ∧ ¬ A = B)"
apply (rule_tac x="{1..}" in exI)
apply (rule_tac x="{0..}" in exI)
apply (fastforce simp add: infinite_atLeast)
done
lemma not_psubset_icard_mono: "∃(A::nat set) B. A ⊂ B ∧ ¬ icard A < icard B"
apply (rule_tac x="{1..}" in exI)
apply (rule_tac x="{0..}" in exI)
apply (fastforce simp add: infinite_atLeast)
done
lemma icard_Un_Int: "icard A + icard B = icard (A ∪ B) + icard (A ∩ B)"
apply (case_tac "finite A", case_tac "finite B")
apply (simp add: icard_finite card_Un_Int[of A])
apply simp_all
done
lemma icard_Un_disjoint: "A ∩ B = {} ⟹ icard (A ∪ B) = icard A + icard B"
by (simp add: icard_Un_Int[of A])
lemma not_icard_Diff_subset: "∃(A::nat set) B. B ⊆ A ∧ ¬ icard (A - B) = icard A - icard B"
apply (rule_tac x="{0..}" in exI)
apply (rule_tac x="{1..}" in exI)
apply (simp add: set_diff_eq linorder_not_le icard_UNIV_nat eSuc_enat)
done
lemma not_icard_Diff1_less: "∃(A::nat set)x. x ∈ A ∧ ¬ icard (A - {x}) < icard A"
by (rule_tac x="{0..}" in exI, simp)
lemma not_icard_Diff2_less: "∃(A::nat set)x y. x ∈ A ∧ y ∈ A ∧ ¬ icard (A - {x} - {y}) < icard A"
by (rule_tac x="{0..}" in exI, simp)
lemma icard_Diff1_le: "icard (A - {x}) ≤ icard A"
by (rule icard_mono, rule Diff_subset)
lemma icard_psubset: "⟦ A ⊆ B; icard A < icard B ⟧ ⟹ A ⊂ B"
by (metis less_le psubset_eq)
lemma icard_partition: "
⟦ ⋀c. c ∈ C ⟹ icard c = k; ⋀c1 c2. ⟦c1 ∈ C; c2 ∈ C; c1 ≠ c2⟧ ⟹ c1 ∩ c2 = {} ⟧ ⟹
icard (⋃C) = k * icard C"
apply (case_tac "C = {}", simp)
apply (case_tac "k = 0")
apply (simp add: icard_empty_iff_enat)
apply simp
apply (case_tac k, rename_tac k1)
apply (subgoal_tac "0 < k1")
prefer 2
apply simp
apply (case_tac "finite C")
apply (simp add: icard_finite)
apply (subgoal_tac "⋀c. c ∈ C ⟹ card c = k1")
prefer 2
apply (rule icard_eq_enat_imp_card, simp)
apply (frule_tac C=C and k=k1 in SetInterval2.card_partition, simp+)
apply (subgoal_tac "finite (⋃C)")
prefer 2
apply (rule card_gr0_imp_finite)
apply (simp add: not_empty_card_gr0_conv)
apply (simp add: icard_finite)
apply simp
apply (rule icard_infinite)
apply (rule ccontr, simp)
apply (drule finite_UnionD, simp)
apply (frule icard_not_empty_iff[THEN iffD2])
apply (simp add: icard_infinite_conv)
apply (frule not_empty_imp_ex, erule exE, rename_tac c)
apply (frule Union_upper)
apply (rule infinite_super, assumption)
apply simp
done
lemma icard_image_le: "icard (f ` A) ≤ icard A"
apply (case_tac "finite A")
apply (simp add: icard_finite card_image_le)
apply simp
done
lemma icard_image: "inj_on f A ⟹ icard (f ` A) = icard A"
apply (case_tac "finite A")
apply (simp add: icard_finite card_image)
apply (simp add: icard_infinite_conv inj_on_imp_infinite_image)
done
lemma not_eq_icard_imp_inj_on: "∃(f::nat⇒nat) (A::nat set). icard (f ` A) = icard A ∧ ¬ inj_on f A"
apply (rule_tac x="λn. (if n = 0 then Suc 0 else n)" in exI)
apply (rule_tac x="{0..}" in exI)
apply (rule conjI)
apply (rule subst[of "{1..}" "((λn. if n = 0 then Suc 0 else n) ` {0..})"])
apply (simp add: set_eq_iff)
apply (rule allI, rename_tac n)
apply (case_tac "n = 0", simp)
apply simp
apply (simp only: icard_infinite[OF infinite_atLeast])
apply (simp add: inj_on_def)
apply blast
done
lemma not_inj_on_iff_eq_icard: "∃(f::nat⇒nat) (A::nat set). ¬ (inj_on f A = (icard (f ` A) = icard A))"
by (insert not_eq_icard_imp_inj_on, blast)
lemma icard_inj_on_le: "⟦ inj_on f A; f ` A ⊆ B ⟧ ⟹ icard A ≤ icard B"
apply (case_tac "finite B")
apply (metis icard_image icard_mono)
apply simp
done
lemma icard_bij_eq: "
⟦ inj_on f A; f ` A ⊆ B; inj_on g B; g ` B ⊆ A ⟧ ⟹
icard A = icard B"
by (simp add: order_eq_iff icard_inj_on_le)
lemma icard_cartesian_product: "icard (A × B) = icard A * icard B"
apply (case_tac "A = {} ∨ B = {}", fastforce)
apply clarsimp
apply (case_tac "finite A ∧ finite B")
apply (simp add: icard_finite)
apply (simp only: de_Morgan_conj, erule disjE)
apply (simp_all add:
icard_not_empty_iff[symmetric]
cartesian_product_infiniteL_imp_infinite cartesian_product_infiniteR_imp_infinite)
done
lemma icard_cartesian_product_singleton: "icard ({x} × A) = icard A"
by (simp add: icard_cartesian_product mult_eSuc)
lemma icard_cartesian_product_singleton_right: "icard (A × {x}) = icard A"
by (simp add: icard_cartesian_product mult_eSuc_right)
lemma
icard_lessThan: "icard {..<u} = enat u" and
icard_atMost: "icard {..u} = enat (Suc u)" and
icard_atLeastLessThan: "icard {l..<u} = enat (u - l)" and
icard_atLeastAtMost: "icard {l..u} = enat (Suc u - l)" and
icard_greaterThanAtMost: "icard {l<..u} = enat (u - l)" and
icard_greaterThanLessThan: "icard {l<..<u} = enat (u - Suc l)"
by (simp_all add: icard_finite)
lemma icard_atLeast: "icard {(u::nat)..} = ∞"
by (simp add: infinite_atLeast)
lemma icard_greaterThan: "icard {(u::nat)<..} = ∞"
by (simp add: infinite_greaterThan)
lemma
icard_atLeastZeroLessThan_int: "icard {0..<u} = enat (nat u)" and
icard_atLeastLessThan_int: "icard {l..<u} = enat (nat (u - l))" and
icard_atLeastAtMost_int: "icard {l..u} = enat (nat (u - l + 1))" and
icard_greaterThanAtMost_int: "icard {l<..u} = enat (nat (u - l))"
by (simp_all add: icard_finite)
lemma icard_atLeast_int: "icard {(u::int)..} = ∞"
by (simp add: infinite_atLeast_int)
lemma icard_greaterThan_int: "icard {(u::int)<..} = ∞"
by (simp add: infinite_greaterThan_int)
lemma icard_atMost_int: "icard {..(u::int)} = ∞"
by (simp add: infinite_atMost_int)
lemma icard_lessThan_int: "icard {..<(u::int)} = ∞"
by (simp add: infinite_lessThan_int)
end