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 *} |
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 |