src/HOL/Library/Multiset.thy
changeset 26016 f9d1bf2fc59c
parent 25759 6326138c1bd7
child 26033 278025d5282d
equal deleted inserted replaced
26015:ad2756de580e 26016:f9d1bf2fc59c
    26 
    26 
    27 definition
    27 definition
    28   single :: "'a => 'a multiset" where
    28   single :: "'a => 'a multiset" where
    29   "single a = Abs_multiset (\<lambda>b. if b = a then 1 else 0)"
    29   "single a = Abs_multiset (\<lambda>b. if b = a then 1 else 0)"
    30 
    30 
       
    31 declare
       
    32   Mempty_def[code func del] single_def[code func del]
       
    33 
    31 definition
    34 definition
    32   count :: "'a multiset => 'a => nat" where
    35   count :: "'a multiset => 'a => nat" where
    33   "count = Rep_multiset"
    36   "count = Rep_multiset"
    34 
    37 
    35 definition
    38 definition
    53 
    56 
    54 instantiation multiset :: (type) "{plus, minus, zero, size}" 
    57 instantiation multiset :: (type) "{plus, minus, zero, size}" 
    55 begin
    58 begin
    56 
    59 
    57 definition
    60 definition
    58   union_def: "M + N == Abs_multiset (\<lambda>a. Rep_multiset M a + Rep_multiset N a)"
    61   union_def[code func del]:
       
    62   "M + N == Abs_multiset (\<lambda>a. Rep_multiset M a + Rep_multiset N a)"
    59 
    63 
    60 definition
    64 definition
    61   diff_def: "M - N == Abs_multiset (\<lambda>a. Rep_multiset M a - Rep_multiset N a)"
    65   diff_def: "M - N == Abs_multiset (\<lambda>a. Rep_multiset M a - Rep_multiset N a)"
    62 
    66 
    63 definition
    67 definition
    64   Zero_multiset_def [simp]: "0 == {#}"
    68   Zero_multiset_def [simp]: "0 == {#}"
    65 
    69 
    66 definition
    70 definition
    67   size_def: "size M == setsum (count M) (set_of M)"
    71   size_def[code func del]: "size M == setsum (count M) (set_of M)"
    68 
    72 
    69 instance ..
    73 instance ..
    70 
    74 
    71 end
    75 end
    72 
    76 
    84 
    88 
    85 text {*
    89 text {*
    86  \medskip Preservation of the representing set @{term multiset}.
    90  \medskip Preservation of the representing set @{term multiset}.
    87 *}
    91 *}
    88 
    92 
    89 lemma const0_in_multiset [simp]: "(\<lambda>a. 0) \<in> multiset"
    93 lemma const0_in_multiset: "(\<lambda>a. 0) \<in> multiset"
    90   by (simp add: multiset_def)
    94   by (simp add: multiset_def)
    91 
    95 
    92 lemma only1_in_multiset [simp]: "(\<lambda>b. if b = a then 1 else 0) \<in> multiset"
    96 lemma only1_in_multiset: "(\<lambda>b. if b = a then 1 else 0) \<in> multiset"
    93   by (simp add: multiset_def)
    97   by (simp add: multiset_def)
    94 
    98 
    95 lemma union_preserves_multiset [simp]:
    99 lemma union_preserves_multiset:
    96     "M \<in> multiset ==> N \<in> multiset ==> (\<lambda>a. M a + N a) \<in> multiset"
   100     "M \<in> multiset ==> N \<in> multiset ==> (\<lambda>a. M a + N a) \<in> multiset"
    97   apply (simp add: multiset_def)
   101   apply (simp add: multiset_def)
    98   apply (drule (1) finite_UnI)
   102   apply (drule (1) finite_UnI)
    99   apply (simp del: finite_Un add: Un_def)
   103   apply (simp del: finite_Un add: Un_def)
   100   done
   104   done
   101 
   105 
   102 lemma diff_preserves_multiset [simp]:
   106 lemma diff_preserves_multiset:
   103     "M \<in> multiset ==> (\<lambda>a. M a - N a) \<in> multiset"
   107     "M \<in> multiset ==> (\<lambda>a. M a - N a) \<in> multiset"
   104   apply (simp add: multiset_def)
   108   apply (simp add: multiset_def)
   105   apply (rule finite_subset)
   109   apply (rule finite_subset)
   106    apply auto
   110    apply auto
   107   done
   111   done
   108 
   112 
   109 
   113 lemma MCollect_preserves_multiset:
   110 subsection {* Algebraic properties of multisets *}
   114     "M \<in> multiset ==> (\<lambda>x. if P x then M x else 0) \<in> multiset"
       
   115   apply (simp add: multiset_def)
       
   116   apply (rule finite_subset, auto)
       
   117   done
       
   118 
       
   119 lemmas in_multiset = const0_in_multiset only1_in_multiset
       
   120   union_preserves_multiset diff_preserves_multiset MCollect_preserves_multiset
       
   121 
       
   122 subsection {* Algebraic properties *}
   111 
   123 
   112 subsubsection {* Union *}
   124 subsubsection {* Union *}
   113 
   125 
   114 lemma union_empty [simp]: "M + {#} = M \<and> {#} + M = M"
   126 lemma union_empty [simp]: "M + {#} = M \<and> {#} + M = M"
   115   by (simp add: union_def Mempty_def)
   127 by (simp add: union_def Mempty_def in_multiset)
   116 
   128 
   117 lemma union_commute: "M + N = N + (M::'a multiset)"
   129 lemma union_commute: "M + N = N + (M::'a multiset)"
   118   by (simp add: union_def add_ac)
   130 by (simp add: union_def add_ac in_multiset)
   119 
   131 
   120 lemma union_assoc: "(M + N) + K = M + (N + (K::'a multiset))"
   132 lemma union_assoc: "(M + N) + K = M + (N + (K::'a multiset))"
   121   by (simp add: union_def add_ac)
   133 by (simp add: union_def add_ac in_multiset)
   122 
   134 
   123 lemma union_lcomm: "M + (N + K) = N + (M + (K::'a multiset))"
   135 lemma union_lcomm: "M + (N + K) = N + (M + (K::'a multiset))"
   124 proof -
   136 proof -
   125   have "M + (N + K) = (N + K) + M"
   137   have "M + (N + K) = (N + K) + M"
   126     by (rule union_commute)
   138     by (rule union_commute)
   143 
   155 
   144 
   156 
   145 subsubsection {* Difference *}
   157 subsubsection {* Difference *}
   146 
   158 
   147 lemma diff_empty [simp]: "M - {#} = M \<and> {#} - M = {#}"
   159 lemma diff_empty [simp]: "M - {#} = M \<and> {#} - M = {#}"
   148   by (simp add: Mempty_def diff_def)
   160 by (simp add: Mempty_def diff_def in_multiset)
   149 
   161 
   150 lemma diff_union_inverse2 [simp]: "M + {#a#} - {#a#} = M"
   162 lemma diff_union_inverse2 [simp]: "M + {#a#} - {#a#} = M"
   151   by (simp add: union_def diff_def)
   163 by (simp add: union_def diff_def in_multiset)
   152 
   164 
   153 
   165 
   154 subsubsection {* Count of elements *}
   166 subsubsection {* Count of elements *}
   155 
   167 
   156 lemma count_empty [simp]: "count {#} a = 0"
   168 lemma count_empty [simp]: "count {#} a = 0"
   157   by (simp add: count_def Mempty_def)
   169 by (simp add: count_def Mempty_def in_multiset)
   158 
   170 
   159 lemma count_single [simp]: "count {#b#} a = (if b = a then 1 else 0)"
   171 lemma count_single [simp]: "count {#b#} a = (if b = a then 1 else 0)"
   160   by (simp add: count_def single_def)
   172 by (simp add: count_def single_def in_multiset)
   161 
   173 
   162 lemma count_union [simp]: "count (M + N) a = count M a + count N a"
   174 lemma count_union [simp]: "count (M + N) a = count M a + count N a"
   163   by (simp add: count_def union_def)
   175 by (simp add: count_def union_def in_multiset)
   164 
   176 
   165 lemma count_diff [simp]: "count (M - N) a = count M a - count N a"
   177 lemma count_diff [simp]: "count (M - N) a = count M a - count N a"
   166   by (simp add: count_def diff_def)
   178 by (simp add: count_def diff_def in_multiset)
       
   179 
       
   180 lemma count_MCollect [simp]:
       
   181   "count {# x:M. P x #} a = (if P a then count M a else 0)"
       
   182 by (simp add: count_def MCollect_def in_multiset)
   167 
   183 
   168 
   184 
   169 subsubsection {* Set of elements *}
   185 subsubsection {* Set of elements *}
   170 
   186 
   171 lemma set_of_empty [simp]: "set_of {#} = {}"
   187 lemma set_of_empty [simp]: "set_of {#} = {}"
   172   by (simp add: set_of_def)
   188 by (simp add: set_of_def)
   173 
   189 
   174 lemma set_of_single [simp]: "set_of {#b#} = {b}"
   190 lemma set_of_single [simp]: "set_of {#b#} = {b}"
   175   by (simp add: set_of_def)
   191 by (simp add: set_of_def)
   176 
   192 
   177 lemma set_of_union [simp]: "set_of (M + N) = set_of M \<union> set_of N"
   193 lemma set_of_union [simp]: "set_of (M + N) = set_of M \<union> set_of N"
   178   by (auto simp add: set_of_def)
   194 by (auto simp add: set_of_def)
   179 
   195 
   180 lemma set_of_eq_empty_iff [simp]: "(set_of M = {}) = (M = {#})"
   196 lemma set_of_eq_empty_iff [simp]: "(set_of M = {}) = (M = {#})"
   181   by (auto simp add: set_of_def Mempty_def count_def expand_fun_eq)
   197 by(auto simp: set_of_def Mempty_def in_multiset count_def expand_fun_eq)
   182 
   198 
   183 lemma mem_set_of_iff [simp]: "(x \<in> set_of M) = (x :# M)"
   199 lemma mem_set_of_iff [simp]: "(x \<in> set_of M) = (x :# M)"
   184   by (auto simp add: set_of_def)
   200 by (auto simp add: set_of_def)
       
   201 
       
   202 lemma set_of_MCollect [simp]: "set_of {# x:M. P x #} = set_of M \<inter> {x. P x}"
       
   203 by (auto simp add: set_of_def)
   185 
   204 
   186 
   205 
   187 subsubsection {* Size *}
   206 subsubsection {* Size *}
   188 
   207 
   189 lemma size_empty [simp]: "size {#} = 0"
   208 lemma size_empty [simp,code func]: "size {#} = 0"
   190   by (simp add: size_def)
   209 by (simp add: size_def)
   191 
   210 
   192 lemma size_single [simp]: "size {#b#} = 1"
   211 lemma size_single [simp,code func]: "size {#b#} = 1"
   193   by (simp add: size_def)
   212 by (simp add: size_def)
   194 
   213 
   195 lemma finite_set_of [iff]: "finite (set_of M)"
   214 lemma finite_set_of [iff]: "finite (set_of M)"
   196   using Rep_multiset [of M]
   215   using Rep_multiset [of M]
   197   by (simp add: multiset_def set_of_def count_def)
   216   by (simp add: multiset_def set_of_def count_def)
   198 
   217 
   201   apply (induct rule: finite_induct)
   220   apply (induct rule: finite_induct)
   202    apply simp
   221    apply simp
   203   apply (simp add: Int_insert_left set_of_def)
   222   apply (simp add: Int_insert_left set_of_def)
   204   done
   223   done
   205 
   224 
   206 lemma size_union [simp]: "size (M + N::'a multiset) = size M + size N"
   225 lemma size_union[simp,code func]: "size (M + N::'a multiset) = size M + size N"
   207   apply (unfold size_def)
   226   apply (unfold size_def)
   208   apply (subgoal_tac "count (M + N) = (\<lambda>a. count M a + count N a)")
   227   apply (subgoal_tac "count (M + N) = (\<lambda>a. count M a + count N a)")
   209    prefer 2
   228    prefer 2
   210    apply (rule ext, simp)
   229    apply (rule ext, simp)
   211   apply (simp (no_asm_simp) add: setsum_Un_nat setsum_addf setsum_count_Int)
   230   apply (simp (no_asm_simp) add: setsum_Un_nat setsum_addf setsum_count_Int)
   212   apply (subst Int_commute)
   231   apply (subst Int_commute)
   213   apply (simp (no_asm_simp) add: setsum_count_Int)
   232   apply (simp (no_asm_simp) add: setsum_count_Int)
   214   done
   233   done
   215 
   234 
   216 lemma size_eq_0_iff_empty [iff]: "(size M = 0) = (M = {#})"
   235 lemma size_eq_0_iff_empty [iff]: "(size M = 0) = (M = {#})"
   217   apply (unfold size_def Mempty_def count_def, auto)
   236 apply (unfold size_def Mempty_def count_def, auto simp: in_multiset)
   218   apply (simp add: set_of_def count_def expand_fun_eq)
   237 apply (simp add: set_of_def count_def in_multiset expand_fun_eq)
   219   done
   238 done
       
   239 
       
   240 lemma nonempty_has_size: "(S \<noteq> {#}) = (0 < size S)"
       
   241 by(metis gr0I gr_implies_not0 size_empty size_eq_0_iff_empty)
   220 
   242 
   221 lemma size_eq_Suc_imp_elem: "size M = Suc n ==> \<exists>a. a :# M"
   243 lemma size_eq_Suc_imp_elem: "size M = Suc n ==> \<exists>a. a :# M"
   222   apply (unfold size_def)
   244   apply (unfold size_def)
   223   apply (drule setsum_SucD, auto)
   245   apply (drule setsum_SucD, auto)
   224   done
   246   done
   227 
   249 
   228 lemma multiset_eq_conv_count_eq: "(M = N) = (\<forall>a. count M a = count N a)"
   250 lemma multiset_eq_conv_count_eq: "(M = N) = (\<forall>a. count M a = count N a)"
   229   by (simp add: count_def expand_fun_eq)
   251   by (simp add: count_def expand_fun_eq)
   230 
   252 
   231 lemma single_not_empty [simp]: "{#a#} \<noteq> {#} \<and> {#} \<noteq> {#a#}"
   253 lemma single_not_empty [simp]: "{#a#} \<noteq> {#} \<and> {#} \<noteq> {#a#}"
   232   by (simp add: single_def Mempty_def expand_fun_eq)
   254 by (simp add: single_def Mempty_def in_multiset expand_fun_eq)
   233 
   255 
   234 lemma single_eq_single [simp]: "({#a#} = {#b#}) = (a = b)"
   256 lemma single_eq_single [simp]: "({#a#} = {#b#}) = (a = b)"
   235   by (auto simp add: single_def expand_fun_eq)
   257 by (auto simp add: single_def in_multiset expand_fun_eq)
   236 
   258 
   237 lemma union_eq_empty [iff]: "(M + N = {#}) = (M = {#} \<and> N = {#})"
   259 lemma union_eq_empty [iff]: "(M + N = {#}) = (M = {#} \<and> N = {#})"
   238   by (auto simp add: union_def Mempty_def expand_fun_eq)
   260 by (auto simp add: union_def Mempty_def in_multiset expand_fun_eq)
   239 
   261 
   240 lemma empty_eq_union [iff]: "({#} = M + N) = (M = {#} \<and> N = {#})"
   262 lemma empty_eq_union [iff]: "({#} = M + N) = (M = {#} \<and> N = {#})"
   241   by (auto simp add: union_def Mempty_def expand_fun_eq)
   263 by (auto simp add: union_def Mempty_def in_multiset expand_fun_eq)
   242 
   264 
   243 lemma union_right_cancel [simp]: "(M + K = N + K) = (M = (N::'a multiset))"
   265 lemma union_right_cancel [simp]: "(M + K = N + K) = (M = (N::'a multiset))"
   244   by (simp add: union_def expand_fun_eq)
   266 by (simp add: union_def in_multiset expand_fun_eq)
   245 
   267 
   246 lemma union_left_cancel [simp]: "(K + M = K + N) = (M = (N::'a multiset))"
   268 lemma union_left_cancel [simp]: "(K + M = K + N) = (M = (N::'a multiset))"
   247   by (simp add: union_def expand_fun_eq)
   269 by (simp add: union_def in_multiset expand_fun_eq)
   248 
   270 
   249 lemma union_is_single:
   271 lemma union_is_single:
   250     "(M + N = {#a#}) = (M = {#a#} \<and> N={#} \<or> M = {#} \<and> N = {#a#})"
   272   "(M + N = {#a#}) = (M = {#a#} \<and> N={#} \<or> M = {#} \<and> N = {#a#})"
   251   apply (simp add: Mempty_def single_def union_def add_is_1 expand_fun_eq)
   273 apply (simp add: Mempty_def single_def union_def in_multiset add_is_1 expand_fun_eq)
   252   apply blast
   274 apply blast
   253   done
   275 done
   254 
   276 
   255 lemma single_is_union:
   277 lemma single_is_union:
   256      "({#a#} = M + N) = ({#a#} = M \<and> N = {#} \<or> M = {#} \<and> {#a#} = N)"
   278      "({#a#} = M + N) = ({#a#} = M \<and> N = {#} \<or> M = {#} \<and> {#a#} = N)"
   257   apply (unfold Mempty_def single_def union_def)
   279 apply (unfold Mempty_def single_def union_def)
   258   apply (simp add: add_is_1 one_is_add expand_fun_eq)
   280 apply (simp add: add_is_1 one_is_add in_multiset expand_fun_eq)
   259   apply (blast dest: sym)
   281 apply (blast dest: sym)
   260   done
   282 done
   261 
   283 
   262 lemma add_eq_conv_diff:
   284 lemma add_eq_conv_diff:
   263   "(M + {#a#} = N + {#b#}) =
   285   "(M + {#a#} = N + {#b#}) =
   264    (M = N \<and> a = b \<or> M = N - {#a#} + {#b#} \<and> N = M - {#b#} + {#a#})"
   286    (M = N \<and> a = b \<or> M = N - {#a#} + {#b#} \<and> N = M - {#b#} + {#a#})"
   265   using [[simproc del: neq]]
   287   using [[simproc del: neq]]
   266   apply (unfold single_def union_def diff_def)
   288   apply (unfold single_def union_def diff_def)
   267   apply (simp (no_asm) add: expand_fun_eq)
   289   apply (simp (no_asm) add: in_multiset expand_fun_eq)
   268   apply (rule conjI, force, safe, simp_all)
   290   apply (rule conjI, force, safe, simp_all)
   269   apply (simp add: eq_sym_conv)
   291   apply (simp add: eq_sym_conv)
   270   done
   292   done
   271 
   293 
   272 declare Rep_multiset_inject [symmetric, simp del]
   294 declare Rep_multiset_inject [symmetric, simp del]
   288 lemma multi_union_self_other_eq: 
   310 lemma multi_union_self_other_eq: 
   289   "(A::'a multiset) + X = A + Y \<Longrightarrow> X = Y"
   311   "(A::'a multiset) + X = A + Y \<Longrightarrow> X = Y"
   290   by (induct A arbitrary: X Y, auto)
   312   by (induct A arbitrary: X Y, auto)
   291 
   313 
   292 lemma multi_self_add_other_not_self[simp]: "(A = A + {#x#}) = False"
   314 lemma multi_self_add_other_not_self[simp]: "(A = A + {#x#}) = False"
   293 proof -
   315 by (metis single_not_empty union_empty union_left_cancel)
   294   {
       
   295     assume a: "A = A + {#x#}"
       
   296     have "A = A + {#}" by simp
       
   297     hence "A + {#} = A + {#x#}" using a by auto 
       
   298     hence "{#} = {#x#}"
       
   299       by - (drule multi_union_self_other_eq)
       
   300     hence False by auto
       
   301   }
       
   302   thus ?thesis by blast
       
   303 qed
       
   304 
   316 
   305 lemma insert_noteq_member: 
   317 lemma insert_noteq_member: 
   306   assumes BC: "B + {#b#} = C + {#c#}"
   318   assumes BC: "B + {#b#} = C + {#c#}"
   307    and bnotc: "b \<noteq> c"
   319    and bnotc: "b \<noteq> c"
   308   shows "c \<in># B"
   320   shows "c \<in># B"
   312   hence "c \<in># B + {#b#}" using BC by simp
   324   hence "c \<in># B + {#b#}" using BC by simp
   313   thus "c \<in># B" using nc by simp
   325   thus "c \<in># B" using nc by simp
   314 qed
   326 qed
   315 
   327 
   316 
   328 
       
   329 lemma add_eq_conv_ex:
       
   330   "(M + {#a#} = N + {#b#}) =
       
   331     (M = N \<and> a = b \<or> (\<exists>K. M = K + {#b#} \<and> N = K + {#a#}))"
       
   332 by (auto simp add: add_eq_conv_diff)
       
   333 
       
   334 
       
   335 lemma empty_multiset_count:
       
   336   "(\<forall>x. count A x = 0) = (A = {#})"
       
   337 by(metis count_empty multiset_eq_conv_count_eq)
       
   338 
       
   339 
   317 subsubsection {* Intersection *}
   340 subsubsection {* Intersection *}
   318 
   341 
   319 lemma multiset_inter_count:
   342 lemma multiset_inter_count:
   320     "count (A #\<inter> B) x = min (count A x) (count B x)"
   343   "count (A #\<inter> B) x = min (count A x) (count B x)"
   321   by (simp add: multiset_inter_def min_def)
   344 by (simp add: multiset_inter_def min_def)
   322 
   345 
   323 lemma multiset_inter_commute: "A #\<inter> B = B #\<inter> A"
   346 lemma multiset_inter_commute: "A #\<inter> B = B #\<inter> A"
   324   by (simp add: multiset_eq_conv_count_eq multiset_inter_count
   347 by (simp add: multiset_eq_conv_count_eq multiset_inter_count
   325     min_max.inf_commute)
   348     min_max.inf_commute)
   326 
   349 
   327 lemma multiset_inter_assoc: "A #\<inter> (B #\<inter> C) = A #\<inter> B #\<inter> C"
   350 lemma multiset_inter_assoc: "A #\<inter> (B #\<inter> C) = A #\<inter> B #\<inter> C"
   328   by (simp add: multiset_eq_conv_count_eq multiset_inter_count
   351 by (simp add: multiset_eq_conv_count_eq multiset_inter_count
   329     min_max.inf_assoc)
   352     min_max.inf_assoc)
   330 
   353 
   331 lemma multiset_inter_left_commute: "A #\<inter> (B #\<inter> C) = B #\<inter> (A #\<inter> C)"
   354 lemma multiset_inter_left_commute: "A #\<inter> (B #\<inter> C) = B #\<inter> (A #\<inter> C)"
   332   by (simp add: multiset_eq_conv_count_eq multiset_inter_count min_def)
   355 by (simp add: multiset_eq_conv_count_eq multiset_inter_count min_def)
   333 
   356 
   334 lemmas multiset_inter_ac =
   357 lemmas multiset_inter_ac =
   335   multiset_inter_commute
   358   multiset_inter_commute
   336   multiset_inter_assoc
   359   multiset_inter_assoc
   337   multiset_inter_left_commute
   360   multiset_inter_left_commute
   343   apply (erule_tac x = a in allE)
   366   apply (erule_tac x = a in allE)
   344   apply auto
   367   apply auto
   345   done
   368   done
   346 
   369 
   347 
   370 
   348 subsection {* Induction over multisets *}
   371 subsubsection {* Comprehension (filter) *}
       
   372 
       
   373 lemma MCollect_empty[simp, code func]: "MCollect {#} P = {#}"
       
   374 by(simp add:MCollect_def Mempty_def Abs_multiset_inject in_multiset expand_fun_eq)
       
   375 
       
   376 lemma MCollect_single[simp, code func]:
       
   377   "MCollect {#x#} P = (if P x then {#x#} else {#})"
       
   378 by(simp add:MCollect_def Mempty_def single_def Abs_multiset_inject in_multiset expand_fun_eq)
       
   379 
       
   380 lemma MCollect_union[simp, code func]:
       
   381   "MCollect (M+N) f = MCollect M f + MCollect N f"
       
   382 by(simp add:MCollect_def union_def Abs_multiset_inject in_multiset expand_fun_eq)
       
   383 
       
   384 
       
   385 subsection {* Induction and case splits *}
   349 
   386 
   350 lemma setsum_decr:
   387 lemma setsum_decr:
   351   "finite F ==> (0::nat) < f a ==>
   388   "finite F ==> (0::nat) < f a ==>
   352     setsum (f (a := f a - 1)) F = (if a\<in>F then setsum f F - 1 else setsum f F)"
   389     setsum (f (a := f a - 1)) F = (if a\<in>F then setsum f F - 1 else setsum f F)"
   353   apply (induct rule: finite_induct)
   390   apply (induct rule: finite_induct)
   408     apply (subgoal_tac "f(b := f b + 1) = (\<lambda>a. f a + (if a=b then 1 else 0))")
   445     apply (subgoal_tac "f(b := f b + 1) = (\<lambda>a. f a + (if a=b then 1 else 0))")
   409      prefer 2
   446      prefer 2
   410      apply (simp add: expand_fun_eq)
   447      apply (simp add: expand_fun_eq)
   411     apply (erule ssubst)
   448     apply (erule ssubst)
   412     apply (erule Abs_multiset_inverse [THEN subst])
   449     apply (erule Abs_multiset_inverse [THEN subst])
   413     apply (erule add [unfolded defns, simplified])
   450     apply (drule add [unfolded defns, simplified])
       
   451     apply(simp add:in_multiset)
   414     done
   452     done
   415 qed
   453 qed
   416 
       
   417 lemma empty_multiset_count:
       
   418   "(\<forall>x. count A x = 0) = (A = {#})"
       
   419   apply (rule iffI)
       
   420    apply (induct A, simp)
       
   421    apply (erule_tac x=x in allE)
       
   422    apply auto
       
   423   done
       
   424 
       
   425 subsection {* Case splits *}
       
   426 
   454 
   427 lemma multi_nonempty_split: "M \<noteq> {#} \<Longrightarrow> \<exists>A a. M = A + {#a#}"
   455 lemma multi_nonempty_split: "M \<noteq> {#} \<Longrightarrow> \<exists>A a. M = A + {#a#}"
   428   by (induct M, auto)
   456   by (induct M, auto)
   429 
   457 
   430 lemma multiset_cases [cases type, case_names empty add]:
   458 lemma multiset_cases [cases type, case_names empty add]:
   443 lemma multi_member_split: "x \<in># M \<Longrightarrow> \<exists>A. M = A + {#x#}"
   471 lemma multi_member_split: "x \<in># M \<Longrightarrow> \<exists>A. M = A + {#x#}"
   444   apply (cases M, simp)
   472   apply (cases M, simp)
   445   apply (rule_tac x="M - {#x#}" in exI, simp)
   473   apply (rule_tac x="M - {#x#}" in exI, simp)
   446   done
   474   done
   447 
   475 
   448 lemma MCollect_preserves_multiset:
       
   449     "M \<in> multiset ==> (\<lambda>x. if P x then M x else 0) \<in> multiset"
       
   450   apply (simp add: multiset_def)
       
   451   apply (rule finite_subset, auto)
       
   452   done
       
   453 
       
   454 lemma count_MCollect [simp]:
       
   455     "count {# x:M. P x #} a = (if P a then count M a else 0)"
       
   456   by (simp add: count_def MCollect_def MCollect_preserves_multiset)
       
   457 
       
   458 lemma set_of_MCollect [simp]: "set_of {# x:M. P x #} = set_of M \<inter> {x. P x}"
       
   459   by (auto simp add: set_of_def)
       
   460 
       
   461 lemma multiset_partition: "M = {# x:M. P x #} + {# x:M. \<not> P x #}"
   476 lemma multiset_partition: "M = {# x:M. P x #} + {# x:M. \<not> P x #}"
   462   by (subst multiset_eq_conv_count_eq, auto)
   477   by (subst multiset_eq_conv_count_eq, auto)
   463 
   478 
   464 lemma add_eq_conv_ex:
       
   465   "(M + {#a#} = N + {#b#}) =
       
   466     (M = N \<and> a = b \<or> (\<exists>K. M = K + {#b#} \<and> N = K + {#a#}))"
       
   467   by (auto simp add: add_eq_conv_diff)
       
   468 
       
   469 declare multiset_typedef [simp del]
   479 declare multiset_typedef [simp del]
   470 
       
   471 lemma nonempty_has_size: "(S \<noteq> {#}) = (0 < size S)"
       
   472   apply (rule iffI)
       
   473    apply (case_tac "size S = 0")
       
   474     apply clarsimp
       
   475    apply (subst (asm) neq0_conv)
       
   476    apply auto
       
   477   done
       
   478 
   480 
   479 lemma multi_drop_mem_not_eq: "c \<in># B \<Longrightarrow> B - {#c#} \<noteq> B"
   481 lemma multi_drop_mem_not_eq: "c \<in># B \<Longrightarrow> B - {#c#} \<noteq> B"
   480   by (cases "B={#}", auto dest: multi_member_split)
   482   by (cases "B={#}", auto dest: multi_member_split)
   481 
   483 
   482 subsection {* Multiset orderings *}
   484 subsection {* Orderings *}
   483 
   485 
   484 subsubsection {* Well-foundedness *}
   486 subsubsection {* Well-foundedness *}
   485 
   487 
   486 definition
   488 definition
   487   mult1 :: "('a \<times> 'a) set => ('a multiset \<times> 'a multiset) set" where
   489   mult1 :: "('a \<times> 'a) set => ('a multiset \<times> 'a multiset) set" where
   828 apply(erule union_le_mono[OF mult_le_refl])
   830 apply(erule union_le_mono[OF mult_le_refl])
   829 done
   831 done
   830 
   832 
   831 subsection {* Link with lists *}
   833 subsection {* Link with lists *}
   832 
   834 
   833 consts
   835 primrec multiset_of :: "'a list \<Rightarrow> 'a multiset" where
   834   multiset_of :: "'a list \<Rightarrow> 'a multiset"
   836 "multiset_of [] = {#}" |
   835 primrec
   837 "multiset_of (a # x) = multiset_of x + {# a #}"
   836   "multiset_of [] = {#}"
       
   837   "multiset_of (a # x) = multiset_of x + {# a #}"
       
   838 
   838 
   839 lemma multiset_of_zero_iff[simp]: "(multiset_of x = {#}) = (x = [])"
   839 lemma multiset_of_zero_iff[simp]: "(multiset_of x = {#}) = (x = [])"
   840   by (induct x) auto
   840   by (induct x) auto
   841 
   841 
   842 lemma multiset_of_zero_iff_right[simp]: "({#} = multiset_of x) = (x = [])"
   842 lemma multiset_of_zero_iff_right[simp]: "({#} = multiset_of x) = (x = [])"
  1039 lemma mset_less_diff_self: "c \<in># B \<Longrightarrow> B - {#c#} \<subset># B"
  1039 lemma mset_less_diff_self: "c \<in># B \<Longrightarrow> B - {#c#} \<subset># B"
  1040   by (auto simp: mset_le_def mset_less_def multi_drop_mem_not_eq)
  1040   by (auto simp: mset_le_def mset_less_def multi_drop_mem_not_eq)
  1041 
  1041 
  1042 subsection {* Strong induction and subset induction for multisets *}
  1042 subsection {* Strong induction and subset induction for multisets *}
  1043 
  1043 
  1044 subsubsection {* Well-foundedness of proper subset operator *}
  1044 text {* Well-foundedness of proper subset operator: *}
  1045 
  1045 
  1046 definition
  1046 definition
  1047   mset_less_rel  :: "('a multiset * 'a multiset) set" 
  1047   mset_less_rel  :: "('a multiset * 'a multiset) set" 
  1048   where
  1048   where
  1049   --{* proper multiset subset *}
  1049   --{* proper multiset subset *}
  1065   apply (unfold mset_less_rel_def)
  1065   apply (unfold mset_less_rel_def)
  1066   apply (rule wf_measure [THEN wf_subset, where f1=size])
  1066   apply (rule wf_measure [THEN wf_subset, where f1=size])
  1067   apply (clarsimp simp: measure_def inv_image_def mset_less_size)
  1067   apply (clarsimp simp: measure_def inv_image_def mset_less_size)
  1068   done
  1068   done
  1069 
  1069 
  1070 subsubsection {* The induction rules *}
  1070 text {* The induction rules: *}
  1071 
  1071 
  1072 lemma full_multiset_induct [case_names less]:
  1072 lemma full_multiset_induct [case_names less]:
  1073   assumes ih: "\<And>B. \<forall>A. A \<subset># B \<longrightarrow> P A \<Longrightarrow> P B"
  1073   assumes ih: "\<And>B. \<forall>A. A \<subset># B \<longrightarrow> P A \<Longrightarrow> P B"
  1074   shows "P B"
  1074   shows "P B"
  1075   apply (rule wf_mset_less_rel [THEN wf_induct])
  1075   apply (rule wf_mset_less_rel [THEN wf_induct])
  1096       with P show "P F" .
  1096       with P show "P F" .
  1097     qed
  1097     qed
  1098   qed
  1098   qed
  1099 qed 
  1099 qed 
  1100 
  1100 
  1101 subsection {* Multiset extensionality *}
  1101 text{* A consequence: Extensionality. *}
  1102 
  1102 
  1103 lemma multi_count_eq: 
  1103 lemma multi_count_eq: 
  1104   "(\<forall>x. count A x = count B x) = (A = B)"
  1104   "(\<forall>x. count A x = count B x) = (A = B)"
  1105   apply (rule iffI)
  1105   apply (rule iffI)
  1106    prefer 2
  1106    prefer 2
  1285 proof -
  1285 proof -
  1286   from a obtain A' where "A = A' + {#a#}" by (blast dest: multi_member_split)
  1286   from a obtain A' where "A = A' + {#a#}" by (blast dest: multi_member_split)
  1287   thus ?thesis by simp
  1287   thus ?thesis by simp
  1288 qed
  1288 qed
  1289 
  1289 
       
  1290 text{* A note on code generation: When defining some
       
  1291 function containing a subterm @{term"fold_mset F"}, code generation is
       
  1292 not automatic. When interpreting locale @{text left_commutative} with
       
  1293 @{text F}, the would be code thms for @{const fold_mset} become thms like
       
  1294 @{term"fold_mset F z {#} = z"} where @{text F} is not a pattern but contains
       
  1295 defined symbols, i.e.\ is not a code thm. Hence a separate constant with its
       
  1296 own code thms needs to be introduced for @{text F}. See the image operator
       
  1297 below. *}
       
  1298 
       
  1299 subsection {* Image *}
       
  1300 
       
  1301 definition [code func del]: "image_mset f == fold_mset (op + o single o f) {#}"
       
  1302 
       
  1303 interpretation image_left_comm: left_commutative["op + o single o f"]
       
  1304 by(unfold_locales)(simp add:union_ac)
       
  1305 
       
  1306 lemma image_mset_empty[simp,code func]: "image_mset f {#} = {#}"
       
  1307 by(simp add:image_mset_def)
       
  1308 
       
  1309 lemma image_mset_single[simp,code func]: "image_mset f {#x#} = {#f x#}"
       
  1310 by(simp add:image_mset_def)
       
  1311 
       
  1312 lemma image_mset_insert:
       
  1313   "image_mset f (M + {#a#}) = image_mset f M + {#f a#}"
       
  1314 by(simp add:image_mset_def add_ac)
       
  1315 
       
  1316 lemma image_mset_union[simp, code func]:
       
  1317   "image_mset f (M+N) = image_mset f M + image_mset f N"
       
  1318 apply(induct N)
       
  1319  apply simp
       
  1320 apply(simp add:union_assoc[symmetric] image_mset_insert)
       
  1321 done
       
  1322 
       
  1323 lemma size_image_mset[simp]: "size(image_mset f M) = size M"
       
  1324 by(induct M) simp_all
       
  1325 
       
  1326 lemma image_mset_is_empty_iff[simp]: "image_mset f M = {#} \<longleftrightarrow> M={#}"
       
  1327 by (cases M) auto
       
  1328 
       
  1329 
       
  1330 syntax comprehension1_mset :: "'a \<Rightarrow> 'b \<Rightarrow> 'b multiset \<Rightarrow> 'a multiset"
       
  1331        ("({#_/. _ :# _#})")
       
  1332 translations "{#e. x:#M#}" == "CONST image_mset (%x. e) M"
       
  1333 
       
  1334 syntax comprehension2_mset :: "'a \<Rightarrow> 'b \<Rightarrow> 'b multiset \<Rightarrow> bool \<Rightarrow> 'a multiset"
       
  1335        ("({#_/ | _ :# _./ _#})")
       
  1336 translations
       
  1337   "{#e | x:#M. P#}" => "{#e. x :# {# x:M. P#}#}"
       
  1338 
       
  1339 text{* This allows to write not just filters like @{term"{#x:M. x<c#}"}
       
  1340 but also images like @{term"{#x+x. x:#M #}"}
       
  1341 and @{term[source]"{#x+x|x:#M. x<c#}"}, where the latter is currently
       
  1342 displayed as @{term"{#x+x|x:#M. x<c#}"}. *}
       
  1343 
  1290 end
  1344 end