src/HOL/Library/Multiset.thy
changeset 17161 57c69627d71a
parent 15869 3aca7f05cd12
child 17200 3a4d03d1a31b
equal deleted inserted replaced
17160:fb65eda72fc7 17161:57c69627d71a
    60 text {*
    60 text {*
    61  \medskip Preservation of the representing set @{term multiset}.
    61  \medskip Preservation of the representing set @{term multiset}.
    62 *}
    62 *}
    63 
    63 
    64 lemma const0_in_multiset [simp]: "(\<lambda>a. 0) \<in> multiset"
    64 lemma const0_in_multiset [simp]: "(\<lambda>a. 0) \<in> multiset"
    65 by (simp add: multiset_def)
    65   by (simp add: multiset_def)
    66 
    66 
    67 lemma only1_in_multiset [simp]: "(\<lambda>b. if b = a then 1 else 0) \<in> multiset"
    67 lemma only1_in_multiset [simp]: "(\<lambda>b. if b = a then 1 else 0) \<in> multiset"
    68 by (simp add: multiset_def)
    68   by (simp add: multiset_def)
    69 
    69 
    70 lemma union_preserves_multiset [simp]:
    70 lemma union_preserves_multiset [simp]:
    71     "M \<in> multiset ==> N \<in> multiset ==> (\<lambda>a. M a + N a) \<in> multiset"
    71     "M \<in> multiset ==> N \<in> multiset ==> (\<lambda>a. M a + N a) \<in> multiset"
    72   apply (unfold multiset_def, simp)
    72   apply (simp add: multiset_def)
    73   apply (drule finite_UnI, assumption)
    73   apply (drule (1) finite_UnI)
    74   apply (simp del: finite_Un add: Un_def)
    74   apply (simp del: finite_Un add: Un_def)
    75   done
    75   done
    76 
    76 
    77 lemma diff_preserves_multiset [simp]:
    77 lemma diff_preserves_multiset [simp]:
    78     "M \<in> multiset ==> (\<lambda>a. M a - N a) \<in> multiset"
    78     "M \<in> multiset ==> (\<lambda>a. M a - N a) \<in> multiset"
    79   apply (unfold multiset_def, simp)
    79   apply (simp add: multiset_def)
    80   apply (rule finite_subset)
    80   apply (rule finite_subset)
    81    prefer 2
    81    apply auto
    82    apply assumption
       
    83   apply auto
       
    84   done
    82   done
    85 
    83 
    86 
    84 
    87 subsection {* Algebraic properties of multisets *}
    85 subsection {* Algebraic properties of multisets *}
    88 
    86 
    89 subsubsection {* Union *}
    87 subsubsection {* Union *}
    90 
    88 
    91 theorem union_empty [simp]: "M + {#} = M \<and> {#} + M = M"
    89 lemma union_empty [simp]: "M + {#} = M \<and> {#} + M = M"
    92 by (simp add: union_def Mempty_def)
    90   by (simp add: union_def Mempty_def)
    93 
    91 
    94 theorem union_commute: "M + N = N + (M::'a multiset)"
    92 lemma union_commute: "M + N = N + (M::'a multiset)"
    95 by (simp add: union_def add_ac)
    93   by (simp add: union_def add_ac)
    96 
    94 
    97 theorem union_assoc: "(M + N) + K = M + (N + (K::'a multiset))"
    95 lemma union_assoc: "(M + N) + K = M + (N + (K::'a multiset))"
    98 by (simp add: union_def add_ac)
    96   by (simp add: union_def add_ac)
    99 
    97 
   100 theorem union_lcomm: "M + (N + K) = N + (M + (K::'a multiset))"
    98 lemma union_lcomm: "M + (N + K) = N + (M + (K::'a multiset))"
   101   apply (rule union_commute [THEN trans])
    99 proof -
   102   apply (rule union_assoc [THEN trans])
   100   have "M + (N + K) = (N + K) + M"
   103   apply (rule union_commute [THEN arg_cong])
   101     by (rule union_commute)
   104   done
   102   also have "\<dots> = N + (K + M)"
   105 
   103     by (rule union_assoc)
   106 theorems union_ac = union_assoc union_commute union_lcomm
   104   also have "K + M = M + K"
       
   105     by (rule union_commute)
       
   106   finally show ?thesis .
       
   107 qed
       
   108 
       
   109 lemmas union_ac = union_assoc union_commute union_lcomm
   107 
   110 
   108 instance multiset :: (type) comm_monoid_add
   111 instance multiset :: (type) comm_monoid_add
   109 proof 
   112 proof 
   110   fix a b c :: "'a multiset"
   113   fix a b c :: "'a multiset"
   111   show "(a + b) + c = a + (b + c)" by (rule union_assoc)
   114   show "(a + b) + c = a + (b + c)" by (rule union_assoc)
   114 qed
   117 qed
   115 
   118 
   116 
   119 
   117 subsubsection {* Difference *}
   120 subsubsection {* Difference *}
   118 
   121 
   119 theorem diff_empty [simp]: "M - {#} = M \<and> {#} - M = {#}"
   122 lemma diff_empty [simp]: "M - {#} = M \<and> {#} - M = {#}"
   120 by (simp add: Mempty_def diff_def)
   123   by (simp add: Mempty_def diff_def)
   121 
   124 
   122 theorem diff_union_inverse2 [simp]: "M + {#a#} - {#a#} = M"
   125 lemma diff_union_inverse2 [simp]: "M + {#a#} - {#a#} = M"
   123 by (simp add: union_def diff_def)
   126   by (simp add: union_def diff_def)
   124 
   127 
   125 
   128 
   126 subsubsection {* Count of elements *}
   129 subsubsection {* Count of elements *}
   127 
   130 
   128 theorem count_empty [simp]: "count {#} a = 0"
   131 lemma count_empty [simp]: "count {#} a = 0"
   129 by (simp add: count_def Mempty_def)
   132   by (simp add: count_def Mempty_def)
   130 
   133 
   131 theorem count_single [simp]: "count {#b#} a = (if b = a then 1 else 0)"
   134 lemma count_single [simp]: "count {#b#} a = (if b = a then 1 else 0)"
   132 by (simp add: count_def single_def)
   135   by (simp add: count_def single_def)
   133 
   136 
   134 theorem count_union [simp]: "count (M + N) a = count M a + count N a"
   137 lemma count_union [simp]: "count (M + N) a = count M a + count N a"
   135 by (simp add: count_def union_def)
   138   by (simp add: count_def union_def)
   136 
   139 
   137 theorem count_diff [simp]: "count (M - N) a = count M a - count N a"
   140 lemma count_diff [simp]: "count (M - N) a = count M a - count N a"
   138 by (simp add: count_def diff_def)
   141   by (simp add: count_def diff_def)
   139 
   142 
   140 
   143 
   141 subsubsection {* Set of elements *}
   144 subsubsection {* Set of elements *}
   142 
   145 
   143 theorem set_of_empty [simp]: "set_of {#} = {}"
   146 lemma set_of_empty [simp]: "set_of {#} = {}"
   144 by (simp add: set_of_def)
   147   by (simp add: set_of_def)
   145 
   148 
   146 theorem set_of_single [simp]: "set_of {#b#} = {b}"
   149 lemma set_of_single [simp]: "set_of {#b#} = {b}"
   147 by (simp add: set_of_def)
   150   by (simp add: set_of_def)
   148 
   151 
   149 theorem set_of_union [simp]: "set_of (M + N) = set_of M \<union> set_of N"
   152 lemma set_of_union [simp]: "set_of (M + N) = set_of M \<union> set_of N"
   150 by (auto simp add: set_of_def)
   153   by (auto simp add: set_of_def)
   151 
   154 
   152 theorem set_of_eq_empty_iff [simp]: "(set_of M = {}) = (M = {#})"
   155 lemma set_of_eq_empty_iff [simp]: "(set_of M = {}) = (M = {#})"
   153 by (auto simp add: set_of_def Mempty_def count_def expand_fun_eq)
   156   by (auto simp add: set_of_def Mempty_def count_def expand_fun_eq)
   154 
   157 
   155 theorem mem_set_of_iff [simp]: "(x \<in> set_of M) = (x :# M)"
   158 lemma mem_set_of_iff [simp]: "(x \<in> set_of M) = (x :# M)"
   156 by (auto simp add: set_of_def)
   159   by (auto simp add: set_of_def)
   157 
   160 
   158 
   161 
   159 subsubsection {* Size *}
   162 subsubsection {* Size *}
   160 
   163 
   161 theorem size_empty [simp]: "size {#} = 0"
   164 lemma size_empty [simp]: "size {#} = 0"
   162 by (simp add: size_def)
   165   by (simp add: size_def)
   163 
   166 
   164 theorem size_single [simp]: "size {#b#} = 1"
   167 lemma size_single [simp]: "size {#b#} = 1"
   165 by (simp add: size_def)
   168   by (simp add: size_def)
   166 
   169 
   167 theorem finite_set_of [iff]: "finite (set_of M)"
   170 lemma finite_set_of [iff]: "finite (set_of M)"
   168   apply (cut_tac x = M in Rep_multiset)
   171   using Rep_multiset [of M]
   169   apply (simp add: multiset_def set_of_def count_def)
   172   by (simp add: multiset_def set_of_def count_def)
   170   done
   173 
   171 
   174 lemma setsum_count_Int:
   172 theorem setsum_count_Int:
       
   173     "finite A ==> setsum (count N) (A \<inter> set_of N) = setsum (count N) A"
   175     "finite A ==> setsum (count N) (A \<inter> set_of N) = setsum (count N) A"
   174   apply (erule finite_induct, simp)
   176   apply (erule finite_induct)
       
   177    apply simp
   175   apply (simp add: Int_insert_left set_of_def)
   178   apply (simp add: Int_insert_left set_of_def)
   176   done
   179   done
   177 
   180 
   178 theorem size_union [simp]: "size (M + N::'a multiset) = size M + size N"
   181 lemma size_union [simp]: "size (M + N::'a multiset) = size M + size N"
   179   apply (unfold size_def)
   182   apply (unfold size_def)
   180   apply (subgoal_tac "count (M + N) = (\<lambda>a. count M a + count N a)")
   183   apply (subgoal_tac "count (M + N) = (\<lambda>a. count M a + count N a)")
   181    prefer 2
   184    prefer 2
   182    apply (rule ext, simp)
   185    apply (rule ext, simp)
   183   apply (simp (no_asm_simp) add: setsum_Un_nat setsum_addf setsum_count_Int)
   186   apply (simp (no_asm_simp) add: setsum_Un_nat setsum_addf setsum_count_Int)
   184   apply (subst Int_commute)
   187   apply (subst Int_commute)
   185   apply (simp (no_asm_simp) add: setsum_count_Int)
   188   apply (simp (no_asm_simp) add: setsum_count_Int)
   186   done
   189   done
   187 
   190 
   188 theorem size_eq_0_iff_empty [iff]: "(size M = 0) = (M = {#})"
   191 lemma size_eq_0_iff_empty [iff]: "(size M = 0) = (M = {#})"
   189   apply (unfold size_def Mempty_def count_def, auto)
   192   apply (unfold size_def Mempty_def count_def, auto)
   190   apply (simp add: set_of_def count_def expand_fun_eq)
   193   apply (simp add: set_of_def count_def expand_fun_eq)
   191   done
   194   done
   192 
   195 
   193 theorem size_eq_Suc_imp_elem: "size M = Suc n ==> \<exists>a. a :# M"
   196 lemma size_eq_Suc_imp_elem: "size M = Suc n ==> \<exists>a. a :# M"
   194   apply (unfold size_def)
   197   apply (unfold size_def)
   195   apply (drule setsum_SucD, auto)
   198   apply (drule setsum_SucD, auto)
   196   done
   199   done
   197 
   200 
   198 
   201 
   199 subsubsection {* Equality of multisets *}
   202 subsubsection {* Equality of multisets *}
   200 
   203 
   201 theorem multiset_eq_conv_count_eq: "(M = N) = (\<forall>a. count M a = count N a)"
   204 lemma multiset_eq_conv_count_eq: "(M = N) = (\<forall>a. count M a = count N a)"
   202 by (simp add: count_def expand_fun_eq)
   205   by (simp add: count_def expand_fun_eq)
   203 
   206 
   204 theorem single_not_empty [simp]: "{#a#} \<noteq> {#} \<and> {#} \<noteq> {#a#}"
   207 lemma single_not_empty [simp]: "{#a#} \<noteq> {#} \<and> {#} \<noteq> {#a#}"
   205 by (simp add: single_def Mempty_def expand_fun_eq)
   208   by (simp add: single_def Mempty_def expand_fun_eq)
   206 
   209 
   207 theorem single_eq_single [simp]: "({#a#} = {#b#}) = (a = b)"
   210 lemma single_eq_single [simp]: "({#a#} = {#b#}) = (a = b)"
   208 by (auto simp add: single_def expand_fun_eq)
   211   by (auto simp add: single_def expand_fun_eq)
   209 
   212 
   210 theorem union_eq_empty [iff]: "(M + N = {#}) = (M = {#} \<and> N = {#})"
   213 lemma union_eq_empty [iff]: "(M + N = {#}) = (M = {#} \<and> N = {#})"
   211 by (auto simp add: union_def Mempty_def expand_fun_eq)
   214   by (auto simp add: union_def Mempty_def expand_fun_eq)
   212 
   215 
   213 theorem empty_eq_union [iff]: "({#} = M + N) = (M = {#} \<and> N = {#})"
   216 lemma empty_eq_union [iff]: "({#} = M + N) = (M = {#} \<and> N = {#})"
   214 by (auto simp add: union_def Mempty_def expand_fun_eq)
   217   by (auto simp add: union_def Mempty_def expand_fun_eq)
   215 
   218 
   216 theorem union_right_cancel [simp]: "(M + K = N + K) = (M = (N::'a multiset))"
   219 lemma union_right_cancel [simp]: "(M + K = N + K) = (M = (N::'a multiset))"
   217 by (simp add: union_def expand_fun_eq)
   220   by (simp add: union_def expand_fun_eq)
   218 
   221 
   219 theorem union_left_cancel [simp]: "(K + M = K + N) = (M = (N::'a multiset))"
   222 lemma union_left_cancel [simp]: "(K + M = K + N) = (M = (N::'a multiset))"
   220 by (simp add: union_def expand_fun_eq)
   223   by (simp add: union_def expand_fun_eq)
   221 
   224 
   222 theorem union_is_single:
   225 lemma union_is_single:
   223     "(M + N = {#a#}) = (M = {#a#} \<and> N={#} \<or> M = {#} \<and> N = {#a#})"
   226     "(M + N = {#a#}) = (M = {#a#} \<and> N={#} \<or> M = {#} \<and> N = {#a#})"
   224   apply (simp add: Mempty_def single_def union_def add_is_1 expand_fun_eq)
   227   apply (simp add: Mempty_def single_def union_def add_is_1 expand_fun_eq)
   225   apply blast
   228   apply blast
   226   done
   229   done
   227 
   230 
   228 theorem single_is_union:
   231 lemma single_is_union:
   229      "({#a#} = M + N) = ({#a#} = M \<and> N = {#} \<or> M = {#} \<and> {#a#} = N)"
   232      "({#a#} = M + N) = ({#a#} = M \<and> N = {#} \<or> M = {#} \<and> {#a#} = N)"
   230   apply (unfold Mempty_def single_def union_def)
   233   apply (unfold Mempty_def single_def union_def)
   231   apply (simp add: add_is_1 one_is_add expand_fun_eq)
   234   apply (simp add: add_is_1 one_is_add expand_fun_eq)
   232   apply (blast dest: sym)
   235   apply (blast dest: sym)
   233   done
   236   done
   234 
   237 
   235 theorem add_eq_conv_diff:
   238 lemma add_eq_conv_diff:
   236   "(M + {#a#} = N + {#b#}) =
   239   "(M + {#a#} = N + {#b#}) =
   237    (M = N \<and> a = b \<or> M = N - {#a#} + {#b#} \<and> N = M - {#b#} + {#a#})"
   240    (M = N \<and> a = b \<or> M = N - {#a#} + {#b#} \<and> N = M - {#b#} + {#a#})"
   238   apply (unfold single_def union_def diff_def)
   241   apply (unfold single_def union_def diff_def)
   239   apply (simp (no_asm) add: expand_fun_eq)
   242   apply (simp (no_asm) add: expand_fun_eq)
   240   apply (rule conjI, force, safe, simp_all)
   243   apply (rule conjI, force, safe, simp_all)
   241   apply (simp add: eq_sym_conv)
   244   apply (simp add: eq_sym_conv)
   242   done
   245   done
   243 
   246 
   244 (*
       
   245 val prems = Goal
       
   246  "[| !!F. [| finite F; !G. G < F --> P G |] ==> P F |] ==> finite F --> P F";
       
   247 by (res_inst_tac [("a","F"),("f","\<lambda>A. if finite A then card A else 0")]
       
   248      measure_induct 1);
       
   249 by (Clarify_tac 1)
       
   250 by (resolve_tac prems 1)
       
   251  by (assume_tac 1)
       
   252 by (Clarify_tac 1)
       
   253 by (subgoal_tac "finite G" 1)
       
   254  by (fast_tac (claset() addDs [finite_subset,order_less_le RS iffD1]) 2);
       
   255 by (etac allE 1)
       
   256 by (etac impE 1)
       
   257  by (Blast_tac 2)
       
   258 by (asm_simp_tac (simpset() addsimps [psubset_card]) 1);
       
   259 no_qed();
       
   260 val lemma = result();
       
   261 
       
   262 val prems = Goal
       
   263  "[| finite F; !!F. [| finite F; !G. G < F --> P G |] ==> P F |] ==> P F";
       
   264 by (rtac (lemma RS mp) 1);
       
   265 by (REPEAT(ares_tac prems 1));
       
   266 qed "finite_psubset_induct";
       
   267 
       
   268 Better: use wf_finite_psubset in WF_Rel
       
   269 *)
       
   270 
       
   271 declare Rep_multiset_inject [symmetric, simp del]
   247 declare Rep_multiset_inject [symmetric, simp del]
   272 
   248 
   273 
   249 
   274 subsubsection {* Intersection *}
   250 subsubsection {* Intersection *}
   275 
   251 
   276 lemma multiset_inter_count:
   252 lemma multiset_inter_count:
   277   "count (A #\<inter> B) x = min (count A x) (count B x)"
   253     "count (A #\<inter> B) x = min (count A x) (count B x)"
   278   by (simp add:multiset_inter_def min_def)
   254   by (simp add: multiset_inter_def min_def)
   279 
   255 
   280 lemma multiset_inter_commute: "A #\<inter> B = B #\<inter> A"
   256 lemma multiset_inter_commute: "A #\<inter> B = B #\<inter> A"
   281   by (simp add: multiset_eq_conv_count_eq multiset_inter_count 
   257   by (simp add: multiset_eq_conv_count_eq multiset_inter_count 
   282                 min_max.below_inf.inf_commute)
   258     min_max.below_inf.inf_commute)
   283 
   259 
   284 lemma multiset_inter_assoc: "A #\<inter> (B #\<inter> C) = A #\<inter> B #\<inter> C"
   260 lemma multiset_inter_assoc: "A #\<inter> (B #\<inter> C) = A #\<inter> B #\<inter> C"
   285   by (simp add: multiset_eq_conv_count_eq multiset_inter_count 
   261   by (simp add: multiset_eq_conv_count_eq multiset_inter_count 
   286                 min_max.below_inf.inf_assoc)
   262     min_max.below_inf.inf_assoc)
   287 
   263 
   288 lemma multiset_inter_left_commute: "A #\<inter> (B #\<inter> C) = B #\<inter> (A #\<inter> C)"
   264 lemma multiset_inter_left_commute: "A #\<inter> (B #\<inter> C) = B #\<inter> (A #\<inter> C)"
   289   by (simp add: multiset_eq_conv_count_eq multiset_inter_count min_def)
   265   by (simp add: multiset_eq_conv_count_eq multiset_inter_count min_def)
   290 
   266 
   291 lemmas multiset_inter_ac = multiset_inter_commute multiset_inter_assoc
   267 lemmas multiset_inter_ac =
   292                            multiset_inter_left_commute
   268   multiset_inter_commute
       
   269   multiset_inter_assoc
       
   270   multiset_inter_left_commute
   293 
   271 
   294 lemma multiset_union_diff_commute: "B #\<inter> C = {#} \<Longrightarrow> A + B - C = A - C + B"
   272 lemma multiset_union_diff_commute: "B #\<inter> C = {#} \<Longrightarrow> A + B - C = A - C + B"
   295   apply (simp add:multiset_eq_conv_count_eq multiset_inter_count min_def 
   273   apply (simp add: multiset_eq_conv_count_eq multiset_inter_count min_def 
   296               split:split_if_asm)
   274     split: split_if_asm)
   297   apply clarsimp
   275   apply clarsimp
   298   apply (erule_tac x="a" in allE)
   276   apply (erule_tac x = a in allE)
   299   apply auto
   277   apply auto
   300   done
   278   done
   301 
   279 
   302 
   280 
   303 subsection {* Induction over multisets *}
   281 subsection {* Induction over multisets *}
   308   apply (erule finite_induct, auto)
   286   apply (erule finite_induct, auto)
   309   apply (drule_tac a = a in mk_disjoint_insert, auto)
   287   apply (drule_tac a = a in mk_disjoint_insert, auto)
   310   done
   288   done
   311 
   289 
   312 lemma rep_multiset_induct_aux:
   290 lemma rep_multiset_induct_aux:
   313   "P (\<lambda>a. (0::nat)) ==> (!!f b. f \<in> multiset ==> P f ==> P (f (b := f b + 1)))
   291   assumes "P (\<lambda>a. (0::nat))"
   314     ==> \<forall>f. f \<in> multiset --> setsum f {x. 0 < f x} = n --> P f"
   292     and "!!f b. f \<in> multiset ==> P f ==> P (f (b := f b + 1))"
       
   293   shows "\<forall>f. f \<in> multiset --> setsum f {x. 0 < f x} = n --> P f"
   315 proof -
   294 proof -
   316   case rule_context
   295   note premises = prems [unfolded multiset_def]
   317   note premises = this [unfolded multiset_def]
       
   318   show ?thesis
   296   show ?thesis
   319     apply (unfold multiset_def)
   297     apply (unfold multiset_def)
   320     apply (induct_tac n, simp, clarify)
   298     apply (induct_tac n, simp, clarify)
   321      apply (subgoal_tac "f = (\<lambda>a.0)")
   299      apply (subgoal_tac "f = (\<lambda>a.0)")
   322       apply simp
   300       apply simp
   349 qed
   327 qed
   350 
   328 
   351 theorem rep_multiset_induct:
   329 theorem rep_multiset_induct:
   352   "f \<in> multiset ==> P (\<lambda>a. 0) ==>
   330   "f \<in> multiset ==> P (\<lambda>a. 0) ==>
   353     (!!f b. f \<in> multiset ==> P f ==> P (f (b := f b + 1))) ==> P f"
   331     (!!f b. f \<in> multiset ==> P f ==> P (f (b := f b + 1))) ==> P f"
   354   by (insert rep_multiset_induct_aux, blast)
   332   using rep_multiset_induct_aux by blast
   355 
   333 
   356 theorem multiset_induct [induct type: multiset]:
   334 theorem multiset_induct [induct type: multiset]:
   357   "P {#} ==> (!!M x. P M ==> P (M + {#x#})) ==> P M"
   335   assumes prem1: "P {#}"
       
   336     and prem2: "!!M x. P M ==> P (M + {#x#})"
       
   337   shows "P M"
   358 proof -
   338 proof -
   359   note defns = union_def single_def Mempty_def
   339   note defns = union_def single_def Mempty_def
   360   assume prem1 [unfolded defns]: "P {#}"
       
   361   assume prem2 [unfolded defns]: "!!M x. P M ==> P (M + {#x#})"
       
   362   show ?thesis
   340   show ?thesis
   363     apply (rule Rep_multiset_inverse [THEN subst])
   341     apply (rule Rep_multiset_inverse [THEN subst])
   364     apply (rule Rep_multiset [THEN rep_multiset_induct])
   342     apply (rule Rep_multiset [THEN rep_multiset_induct])
   365      apply (rule prem1)
   343      apply (rule prem1 [unfolded defns])
   366     apply (subgoal_tac "f(b := f b + 1) = (\<lambda>a. f a + (if a=b then 1 else 0))")
   344     apply (subgoal_tac "f(b := f b + 1) = (\<lambda>a. f a + (if a=b then 1 else 0))")
   367      prefer 2
   345      prefer 2
   368      apply (simp add: expand_fun_eq)
   346      apply (simp add: expand_fun_eq)
   369     apply (erule ssubst)
   347     apply (erule ssubst)
   370     apply (erule Abs_multiset_inverse [THEN subst]) 
   348     apply (erule Abs_multiset_inverse [THEN subst]) 
   371     apply (erule prem2 [simplified])
   349     apply (erule prem2 [unfolded defns, simplified])
   372     done
   350     done
   373 qed
   351 qed
   374 
       
   375 
   352 
   376 lemma MCollect_preserves_multiset:
   353 lemma MCollect_preserves_multiset:
   377     "M \<in> multiset ==> (\<lambda>x. if P x then M x else 0) \<in> multiset"
   354     "M \<in> multiset ==> (\<lambda>x. if P x then M x else 0) \<in> multiset"
   378   apply (simp add: multiset_def)
   355   apply (simp add: multiset_def)
   379   apply (rule finite_subset, auto)
   356   apply (rule finite_subset, auto)
   380   done
   357   done
   381 
   358 
   382 theorem count_MCollect [simp]:
   359 lemma count_MCollect [simp]:
   383     "count {# x:M. P x #} a = (if P a then count M a else 0)"
   360     "count {# x:M. P x #} a = (if P a then count M a else 0)"
   384   by (simp add: count_def MCollect_def MCollect_preserves_multiset)
   361   by (simp add: count_def MCollect_def MCollect_preserves_multiset)
   385 
   362 
   386 theorem set_of_MCollect [simp]: "set_of {# x:M. P x #} = set_of M \<inter> {x. P x}"
   363 lemma set_of_MCollect [simp]: "set_of {# x:M. P x #} = set_of M \<inter> {x. P x}"
   387 by (auto simp add: set_of_def)
   364   by (auto simp add: set_of_def)
   388 
   365 
   389 theorem multiset_partition: "M = {# x:M. P x #} + {# x:M. \<not> P x #}"
   366 lemma multiset_partition: "M = {# x:M. P x #} + {# x:M. \<not> P x #}"
   390 by (subst multiset_eq_conv_count_eq, auto)
   367   by (subst multiset_eq_conv_count_eq, auto)
   391 
   368 
   392 theorem add_eq_conv_ex:
   369 lemma add_eq_conv_ex:
   393       "(M + {#a#} = N + {#b#}) =
   370   "(M + {#a#} = N + {#b#}) =
   394        (M = N \<and> a = b \<or> (\<exists>K. M = K + {#b#} \<and> N = K + {#a#}))"
   371     (M = N \<and> a = b \<or> (\<exists>K. M = K + {#b#} \<and> N = K + {#a#}))"
   395   by (auto simp add: add_eq_conv_diff)
   372   by (auto simp add: add_eq_conv_diff)
   396 
   373 
   397 declare multiset_typedef [simp del]
   374 declare multiset_typedef [simp del]
       
   375 
   398 
   376 
   399 subsection {* Multiset orderings *}
   377 subsection {* Multiset orderings *}
   400 
   378 
   401 subsubsection {* Well-foundedness *}
   379 subsubsection {* Well-foundedness *}
   402 
   380 
   609   apply (rule_tac x = a in exI)
   587   apply (rule_tac x = a in exI)
   610   apply (rule_tac x = "I + J'" in exI)
   588   apply (rule_tac x = "I + J'" in exI)
   611   apply (simp add: union_ac)
   589   apply (simp add: union_ac)
   612   done
   590   done
   613 
   591 
   614 theorem one_step_implies_mult:
   592 lemma one_step_implies_mult:
   615   "trans r ==> J \<noteq> {#} ==> \<forall>k \<in> set_of K. \<exists>j \<in> set_of J. (k, j) \<in> r
   593   "trans r ==> J \<noteq> {#} ==> \<forall>k \<in> set_of K. \<exists>j \<in> set_of J. (k, j) \<in> r
   616     ==> (I + K, I + J) \<in> mult r"
   594     ==> (I + K, I + J) \<in> mult r"
   617   apply (insert one_step_implies_mult_aux, blast)
   595   apply (insert one_step_implies_mult_aux, blast)
   618   done
   596   done
   619 
   597 
   639     "finite A ==> (\<forall>x \<in> A. \<exists>y \<in> A. x < (y::'a::order)) --> A = {}"
   617     "finite A ==> (\<forall>x \<in> A. \<exists>y \<in> A. x < (y::'a::order)) --> A = {}"
   640   apply (erule finite_induct)
   618   apply (erule finite_induct)
   641    apply (auto intro: order_less_trans)
   619    apply (auto intro: order_less_trans)
   642   done
   620   done
   643 
   621 
   644 theorem mult_less_not_refl: "\<not> M < (M::'a::order multiset)"
   622 lemma mult_less_not_refl: "\<not> M < (M::'a::order multiset)"
   645   apply (unfold less_multiset_def, auto)
   623   apply (unfold less_multiset_def, auto)
   646   apply (drule trans_base_order [THEN mult_implies_one_step], auto)
   624   apply (drule trans_base_order [THEN mult_implies_one_step], auto)
   647   apply (drule finite_set_of [THEN mult_irrefl_aux [rule_format (no_asm)]])
   625   apply (drule finite_set_of [THEN mult_irrefl_aux [rule_format (no_asm)]])
   648   apply (simp add: set_of_eq_empty_iff)
   626   apply (simp add: set_of_eq_empty_iff)
   649   done
   627   done
   704   done
   682   done
   705 
   683 
   706 
   684 
   707 subsubsection {* Monotonicity of multiset union *}
   685 subsubsection {* Monotonicity of multiset union *}
   708 
   686 
   709 theorem mult1_union:
   687 lemma mult1_union:
   710     "(B, D) \<in> mult1 r ==> trans r ==> (C + B, C + D) \<in> mult1 r"
   688     "(B, D) \<in> mult1 r ==> trans r ==> (C + B, C + D) \<in> mult1 r"
   711   apply (unfold mult1_def, auto)
   689   apply (unfold mult1_def, auto)
   712   apply (rule_tac x = a in exI)
   690   apply (rule_tac x = a in exI)
   713   apply (rule_tac x = "C + M0" in exI)
   691   apply (rule_tac x = "C + M0" in exI)
   714   apply (simp add: union_assoc)
   692   apply (simp add: union_assoc)
   725   apply (subst union_commute [of B C])
   703   apply (subst union_commute [of B C])
   726   apply (subst union_commute [of D C])
   704   apply (subst union_commute [of D C])
   727   apply (erule union_less_mono2)
   705   apply (erule union_less_mono2)
   728   done
   706   done
   729 
   707 
   730 theorem union_less_mono:
   708 lemma union_less_mono:
   731     "A < C ==> B < D ==> A + B < C + (D::'a::order multiset)"
   709     "A < C ==> B < D ==> A + B < C + (D::'a::order multiset)"
   732   apply (blast intro!: union_less_mono1 union_less_mono2 mult_less_trans)
   710   apply (blast intro!: union_less_mono1 union_less_mono2 mult_less_trans)
   733   done
   711   done
   734 
   712 
   735 theorem union_le_mono:
   713 lemma union_le_mono:
   736     "A <= C ==> B <= D ==> A + B <= C + (D::'a::order multiset)"
   714     "A <= C ==> B <= D ==> A + B <= C + (D::'a::order multiset)"
   737   apply (unfold le_multiset_def)
   715   apply (unfold le_multiset_def)
   738   apply (blast intro: union_less_mono union_less_mono1 union_less_mono2)
   716   apply (blast intro: union_less_mono union_less_mono1 union_less_mono2)
   739   done
   717   done
   740 
   718 
   741 theorem empty_leI [iff]: "{#} <= (M::'a::order multiset)"
   719 lemma empty_leI [iff]: "{#} <= (M::'a::order multiset)"
   742   apply (unfold le_multiset_def less_multiset_def)
   720   apply (unfold le_multiset_def less_multiset_def)
   743   apply (case_tac "M = {#}")
   721   apply (case_tac "M = {#}")
   744    prefer 2
   722    prefer 2
   745    apply (subgoal_tac "({#} + {#}, {#} + M) \<in> mult (Collect (split op <))")
   723    apply (subgoal_tac "({#} + {#}, {#} + M) \<in> mult (Collect (split op <))")
   746     prefer 2
   724     prefer 2
   747     apply (rule one_step_implies_mult)
   725     apply (rule one_step_implies_mult)
   748       apply (simp only: trans_def, auto)
   726       apply (simp only: trans_def, auto)
   749   done
   727   done
   750 
   728 
   751 theorem union_upper1: "A <= A + (B::'a::order multiset)"
   729 lemma union_upper1: "A <= A + (B::'a::order multiset)"
   752 proof -
   730 proof -
   753   have "A + {#} <= A + B" by (blast intro: union_le_mono) 
   731   have "A + {#} <= A + B" by (blast intro: union_le_mono) 
   754   thus ?thesis by simp
   732   thus ?thesis by simp
   755 qed
   733 qed
   756 
   734 
   757 theorem union_upper2: "B <= A + (B::'a::order multiset)"
   735 lemma union_upper2: "B <= A + (B::'a::order multiset)"
   758 by (subst union_commute, rule union_upper1)
   736 by (subst union_commute, rule union_upper1)
   759 
   737 
   760 
   738 
   761 subsection {* Link with lists *} 
   739 subsection {* Link with lists *} 
   762 
   740