src/HOL/Library/Multiset.thy
changeset 26033 278025d5282d
parent 26016 f9d1bf2fc59c
child 26143 314c0bcb7df7
equal deleted inserted replaced
26032:377b7aa0b5b5 26033:278025d5282d
    44   "a :# M == 0 < count M a"
    44   "a :# M == 0 < count M a"
    45 
    45 
    46 notation (xsymbols) Melem (infix "\<in>#" 50)
    46 notation (xsymbols) Melem (infix "\<in>#" 50)
    47 
    47 
    48 syntax
    48 syntax
    49   "_MCollect" :: "pttrn => 'a multiset => bool => 'a multiset"    ("(1{# _ : _./ _#})")
    49   "_MCollect" :: "pttrn => 'a multiset => bool => 'a multiset"    ("(1{# _ :# _./ _#})")
    50 translations
    50 translations
    51   "{#x:M. P#}" == "CONST MCollect M (\<lambda>x. P)"
    51   "{#x :# M. P#}" == "CONST MCollect M (\<lambda>x. P)"
    52 
    52 
    53 definition
    53 definition
    54   set_of :: "'a multiset => 'a set" where
    54   set_of :: "'a multiset => 'a set" where
    55   "set_of M = {x. x :# M}"
    55   "set_of M = {x. x :# M}"
    56 
    56 
   176 
   176 
   177 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"
   178 by (simp add: count_def diff_def in_multiset)
   178 by (simp add: count_def diff_def in_multiset)
   179 
   179 
   180 lemma count_MCollect [simp]:
   180 lemma count_MCollect [simp]:
   181   "count {# x:M. P x #} a = (if P a then count M a else 0)"
   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)
   182 by (simp add: count_def MCollect_def in_multiset)
   183 
   183 
   184 
   184 
   185 subsubsection {* Set of elements *}
   185 subsubsection {* Set of elements *}
   186 
   186 
   197 by(auto simp: set_of_def Mempty_def in_multiset count_def expand_fun_eq)
   197 by(auto simp: set_of_def Mempty_def in_multiset count_def expand_fun_eq)
   198 
   198 
   199 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)"
   200 by (auto simp add: set_of_def)
   200 by (auto simp add: set_of_def)
   201 
   201 
   202 lemma set_of_MCollect [simp]: "set_of {# x:M. P x #} = set_of M \<inter> {x. P x}"
   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)
   203 by (auto simp add: set_of_def)
   204 
   204 
   205 
   205 
   206 subsubsection {* Size *}
   206 subsubsection {* Size *}
   207 
   207 
   471 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#}"
   472   apply (cases M, simp)
   472   apply (cases M, simp)
   473   apply (rule_tac x="M - {#x#}" in exI, simp)
   473   apply (rule_tac x="M - {#x#}" in exI, simp)
   474   done
   474   done
   475 
   475 
   476 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 #}"
   477   by (subst multiset_eq_conv_count_eq, auto)
   477   by (subst multiset_eq_conv_count_eq, auto)
   478 
   478 
   479 declare multiset_typedef [simp del]
   479 declare multiset_typedef [simp del]
   480 
   480 
   481 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"
   676   apply (cut_tac M = K and P = "\<lambda>x. (x, a) \<in> r" in multiset_partition)
   676   apply (cut_tac M = K and P = "\<lambda>x. (x, a) \<in> r" in multiset_partition)
   677   apply (erule_tac P = "\<forall>k \<in> set_of K. ?P k" in rev_mp)
   677   apply (erule_tac P = "\<forall>k \<in> set_of K. ?P k" in rev_mp)
   678   apply (erule ssubst)
   678   apply (erule ssubst)
   679   apply (simp add: Ball_def, auto)
   679   apply (simp add: Ball_def, auto)
   680   apply (subgoal_tac
   680   apply (subgoal_tac
   681     "((I + {# x : K. (x, a) \<in> r #}) + {# x : K. (x, a) \<notin> r #},
   681     "((I + {# x :# K. (x, a) \<in> r #}) + {# x :# K. (x, a) \<notin> r #},
   682       (I + {# x : K. (x, a) \<in> r #}) + J') \<in> mult r")
   682       (I + {# x :# K. (x, a) \<in> r #}) + J') \<in> mult r")
   683    prefer 2
   683    prefer 2
   684    apply force
   684    apply force
   685   apply (simp (no_asm_use) add: union_assoc [symmetric] mult_def)
   685   apply (simp (no_asm_use) add: union_assoc [symmetric] mult_def)
   686   apply (erule trancl_trans)
   686   apply (erule trancl_trans)
   687   apply (rule r_into_trancl)
   687   apply (rule r_into_trancl)
  1332 translations "{#e. x:#M#}" == "CONST image_mset (%x. e) M"
  1332 translations "{#e. x:#M#}" == "CONST image_mset (%x. e) M"
  1333 
  1333 
  1334 syntax comprehension2_mset :: "'a \<Rightarrow> 'b \<Rightarrow> 'b multiset \<Rightarrow> bool \<Rightarrow> 'a multiset"
  1334 syntax comprehension2_mset :: "'a \<Rightarrow> 'b \<Rightarrow> 'b multiset \<Rightarrow> bool \<Rightarrow> 'a multiset"
  1335        ("({#_/ | _ :# _./ _#})")
  1335        ("({#_/ | _ :# _./ _#})")
  1336 translations
  1336 translations
  1337   "{#e | x:#M. P#}" => "{#e. x :# {# x:M. P#}#}"
  1337   "{#e | x:#M. P#}" => "{#e. x :# {# x:#M. P#}#}"
  1338 
  1338 
  1339 text{* This allows to write not just filters like @{term"{#x:M. x<c#}"}
  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 #}"}
  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
  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#}"}. *}
  1342 displayed as @{term"{#x+x|x:#M. x<c#}"}. *}
  1343 
  1343 
  1344 end
  1344 end