equal
deleted
inserted
replaced
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 |