src/HOL/Library/Multiset.thy
changeset 64076 9f089287687b
parent 64075 3d4c3eec5143
child 64077 6d770c2dc60d
equal deleted inserted replaced
64075:3d4c3eec5143 64076:9f089287687b
   520   supseteq_mset  (infix ">=#" 50) and
   520   supseteq_mset  (infix ">=#" 50) and
   521   supset_mset  (infix ">#" 50)
   521   supset_mset  (infix ">#" 50)
   522 
   522 
   523 interpretation subset_mset: ordered_ab_semigroup_add_imp_le "op +" "op -" "op \<subseteq>#" "op \<subset>#"
   523 interpretation subset_mset: ordered_ab_semigroup_add_imp_le "op +" "op -" "op \<subseteq>#" "op \<subset>#"
   524   by standard (auto simp add: subset_mset_def subseteq_mset_def multiset_eq_iff intro: order_trans antisym)
   524   by standard (auto simp add: subset_mset_def subseteq_mset_def multiset_eq_iff intro: order_trans antisym)
   525   \<comment> \<open>FIXME: avoid junk stemming from type class interpretation\<close>
       
   526 
   525 
   527 interpretation subset_mset: ordered_ab_semigroup_monoid_add_imp_le "op +" 0 "op -" "op \<le>#" "op <#"
   526 interpretation subset_mset: ordered_ab_semigroup_monoid_add_imp_le "op +" 0 "op -" "op \<le>#" "op <#"
   528   by standard
   527   by standard
   529 
   528 
   530 lemma mset_subset_eqI:
   529 lemma mset_subset_eqI:
   642 
   641 
   643 lemma subset_eq_diff_conv:
   642 lemma subset_eq_diff_conv:
   644   "A - C \<subseteq># B \<longleftrightarrow> A \<subseteq># B + C"
   643   "A - C \<subseteq># B \<longleftrightarrow> A \<subseteq># B + C"
   645   by (simp add: subseteq_mset_def le_diff_conv)
   644   by (simp add: subseteq_mset_def le_diff_conv)
   646 
   645 
   647 lemma subset_eq_empty[simp]: "M \<subseteq># {#} \<longleftrightarrow> M = {#}"
       
   648   by auto
       
   649 
       
   650 lemma multi_psub_of_add_self [simp]: "A \<subset># add_mset x A"
   646 lemma multi_psub_of_add_self [simp]: "A \<subset># add_mset x A"
   651   by (auto simp: subset_mset_def subseteq_mset_def)
   647   by (auto simp: subset_mset_def subseteq_mset_def)
   652 
   648 
   653 lemma multi_psub_self[simp]: "(A::'a multiset) \<subset># A = False"
   649 lemma multi_psub_self: "A \<subset># A = False"
   654   by simp
   650   by simp
   655 
   651 
   656 lemma mset_subset_add_mset [simp]: "add_mset x N \<subset># add_mset x M \<longleftrightarrow> N \<subset># M"
   652 lemma mset_subset_add_mset [simp]: "add_mset x N \<subset># add_mset x M \<longleftrightarrow> N \<subset># M"
   657   unfolding add_mset_add_single[of _ N] add_mset_add_single[of _ M]
   653   unfolding add_mset_add_single[of _ N] add_mset_add_single[of _ M]
   658   by (fact subset_mset.add_less_cancel_right)
   654   by (fact subset_mset.add_less_cancel_right)
   659 
   655 
   660 lemma mset_subset_empty_nonempty: "{#} \<subset># S \<longleftrightarrow> S \<noteq> {#}"
       
   661   by (fact subset_mset.zero_less_iff_neq_zero)
       
   662 
       
   663 lemma mset_subset_diff_self: "c \<in># B \<Longrightarrow> B - {#c#} \<subset># B"
   656 lemma mset_subset_diff_self: "c \<in># B \<Longrightarrow> B - {#c#} \<subset># B"
   664   by (auto simp: subset_mset_def elim: mset_add)
   657   by (auto simp: subset_mset_def elim: mset_add)
   665 
   658 
   666 
   659 
   667 subsubsection \<open>Intersection\<close>
   660 subsubsection \<open>Intersection and bounded union\<close>
   668 
   661 
   669 definition inf_subset_mset :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset" (infixl "\<inter>#" 70) where
   662 definition inf_subset_mset :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset" (infixl "\<inter>#" 70) where
   670   multiset_inter_def: "inf_subset_mset A B = A - (A - B)"
   663   multiset_inter_def: "inf_subset_mset A B = A - (A - B)"
   671 
   664 
   672 interpretation subset_mset: semilattice_inf inf_subset_mset "op \<subseteq>#" "op \<subset>#"
   665 interpretation subset_mset: semilattice_inf inf_subset_mset "op \<subseteq>#" "op \<subset>#"
   675     by arith
   668     by arith
   676   show "class.semilattice_inf op \<inter># op \<subseteq># op \<subset>#"
   669   show "class.semilattice_inf op \<inter># op \<subseteq># op \<subset>#"
   677     by standard (auto simp add: multiset_inter_def subseteq_mset_def)
   670     by standard (auto simp add: multiset_inter_def subseteq_mset_def)
   678 qed
   671 qed
   679   \<comment> \<open>FIXME: avoid junk stemming from type class interpretation\<close>
   672   \<comment> \<open>FIXME: avoid junk stemming from type class interpretation\<close>
       
   673 
       
   674 definition sup_subset_mset :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset"(infixl "\<union>#" 70)
       
   675   where "sup_subset_mset A B = A + (B - A)" \<comment> \<open>FIXME irregular fact name\<close>
       
   676 
       
   677 interpretation subset_mset: semilattice_sup sup_subset_mset "op \<subseteq>#" "op \<subset>#"
       
   678 proof -
       
   679   have [simp]: "m \<le> n \<Longrightarrow> q \<le> n \<Longrightarrow> m + (q - m) \<le> n" for m n q :: nat
       
   680     by arith
       
   681   show "class.semilattice_sup op \<union># op \<subseteq># op \<subset>#"
       
   682     by standard (auto simp add: sup_subset_mset_def subseteq_mset_def)
       
   683 qed
       
   684   \<comment> \<open>FIXME: avoid junk stemming from type class interpretation\<close>
       
   685 
       
   686 interpretation subset_mset: bounded_lattice_bot "op \<inter>#" "op \<subseteq>#" "op \<subset>#"
       
   687   "op \<union>#" "{#}"
       
   688   by standard auto
       
   689 
       
   690 
       
   691 subsubsection \<open>Additional intersection facts\<close>
   680 
   692 
   681 lemma multiset_inter_count [simp]:
   693 lemma multiset_inter_count [simp]:
   682   fixes A B :: "'a multiset"
   694   fixes A B :: "'a multiset"
   683   shows "count (A \<inter># B) x = min (count A x) (count B x)"
   695   shows "count (A \<inter># B) x = min (count A x) (count B x)"
   684   by (simp add: multiset_inter_def)
   696   by (simp add: multiset_inter_def)
   750 lemma disjoint_add_mset [simp]:
   762 lemma disjoint_add_mset [simp]:
   751   "B \<inter># add_mset a A = {#} \<longleftrightarrow> a \<notin># B \<and> B \<inter># A = {#}"
   763   "B \<inter># add_mset a A = {#} \<longleftrightarrow> a \<notin># B \<and> B \<inter># A = {#}"
   752   "{#} = A \<inter># add_mset b B \<longleftrightarrow> b \<notin># A \<and> {#} = A \<inter># B"
   764   "{#} = A \<inter># add_mset b B \<longleftrightarrow> b \<notin># A \<and> {#} = A \<inter># B"
   753   by (auto simp: disjunct_not_in)
   765   by (auto simp: disjunct_not_in)
   754 
   766 
   755 lemma empty_inter[simp]: "{#} \<inter># M = {#}"
       
   756   by (simp add: multiset_eq_iff)
       
   757 
       
   758 lemma inter_empty[simp]: "M \<inter># {#} = {#}"
       
   759   by (simp add: multiset_eq_iff)
       
   760 
       
   761 lemma inter_add_left1: "\<not> x \<in># N \<Longrightarrow> (add_mset x M) \<inter># N = M \<inter># N"
   767 lemma inter_add_left1: "\<not> x \<in># N \<Longrightarrow> (add_mset x M) \<inter># N = M \<inter># N"
   762   by (simp add: multiset_eq_iff not_in_iff)
   768   by (simp add: multiset_eq_iff not_in_iff)
   763 
   769 
   764 lemma inter_add_left2: "x \<in># N \<Longrightarrow> (add_mset x M) \<inter># N = add_mset x (M \<inter># (N - {#x#}))"
   770 lemma inter_add_left2: "x \<in># N \<Longrightarrow> (add_mset x M) \<inter># N = add_mset x (M \<inter># (N - {#x#}))"
   765   by (auto simp add: multiset_eq_iff elim: mset_add)
   771   by (auto simp add: multiset_eq_iff elim: mset_add)
   811 lemma inter_subset_eq_union:
   817 lemma inter_subset_eq_union:
   812   "A \<inter># B \<subseteq># A + B"
   818   "A \<inter># B \<subseteq># A + B"
   813   by (auto simp add: subseteq_mset_def)
   819   by (auto simp add: subseteq_mset_def)
   814 
   820 
   815 
   821 
   816 subsubsection \<open>Bounded union\<close>
   822 subsubsection \<open>Additional bounded union facts\<close>
   817 
       
   818 definition sup_subset_mset :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset"(infixl "\<union>#" 70)
       
   819   where "sup_subset_mset A B = A + (B - A)" \<comment> \<open>FIXME irregular fact name\<close>
       
   820 
       
   821 interpretation subset_mset: semilattice_sup sup_subset_mset "op \<subseteq>#" "op \<subset>#"
       
   822 proof -
       
   823   have [simp]: "m \<le> n \<Longrightarrow> q \<le> n \<Longrightarrow> m + (q - m) \<le> n" for m n q :: nat
       
   824     by arith
       
   825   show "class.semilattice_sup op \<union># op \<subseteq># op \<subset>#"
       
   826     by standard (auto simp add: sup_subset_mset_def subseteq_mset_def)
       
   827 qed
       
   828   \<comment> \<open>FIXME: avoid junk stemming from type class interpretation\<close>
       
   829 
       
   830 interpretation subset_mset: bounded_lattice_bot "op \<inter>#" "op \<subseteq>#" "op \<subset>#"
       
   831   "op \<union>#" "{#}"
       
   832   by standard auto
       
   833 
   823 
   834 lemma sup_subset_mset_count [simp]: \<comment> \<open>FIXME irregular fact name\<close>
   824 lemma sup_subset_mset_count [simp]: \<comment> \<open>FIXME irregular fact name\<close>
   835   "count (A \<union># B) x = max (count A x) (count B x)"
   825   "count (A \<union># B) x = max (count A x) (count B x)"
   836   by (simp add: sup_subset_mset_def)
   826   by (simp add: sup_subset_mset_def)
   837 
   827 
   838 lemma set_mset_sup [simp]:
   828 lemma set_mset_sup [simp]:
   839   "set_mset (A \<union># B) = set_mset A \<union> set_mset B"
   829   "set_mset (A \<union># B) = set_mset A \<union> set_mset B"
   840   by (simp only: set_eq_iff count_greater_zero_iff [symmetric] sup_subset_mset_count)
   830   by (simp only: set_eq_iff count_greater_zero_iff [symmetric] sup_subset_mset_count)
   841     (auto simp add: not_in_iff elim: mset_add)
   831     (auto simp add: not_in_iff elim: mset_add)
   842 
   832 
   843 lemma empty_sup: "{#} \<union># M = M"
       
   844   by (fact subset_mset.sup_bot.left_neutral)
       
   845 
       
   846 lemma sup_empty: "M \<union># {#} = M"
       
   847   by (fact subset_mset.sup_bot.right_neutral)
       
   848 
       
   849 lemma sup_union_left1 [simp]: "\<not> x \<in># N \<Longrightarrow> (add_mset x M) \<union># N = add_mset x (M \<union># N)"
   833 lemma sup_union_left1 [simp]: "\<not> x \<in># N \<Longrightarrow> (add_mset x M) \<union># N = add_mset x (M \<union># N)"
   850   by (simp add: multiset_eq_iff not_in_iff)
   834   by (simp add: multiset_eq_iff not_in_iff)
   851 
   835 
   852 lemma sup_union_left2: "x \<in># N \<Longrightarrow> (add_mset x M) \<union># N = add_mset x (M \<union># (N - {#x#}))"
   836 lemma sup_union_left2: "x \<in># N \<Longrightarrow> (add_mset x M) \<union># N = add_mset x (M \<union># (N - {#x#}))"
   853   by (simp add: multiset_eq_iff)
   837   by (simp add: multiset_eq_iff)
   879   by (auto simp: multiset_eq_iff max_def)
   863   by (auto simp: multiset_eq_iff max_def)
   880 
   864 
   881 
   865 
   882 subsubsection \<open>Subset is an order\<close>
   866 subsubsection \<open>Subset is an order\<close>
   883 
   867 
   884 interpretation subset_mset: order "op \<le>#" "op <#" by unfold_locales auto
   868 interpretation subset_mset: order "op \<subseteq>#" "op \<subset>#" by unfold_locales
   885 
   869 
   886 
   870 
   887 subsection \<open>Replicate and repeat operations\<close>
   871 subsection \<open>Replicate and repeat operations\<close>
   888 
   872 
   889 definition replicate_mset :: "nat \<Rightarrow> 'a \<Rightarrow> 'a multiset" where
   873 definition replicate_mset :: "nat \<Rightarrow> 'a \<Rightarrow> 'a multiset" where
  1049 
  1033 
  1050 instance ..
  1034 instance ..
  1051 
  1035 
  1052 end
  1036 end
  1053 
  1037 
  1054 lemma bdd_below_multiset [simp]: "subset_mset.bdd_below A"
       
  1055   by (intro subset_mset.bdd_belowI[of _ "{#}"]) simp_all
       
  1056 
  1038 
  1057 lemma bdd_above_multiset_imp_bdd_above_count:
  1039 lemma bdd_above_multiset_imp_bdd_above_count:
  1058   assumes "subset_mset.bdd_above (A :: 'a multiset set)"
  1040   assumes "subset_mset.bdd_above (A :: 'a multiset set)"
  1059   shows   "bdd_above ((\<lambda>X. count X x) ` A)"
  1041   shows   "bdd_above ((\<lambda>X. count X x) ` A)"
  1060 proof -
  1042 proof -
  1463 done
  1445 done
  1464 
  1446 
  1465 lemma mset_subset_size: "(A::'a multiset) \<subset># B \<Longrightarrow> size A < size B"
  1447 lemma mset_subset_size: "(A::'a multiset) \<subset># B \<Longrightarrow> size A < size B"
  1466 proof (induct A arbitrary: B)
  1448 proof (induct A arbitrary: B)
  1467   case (empty M)
  1449   case (empty M)
  1468   then have "M \<noteq> {#}" by (simp add: mset_subset_empty_nonempty)
  1450   then have "M \<noteq> {#}" by (simp add: subset_mset.zero_less_iff_neq_zero)
  1469   then obtain M' x where "M = add_mset x M'"
  1451   then obtain M' x where "M = add_mset x M'"
  1470     by (blast dest: multi_nonempty_split)
  1452     by (blast dest: multi_nonempty_split)
  1471   then show ?case by simp
  1453   then show ?case by simp
  1472 next
  1454 next
  1473   case (add x S T)
  1455   case (add x S T)
  1748   by (induct x) auto
  1730   by (induct x) auto
  1749 
  1731 
  1750 lemma mset_zero_iff_right[simp]: "({#} = mset x) = (x = [])"
  1732 lemma mset_zero_iff_right[simp]: "({#} = mset x) = (x = [])"
  1751 by (induct x) auto
  1733 by (induct x) auto
  1752 
  1734 
  1753 lemma set_mset_mset[simp]: "set_mset (mset x) = set x"
  1735 lemma set_mset_mset[simp]: "set_mset (mset xs) = set xs"
  1754 by (induct x) auto
  1736   by (induct xs) auto
  1755 
  1737 
  1756 lemma set_mset_comp_mset [simp]: "set_mset \<circ> mset = set"
  1738 lemma set_mset_comp_mset [simp]: "set_mset \<circ> mset = set"
  1757   by (simp add: fun_eq_iff)
  1739   by (simp add: fun_eq_iff)
  1758 
  1740 
  1759 lemma size_mset [simp]: "size (mset xs) = length xs"
  1741 lemma size_mset [simp]: "size (mset xs) = length xs"
  2919 
  2901 
  2920 
  2902 
  2921 subsubsection \<open>Monotonicity of multiset union\<close>
  2903 subsubsection \<open>Monotonicity of multiset union\<close>
  2922 
  2904 
  2923 lemma mult1_union: "(B, D) \<in> mult1 r \<Longrightarrow> (C + B, C + D) \<in> mult1 r"
  2905 lemma mult1_union: "(B, D) \<in> mult1 r \<Longrightarrow> (C + B, C + D) \<in> mult1 r"
  2924 apply (unfold mult1_def)
  2906   by (force simp: mult1_def)
  2925 apply auto
       
  2926 apply (rule_tac x = a in exI)
       
  2927 apply (rule_tac x = "C + M0" in exI)
       
  2928 apply (simp add: add.assoc)
       
  2929 done
       
  2930 
  2907 
  2931 lemma union_le_mono2: "B < D \<Longrightarrow> C + B < C + (D::'a::preorder multiset)"
  2908 lemma union_le_mono2: "B < D \<Longrightarrow> C + B < C + (D::'a::preorder multiset)"
  2932 apply (unfold less_multiset_def mult_def)
  2909 apply (unfold less_multiset_def mult_def)
  2933 apply (erule trancl_induct)
  2910 apply (erule trancl_induct)
  2934  apply (blast intro: mult1_union)
  2911  apply (blast intro: mult1_union)
  3264 lemma subset_eq_mset_impl: "(subset_eq_mset_impl xs ys = None \<longleftrightarrow> \<not> mset xs \<subseteq># mset ys) \<and>
  3241 lemma subset_eq_mset_impl: "(subset_eq_mset_impl xs ys = None \<longleftrightarrow> \<not> mset xs \<subseteq># mset ys) \<and>
  3265   (subset_eq_mset_impl xs ys = Some True \<longleftrightarrow> mset xs \<subset># mset ys) \<and>
  3242   (subset_eq_mset_impl xs ys = Some True \<longleftrightarrow> mset xs \<subset># mset ys) \<and>
  3266   (subset_eq_mset_impl xs ys = Some False \<longrightarrow> mset xs = mset ys)"
  3243   (subset_eq_mset_impl xs ys = Some False \<longrightarrow> mset xs = mset ys)"
  3267 proof (induct xs arbitrary: ys)
  3244 proof (induct xs arbitrary: ys)
  3268   case (Nil ys)
  3245   case (Nil ys)
  3269   show ?case by (auto simp: mset_subset_empty_nonempty)
  3246   show ?case by (auto simp: subset_mset.zero_less_iff_neq_zero)
  3270 next
  3247 next
  3271   case (Cons x xs ys)
  3248   case (Cons x xs ys)
  3272   show ?case
  3249   show ?case
  3273   proof (cases "List.extract (op = x) ys")
  3250   proof (cases "List.extract (op = x) ys")
  3274     case None
  3251     case None