Theory Card_Multisets.Card_Multisets
section ‹Cardinality of Multisets›
theory Card_Multisets
imports
"HOL-Library.Multiset"
begin
subsection ‹Additions to Multiset Theory›
lemma mset_set_set_mset_subseteq:
"mset_set (set_mset M) ⊆# M"
proof (induct M)
case empty
show ?case by simp
next
case (add x M)
from this show ?case
proof (cases "x ∈# M")
assume "x ∈# M"
from this have "mset_set (set_mset (M + {#x#})) = mset_set (set_mset M)"
by (simp add: insert_absorb)
from this add.hyps show ?thesis
using subset_mset.trans by fastforce
next
assume "¬ x ∈# M"
from this add.hyps have "{#x#} + mset_set (set_mset M) ⊆# M + {#x#}"
by (simp add: insert_subset_eq_iff)
from this ‹¬ x ∈# M› show ?thesis by simp
qed
qed
lemma size_mset_set_eq_card:
assumes "finite A"
shows "size (mset_set A) = card A"
using assms by (induct A) auto
lemma card_set_mset_leq:
"card (set_mset M) ≤ size M"
by (induct M) (auto simp add: card_insert_le_m1)
subsection ‹Lemma to Enumerate Sets of Multisets›
lemma set_of_multisets_eq:
assumes "x ∉ A"
shows "{M. set_mset M ⊆ insert x A ∧ size M = Suc k} =
{M. set_mset M ⊆ A ∧ size M = Suc k} ∪
(λM. M + {#x#}) ` {M. set_mset M ⊆ insert x A ∧ size M = k}"
proof -
from ‹x ∉ A› have "{M. set_mset M ⊆ insert x A ∧ size M = Suc k} =
{M. set_mset M ⊆ A ∧ size M = Suc k} ∪
{M. set_mset M ⊆ insert x A ∧ size M = Suc k ∧ x ∈# M}"
by auto
moreover have "{M. set_mset M ⊆ insert x A ∧ size M = Suc k ∧ x ∈# M} =
(λM. M + {#x#}) ` {M. set_mset M ⊆ insert x A ∧ size M = k}" (is "?S = ?T")
proof
show "?S ⊆ ?T"
proof
fix M
assume "M ∈ ?S"
from this have "M = M - {#x#} + {#x#}" by auto
moreover have "M - {#x#} ∈ {M. set_mset M ⊆ insert x A ∧ size M = k}"
proof -
have "set_mset (M - {#x#} + {#x#}) ⊆ insert x A"
using ‹M ∈ ?S› by force
moreover have "size (M - {#x#} + {#x#}) = Suc k ∧ x ∈# M - {#x#} + {#x#}"
using ‹M ∈ ?S› by force
ultimately show ?thesis by force
qed
ultimately show "M ∈ ?T" by auto
qed
next
show "?T ⊆ ?S" by force
qed
ultimately show ?thesis by auto
qed
subsection ‹Derivation of Suitable Induction Rule›
context
begin
private inductive R :: "'a set ⇒ nat ⇒ bool"
where
"finite A ⟹ R A 0"
| "R {} k"
| "finite A ⟹ x ∉ A ⟹ R A (Suc k) ⟹ R (insert x A) k ⟹ R (insert x A) (Suc k)"
private lemma R_eq_finite:
"R A k ⟷ finite A"
proof
assume "R A k"
from this show "finite A" by cases auto
next
assume "finite A"
from this show "R A k"
proof (induct A)
case empty
from this show ?case by (rule R.intros(2))
next
case insert
from this show ?case
proof (induct k)
case 0
from this show ?case
by (intro R.intros(1) finite.insertI)
next
case Suc
from this show ?case
by (metis R.simps Zero_neq_Suc diff_Suc_1)
qed
qed
qed
lemma finite_set_and_nat_induct[consumes 1, case_names zero empty step]:
assumes "finite A"
assumes "⋀A. finite A ⟹ P A 0"
assumes "⋀k. P {} k"
assumes "⋀A k x. finite A ⟹ x ∉ A ⟹ P A (Suc k) ⟹ P (insert x A) k ⟹ P (insert x A) (Suc k)"
shows "P A k"
proof -
from ‹finite A› have "R A k" by (subst R_eq_finite)
from this assms(2-4) show ?thesis by (induct A k) auto
qed
end
subsection ‹Finiteness of Sets of Multisets›
lemma finite_multisets:
assumes "finite A"
shows "finite {M. set_mset M ⊆ A ∧ size M = k}"
using assms
proof (induct A k rule: finite_set_and_nat_induct)
case zero
from this show ?case by auto
next
case empty
from this show ?case by auto
next
case (step A k x)
from this show ?case
using set_of_multisets_eq[OF ‹x ∉ A›] by simp
qed
subsection ‹Cardinality of Multisets›
lemma card_multisets:
assumes "finite A"
shows "card {M. set_mset M ⊆ A ∧ size M = k} = (card A + k - 1) choose k"
using assms
proof (induct A k rule: finite_set_and_nat_induct)
case (zero A)
assume "finite (A :: 'a set)"
have "{M. set_mset M ⊆ A ∧ size M = 0} = {{#}}" by auto
from this show "card {M. set_mset M ⊆ A ∧ size M = 0} = card A + 0 - 1 choose 0"
by simp
next
case (empty k)
show "card {M. set_mset M ⊆ {} ∧ size M = k} = card {} + k - 1 choose k"
by (cases k) (auto simp add: binomial_eq_0)
next
case (step A k x)
let ?S⇩1 = "{M. set_mset M ⊆ A ∧ size M = Suc k}"
and ?S⇩2 = "{M. set_mset M ⊆ insert x A ∧ size M = k}"
assume hyps1: "card ?S⇩1 = card A + Suc k - 1 choose Suc k"
assume hyps2: "card ?S⇩2 = card (insert x A) + k - 1 choose k"
have finite_sets: "finite ?S⇩1" "finite ((λM. M + {#x#}) ` ?S⇩2)"
using ‹finite A› by (auto simp add: finite_multisets)
have inj: "inj_on (λM. M + {#x#}) ?S⇩2" by (rule inj_onI) auto
have "card {M. set_mset M ⊆ insert x A ∧ size M = Suc k} =
card (?S⇩1 ∪ (λM. M + {#x#}) ` ?S⇩2)"
using set_of_multisets_eq ‹x ∉ A› by fastforce
also have "… = card ?S⇩1 + card ((λM. M + {#x#}) ` ?S⇩2)"
using finite_sets ‹x ∉ A› by (subst card_Un_disjoint) auto
also have "… = card ?S⇩1 + card ?S⇩2"
using inj by (auto intro: card_image)
also have "… = (card A + Suc k - 1 choose Suc k) + (card (insert x A) + k - 1 choose k)"
using hyps1 hyps2 by simp
also have "… = card (insert x A) + Suc k - 1 choose Suc k"
using ‹x ∉ A› ‹finite A› by simp
finally show ?case .
qed
lemma card_too_small_multisets_covering_set:
assumes "finite A"
assumes "k < card A"
shows "card {M. set_mset M = A ∧ size M = k} = 0"
proof -
from ‹k < card A› have eq: "{M. set_mset M = A ∧ size M = k} = {}"
using card_set_mset_leq Collect_empty_eq leD by auto
from this show ?thesis by (metis card.empty)
qed
lemma card_multisets_covering_set:
assumes "finite A"
assumes "card A ≤ k"
shows "card {M. set_mset M = A ∧ size M = k} = (k - 1) choose (k - card A)"
proof -
have "{M. set_mset M = A ∧ size M = k} = (λM. M + mset_set A) `
{M. set_mset M ⊆ A ∧ size M = k - card A}" (is "?S = ?f ` ?T")
proof
show "?S ⊆ ?f ` ?T"
proof
fix M
assume "M ∈ ?S"
from this have "M = M - mset_set A + mset_set A"
by (auto simp add: mset_set_set_mset_subseteq subset_mset.diff_add)
moreover from ‹M ∈ ?S› have "M - mset_set A ∈ ?T"
by (auto simp add: mset_set_set_mset_subseteq size_Diff_submset size_mset_set_eq_card in_diffD)
ultimately show "M ∈ ?f ` ?T" by auto
qed
next
from ‹finite A› ‹card A ≤ k› show "?f ` ?T ⊆ ?S"
by (auto simp add: size_mset_set_eq_card)+
qed
moreover have "inj_on ?f ?T" by (rule inj_onI) auto
ultimately have "card ?S = card ?T" by (simp add: card_image)
also have "… = card A + (k - card A) - 1 choose (k - card A)"
using ‹finite A› by (simp only: card_multisets)
also have "… = (k - 1) choose (k - card A)"
using ‹card A ≤ k› by auto
finally show ?thesis .
qed
end