Theory PAPP_Multiset_Extras
section ‹Auxiliary Facts About Multisets›
theory PAPP_Multiset_Extras
  imports "HOL-Library.Multiset"
begin
text ‹
  This section contains a number of not particularly interesting small facts about multisets.
›
lemma : "finite A ⟹ mset_set A ⊆# B ⟷ A ⊆ set_mset B"
  by (metis finite_set_mset finite_set_mset_mset_set mset_set_set_mset_msubset 
            msubset_mset_set_iff set_mset_mono subset_mset.trans)
lemma :
  assumes "A ⊆# B" "size A ≥ size B"
  shows   "A = B"
  using assms
proof (induction A arbitrary: B)
  case empty
  thus ?case by auto
next
  case (add x A B)
  have [simp]: "x ∈# B"
    using add.prems  by (simp add: insert_subset_eq_iff)
  define B' where "B' = B - {#x#}"
  have B_eq: "B = add_mset x B'"
    using add.prems unfolding B'_def by (auto simp: add_mset_remove_trivial_If)
  have "A = B'"
    using add.prems by (intro add.IH) (auto simp: B_eq)
  thus ?case
    by (auto simp: B_eq)
qed
lemma :
  "X ⊂# Y ⟷ X ⊆# Y ∧ (∃x. count X x < count Y x)"
  by (meson less_le_not_le subset_mset.less_le_not_le subseteq_mset_def)
  
lemma : "count A x ≤ size A"
  by (induction A) auto
lemma  [simp]: "size (filter_mset (λy. y = x) A) = count A x"
  by (induction A) auto
lemma :
  assumes "⋀x. x ∈# A ⟹ P x ⟹ Q x"
  shows   "filter_mset P A ⊆# filter_mset Q A"
  using assms by (induction A)  (auto simp: subset_mset.absorb_iff1 add_mset_union)
lemma :
  assumes "A ⊆# B" "⋀x. x ∈# A ⟹ P x ⟹ Q x"
  shows "filter_mset P A ⊆# filter_mset Q B"
  using assms multiset_filter_mono multiset_filter_mono'
  by (metis subset_mset.order_trans)
lemma :
  assumes "⋀x. x ∈# X ⟹ P x ⟹ Q x ⟹ False"
  shows   "filter_mset (λx. P x ∨ Q x) X = filter_mset P X + filter_mset Q X"
  using assms by (induction X) auto
  
lemma : "size (sum_mset X) = (∑x∈#X. size (x :: 'a multiset))"
  by (induction X) auto
lemma : "count (sum_mset X) x = (∑Y∈#X. count Y x)"
  by (induction X) auto
lemma : "n > 0 ⟹ replicate_mset n x = add_mset x (replicate_mset (n - 1) x)"
  by (cases n) auto
lemma : "x ∉# B ⟹ add_mset x A ≠ B"
  by force
lemma :
  "filter_mset P (replicate_mset n x) = (if P x then replicate_mset n x else {#})"
  by (induction n) auto
lemma : "filter_mset P (X - Y) = filter_mset P X - Y"
  by (rule multiset_eqI) auto
lemma : "x ∉# B ⟹ x ∈# A - B ⟷ x ∈# A"
  by (metis count_greater_zero_iff count_inI in_diff_count)
end