32 mset_of :: "i=>i" where |
32 mset_of :: "i=>i" where |
33 "mset_of(M) == domain(M)" |
33 "mset_of(M) == domain(M)" |
34 |
34 |
35 definition |
35 definition |
36 munion :: "[i, i] => i" (infixl "+#" 65) where |
36 munion :: "[i, i] => i" (infixl "+#" 65) where |
37 "M +# N == \<lambda>x \<in> mset_of(M) Un mset_of(N). |
37 "M +# N == \<lambda>x \<in> mset_of(M) \<union> mset_of(N). |
38 if x \<in> mset_of(M) Int mset_of(N) then (M`x) #+ (N`x) |
38 if x \<in> mset_of(M) \<inter> mset_of(N) then (M`x) #+ (N`x) |
39 else (if x \<in> mset_of(M) then M`x else N`x)" |
39 else (if x \<in> mset_of(M) then M`x else N`x)" |
40 |
40 |
41 definition |
41 definition |
42 (*convert a function to a multiset by eliminating 0*) |
42 (*convert a function to a multiset by eliminating 0*) |
43 normalize :: "i => i" where |
43 normalize :: "i => i" where |
72 abbreviation |
72 abbreviation |
73 melem :: "[i,i] => o" ("(_/ :# _)" [50, 51] 50) where |
73 melem :: "[i,i] => o" ("(_/ :# _)" [50, 51] 50) where |
74 "a :# M == a \<in> mset_of(M)" |
74 "a :# M == a \<in> mset_of(M)" |
75 |
75 |
76 syntax |
76 syntax |
77 "_MColl" :: "[pttrn, i, o] => i" ("(1{# _ : _./ _#})") |
77 "_MColl" :: "[pttrn, i, o] => i" ("(1{# _ \<in> _./ _#})") |
78 syntax (xsymbols) |
78 syntax (xsymbols) |
79 "_MColl" :: "[pttrn, i, o] => i" ("(1{# _ \<in> _./ _#})") |
79 "_MColl" :: "[pttrn, i, o] => i" ("(1{# _ \<in> _./ _#})") |
80 translations |
80 translations |
81 "{#x \<in> M. P#}" == "CONST MCollect(M, %x. P)" |
81 "{#x \<in> M. P#}" == "CONST MCollect(M, %x. P)" |
82 |
82 |
142 declare domainE [rule del] |
142 declare domainE [rule del] |
143 |
143 |
144 |
144 |
145 text{* A useful simplification rule *} |
145 text{* A useful simplification rule *} |
146 lemma multiset_fun_iff: |
146 lemma multiset_fun_iff: |
147 "(f \<in> A -> nat-{0}) <-> f \<in> A->nat&(\<forall>a \<in> A. f`a \<in> nat & 0 < f`a)" |
147 "(f \<in> A -> nat-{0}) \<longleftrightarrow> f \<in> A->nat&(\<forall>a \<in> A. f`a \<in> nat & 0 < f`a)" |
148 apply safe |
148 apply safe |
149 apply (rule_tac [4] B1 = "range (f) " in Pi_mono [THEN subsetD]) |
149 apply (rule_tac [4] B1 = "range (f) " in Pi_mono [THEN subsetD]) |
150 apply (auto intro!: Ord_0_lt |
150 apply (auto intro!: Ord_0_lt |
151 dest: apply_type Diff_subset [THEN Pi_mono, THEN subsetD] |
151 dest: apply_type Diff_subset [THEN Pi_mono, THEN subsetD] |
152 simp add: range_of_fun apply_iff) |
152 simp add: range_of_fun apply_iff) |
168 apply (frule FinD, clarify) |
168 apply (frule FinD, clarify) |
169 apply (rule_tac x = "domain (M) " in exI) |
169 apply (rule_tac x = "domain (M) " in exI) |
170 apply (blast intro: Fin_into_Finite) |
170 apply (blast intro: Fin_into_Finite) |
171 done |
171 done |
172 |
172 |
173 lemma Mult_iff_multiset: "M \<in> Mult(A) <-> multiset(M) & mset_of(M)\<subseteq>A" |
173 lemma Mult_iff_multiset: "M \<in> Mult(A) \<longleftrightarrow> multiset(M) & mset_of(M)\<subseteq>A" |
174 by (blast dest: Mult_into_multiset intro: multiset_into_Mult) |
174 by (blast dest: Mult_into_multiset intro: multiset_into_Mult) |
175 |
175 |
176 lemma multiset_iff_Mult_mset_of: "multiset(M) <-> M \<in> Mult(mset_of(M))" |
176 lemma multiset_iff_Mult_mset_of: "multiset(M) \<longleftrightarrow> M \<in> Mult(mset_of(M))" |
177 by (auto simp add: Mult_iff_multiset) |
177 by (auto simp add: Mult_iff_multiset) |
178 |
178 |
179 |
179 |
180 text{*The @{term multiset} operator*} |
180 text{*The @{term multiset} operator*} |
181 |
181 |
191 by (simp add: multiset_def mset_of_def, auto) |
191 by (simp add: multiset_def mset_of_def, auto) |
192 |
192 |
193 lemma mset_of_0 [iff]: "mset_of(0) = 0" |
193 lemma mset_of_0 [iff]: "mset_of(0) = 0" |
194 by (simp add: mset_of_def) |
194 by (simp add: mset_of_def) |
195 |
195 |
196 lemma mset_is_0_iff: "multiset(M) ==> mset_of(M)=0 <-> M=0" |
196 lemma mset_is_0_iff: "multiset(M) ==> mset_of(M)=0 \<longleftrightarrow> M=0" |
197 by (auto simp add: multiset_def mset_of_def) |
197 by (auto simp add: multiset_def mset_of_def) |
198 |
198 |
199 lemma mset_of_single [iff]: "mset_of({#a#}) = {a}" |
199 lemma mset_of_single [iff]: "mset_of({#a#}) = {a}" |
200 by (simp add: msingle_def mset_of_def) |
200 by (simp add: msingle_def mset_of_def) |
201 |
201 |
202 lemma mset_of_union [iff]: "mset_of(M +# N) = mset_of(M) Un mset_of(N)" |
202 lemma mset_of_union [iff]: "mset_of(M +# N) = mset_of(M) \<union> mset_of(N)" |
203 by (simp add: mset_of_def munion_def) |
203 by (simp add: mset_of_def munion_def) |
204 |
204 |
205 lemma mset_of_diff [simp]: "mset_of(M)\<subseteq>A ==> mset_of(M -# N) \<subseteq> A" |
205 lemma mset_of_diff [simp]: "mset_of(M)\<subseteq>A ==> mset_of(M -# N) \<subseteq> A" |
206 by (auto simp add: mdiff_def multiset_def normalize_def mset_of_def) |
206 by (auto simp add: mdiff_def multiset_def normalize_def mset_of_def) |
207 |
207 |
208 (* msingle *) |
208 (* msingle *) |
209 |
209 |
210 lemma msingle_not_0 [iff]: "{#a#} \<noteq> 0 & 0 \<noteq> {#a#}" |
210 lemma msingle_not_0 [iff]: "{#a#} \<noteq> 0 & 0 \<noteq> {#a#}" |
211 by (simp add: msingle_def) |
211 by (simp add: msingle_def) |
212 |
212 |
213 lemma msingle_eq_iff [iff]: "({#a#} = {#b#}) <-> (a = b)" |
213 lemma msingle_eq_iff [iff]: "({#a#} = {#b#}) \<longleftrightarrow> (a = b)" |
214 by (simp add: msingle_def) |
214 by (simp add: msingle_def) |
215 |
215 |
216 lemma msingle_multiset [iff,TC]: "multiset({#a#})" |
216 lemma msingle_multiset [iff,TC]: "multiset({#a#})" |
217 apply (simp add: multiset_def msingle_def) |
217 apply (simp add: multiset_def msingle_def) |
218 apply (rule_tac x = "{a}" in exI) |
218 apply (rule_tac x = "{a}" in exI) |
246 |
246 |
247 (* union *) |
247 (* union *) |
248 |
248 |
249 lemma munion_multiset [simp]: "[| multiset(M); multiset(N) |] ==> multiset(M +# N)" |
249 lemma munion_multiset [simp]: "[| multiset(M); multiset(N) |] ==> multiset(M +# N)" |
250 apply (unfold multiset_def munion_def mset_of_def, auto) |
250 apply (unfold multiset_def munion_def mset_of_def, auto) |
251 apply (rule_tac x = "A Un Aa" in exI) |
251 apply (rule_tac x = "A \<union> Aa" in exI) |
252 apply (auto intro!: lam_type intro: Finite_Un simp add: multiset_fun_iff zero_less_add) |
252 apply (auto intro!: lam_type intro: Finite_Un simp add: multiset_fun_iff zero_less_add) |
253 done |
253 done |
254 |
254 |
255 (* difference *) |
255 (* difference *) |
256 |
256 |
296 apply (unfold multiset_def munion_def mdiff_def msingle_def normalize_def mset_of_def) |
296 apply (unfold multiset_def munion_def mdiff_def msingle_def normalize_def mset_of_def) |
297 apply (auto cong add: if_cong simp add: ltD multiset_fun_iff funrestrict_def subset_Un_iff2 [THEN iffD1]) |
297 apply (auto cong add: if_cong simp add: ltD multiset_fun_iff funrestrict_def subset_Un_iff2 [THEN iffD1]) |
298 prefer 2 apply (force intro!: lam_type) |
298 prefer 2 apply (force intro!: lam_type) |
299 apply (subgoal_tac [2] "{x \<in> A \<union> {a} . x \<noteq> a \<and> x \<in> A} = A") |
299 apply (subgoal_tac [2] "{x \<in> A \<union> {a} . x \<noteq> a \<and> x \<in> A} = A") |
300 apply (rule fun_extension, auto) |
300 apply (rule fun_extension, auto) |
301 apply (drule_tac x = "A Un {a}" in spec) |
301 apply (drule_tac x = "A \<union> {a}" in spec) |
302 apply (simp add: Finite_Un) |
302 apply (simp add: Finite_Un) |
303 apply (force intro!: lam_type) |
303 apply (force intro!: lam_type) |
304 done |
304 done |
305 |
305 |
306 (** Count of elements **) |
306 (** Count of elements **) |
359 apply (erule not_emptyE) |
359 apply (erule not_emptyE) |
360 apply (auto simp add: mset_of_def mcount_def multiset_fun_iff) |
360 apply (auto simp add: mset_of_def mcount_def multiset_fun_iff) |
361 apply (blast dest!: fun_is_rel) |
361 apply (blast dest!: fun_is_rel) |
362 done |
362 done |
363 |
363 |
364 lemma msize_eq_0_iff: "multiset(M) ==> msize(M)=#0 <-> M=0" |
364 lemma msize_eq_0_iff: "multiset(M) ==> msize(M)=#0 \<longleftrightarrow> M=0" |
365 apply (simp add: msize_def, auto) |
365 apply (simp add: msize_def, auto) |
366 apply (rule_tac P = "setsum (?u,?v) \<noteq> #0" in swap) |
366 apply (rule_tac P = "setsum (?u,?v) \<noteq> #0" in swap) |
367 apply blast |
367 apply blast |
368 apply (drule not_empty_multiset_imp_exist, assumption, clarify) |
368 apply (drule not_empty_multiset_imp_exist, assumption, clarify) |
369 apply (subgoal_tac "Finite (mset_of (M) - {a}) ") |
369 apply (subgoal_tac "Finite (mset_of (M) - {a}) ") |
376 apply (rule not_zneg_int_of [THEN bexE]) |
376 apply (rule not_zneg_int_of [THEN bexE]) |
377 apply (auto simp del: int_of_0 simp add: int_of_add [symmetric] int_of_0 [symmetric]) |
377 apply (auto simp del: int_of_0 simp add: int_of_add [symmetric] int_of_0 [symmetric]) |
378 done |
378 done |
379 |
379 |
380 lemma setsum_mcount_Int: |
380 lemma setsum_mcount_Int: |
381 "Finite(A) ==> setsum(%a. $# mcount(N, a), A Int mset_of(N)) |
381 "Finite(A) ==> setsum(%a. $# mcount(N, a), A \<inter> mset_of(N)) |
382 = setsum(%a. $# mcount(N, a), A)" |
382 = setsum(%a. $# mcount(N, a), A)" |
383 apply (induct rule: Finite_induct) |
383 apply (induct rule: Finite_induct) |
384 apply auto |
384 apply auto |
385 apply (subgoal_tac "Finite (B Int mset_of (N))") |
385 apply (subgoal_tac "Finite (B \<inter> mset_of (N))") |
386 prefer 2 apply (blast intro: subset_Finite) |
386 prefer 2 apply (blast intro: subset_Finite) |
387 apply (auto simp add: mcount_def Int_cons_left) |
387 apply (auto simp add: mcount_def Int_cons_left) |
388 done |
388 done |
389 |
389 |
390 lemma msize_union [simp]: |
390 lemma msize_union [simp]: |
410 apply (drule_tac [!] x=x in spec) |
410 apply (drule_tac [!] x=x in spec) |
411 apply (case_tac [2] "x \<in> Aa", case_tac "x \<in> A", auto) |
411 apply (case_tac [2] "x \<in> Aa", case_tac "x \<in> A", auto) |
412 done |
412 done |
413 |
413 |
414 lemma multiset_equality: |
414 lemma multiset_equality: |
415 "[| multiset(M); multiset(N) |]==> M=N<->(\<forall>a. mcount(M, a)=mcount(N, a))" |
415 "[| multiset(M); multiset(N) |]==> M=N\<longleftrightarrow>(\<forall>a. mcount(M, a)=mcount(N, a))" |
416 apply auto |
416 apply auto |
417 apply (subgoal_tac "mset_of (M) = mset_of (N) ") |
417 apply (subgoal_tac "mset_of (M) = mset_of (N) ") |
418 prefer 2 apply (blast intro: equality_lemma) |
418 prefer 2 apply (blast intro: equality_lemma) |
419 apply (simp add: multiset_def mset_of_def) |
419 apply (simp add: multiset_def mset_of_def) |
420 apply (auto simp add: multiset_fun_iff) |
420 apply (auto simp add: multiset_fun_iff) |
424 apply (auto simp add: mcount_def mset_of_def) |
424 apply (auto simp add: mcount_def mset_of_def) |
425 done |
425 done |
426 |
426 |
427 (** More algebraic properties of multisets **) |
427 (** More algebraic properties of multisets **) |
428 |
428 |
429 lemma munion_eq_0_iff [simp]: "[|multiset(M); multiset(N)|]==>(M +# N =0) <-> (M=0 & N=0)" |
429 lemma munion_eq_0_iff [simp]: "[|multiset(M); multiset(N)|]==>(M +# N =0) \<longleftrightarrow> (M=0 & N=0)" |
430 by (auto simp add: multiset_equality) |
430 by (auto simp add: multiset_equality) |
431 |
431 |
432 lemma empty_eq_munion_iff [simp]: "[|multiset(M); multiset(N)|]==>(0=M +# N) <-> (M=0 & N=0)" |
432 lemma empty_eq_munion_iff [simp]: "[|multiset(M); multiset(N)|]==>(0=M +# N) \<longleftrightarrow> (M=0 & N=0)" |
433 apply (rule iffI, drule sym) |
433 apply (rule iffI, drule sym) |
434 apply (simp_all add: multiset_equality) |
434 apply (simp_all add: multiset_equality) |
435 done |
435 done |
436 |
436 |
437 lemma munion_right_cancel [simp]: |
437 lemma munion_right_cancel [simp]: |
438 "[| multiset(M); multiset(N); multiset(K) |]==>(M +# K = N +# K)<->(M=N)" |
438 "[| multiset(M); multiset(N); multiset(K) |]==>(M +# K = N +# K)\<longleftrightarrow>(M=N)" |
439 by (auto simp add: multiset_equality) |
439 by (auto simp add: multiset_equality) |
440 |
440 |
441 lemma munion_left_cancel [simp]: |
441 lemma munion_left_cancel [simp]: |
442 "[|multiset(K); multiset(M); multiset(N)|] ==>(K +# M = K +# N) <-> (M = N)" |
442 "[|multiset(K); multiset(M); multiset(N)|] ==>(K +# M = K +# N) \<longleftrightarrow> (M = N)" |
443 by (auto simp add: multiset_equality) |
443 by (auto simp add: multiset_equality) |
444 |
444 |
445 lemma nat_add_eq_1_cases: "[| m \<in> nat; n \<in> nat |] ==> (m #+ n = 1) <-> (m=1 & n=0) | (m=0 & n=1)" |
445 lemma nat_add_eq_1_cases: "[| m \<in> nat; n \<in> nat |] ==> (m #+ n = 1) \<longleftrightarrow> (m=1 & n=0) | (m=0 & n=1)" |
446 by (induct_tac n) auto |
446 by (induct_tac n) auto |
447 |
447 |
448 lemma munion_is_single: |
448 lemma munion_is_single: |
449 "[|multiset(M); multiset(N)|] |
449 "[|multiset(M); multiset(N)|] |
450 ==> (M +# N = {#a#}) <-> (M={#a#} & N=0) | (M = 0 & N = {#a#})" |
450 ==> (M +# N = {#a#}) \<longleftrightarrow> (M={#a#} & N=0) | (M = 0 & N = {#a#})" |
451 apply (simp (no_asm_simp) add: multiset_equality) |
451 apply (simp (no_asm_simp) add: multiset_equality) |
452 apply safe |
452 apply safe |
453 apply simp_all |
453 apply simp_all |
454 apply (case_tac "aa=a") |
454 apply (case_tac "aa=a") |
455 apply (drule_tac [2] x = aa in spec) |
455 apply (drule_tac [2] x = aa in spec) |
465 apply (drule_tac x = aa in spec) |
465 apply (drule_tac x = aa in spec) |
466 apply (simp_all add: nat_add_eq_1_cases) |
466 apply (simp_all add: nat_add_eq_1_cases) |
467 done |
467 done |
468 |
468 |
469 lemma msingle_is_union: "[| multiset(M); multiset(N) |] |
469 lemma msingle_is_union: "[| multiset(M); multiset(N) |] |
470 ==> ({#a#} = M +# N) <-> ({#a#} = M & N=0 | M = 0 & {#a#} = N)" |
470 ==> ({#a#} = M +# N) \<longleftrightarrow> ({#a#} = M & N=0 | M = 0 & {#a#} = N)" |
471 apply (subgoal_tac " ({#a#} = M +# N) <-> (M +# N = {#a#}) ") |
471 apply (subgoal_tac " ({#a#} = M +# N) \<longleftrightarrow> (M +# N = {#a#}) ") |
472 apply (simp (no_asm_simp) add: munion_is_single) |
472 apply (simp (no_asm_simp) add: munion_is_single) |
473 apply blast |
473 apply blast |
474 apply (blast dest: sym) |
474 apply (blast dest: sym) |
475 done |
475 done |
476 |
476 |
477 (** Towards induction over multisets **) |
477 (** Towards induction over multisets **) |
478 |
478 |
479 lemma setsum_decr: |
479 lemma setsum_decr: |
480 "Finite(A) |
480 "Finite(A) |
481 ==> (\<forall>M. multiset(M) --> |
481 ==> (\<forall>M. multiset(M) \<longrightarrow> |
482 (\<forall>a \<in> mset_of(M). setsum(%z. $# mcount(M(a:=M`a #- 1), z), A) = |
482 (\<forall>a \<in> mset_of(M). setsum(%z. $# mcount(M(a:=M`a #- 1), z), A) = |
483 (if a \<in> A then setsum(%z. $# mcount(M, z), A) $- #1 |
483 (if a \<in> A then setsum(%z. $# mcount(M, z), A) $- #1 |
484 else setsum(%z. $# mcount(M, z), A))))" |
484 else setsum(%z. $# mcount(M, z), A))))" |
485 apply (unfold multiset_def) |
485 apply (unfold multiset_def) |
486 apply (erule Finite_induct) |
486 apply (erule Finite_induct) |
492 apply (rule int_of_diff, auto) |
492 apply (rule int_of_diff, auto) |
493 done |
493 done |
494 |
494 |
495 lemma setsum_decr2: |
495 lemma setsum_decr2: |
496 "Finite(A) |
496 "Finite(A) |
497 ==> \<forall>M. multiset(M) --> (\<forall>a \<in> mset_of(M). |
497 ==> \<forall>M. multiset(M) \<longrightarrow> (\<forall>a \<in> mset_of(M). |
498 setsum(%x. $# mcount(funrestrict(M, mset_of(M)-{a}), x), A) = |
498 setsum(%x. $# mcount(funrestrict(M, mset_of(M)-{a}), x), A) = |
499 (if a \<in> A then setsum(%x. $# mcount(M, x), A) $- $# M`a |
499 (if a \<in> A then setsum(%x. $# mcount(M, x), A) $- $# M`a |
500 else setsum(%x. $# mcount(M, x), A)))" |
500 else setsum(%x. $# mcount(M, x), A)))" |
501 apply (simp add: multiset_def) |
501 apply (simp add: multiset_def) |
502 apply (erule Finite_induct) |
502 apply (erule Finite_induct) |
512 apply (rule sym, rule ssubst, blast) |
512 apply (rule sym, rule ssubst, blast) |
513 apply (rule sym, drule setsum_decr2, auto) |
513 apply (rule sym, drule setsum_decr2, auto) |
514 apply (simp add: mcount_def mset_of_def) |
514 apply (simp add: mcount_def mset_of_def) |
515 done |
515 done |
516 |
516 |
517 lemma nat_le_1_cases: "n \<in> nat ==> n le 1 <-> (n=0 | n=1)" |
517 lemma nat_le_1_cases: "n \<in> nat ==> n \<le> 1 \<longleftrightarrow> (n=0 | n=1)" |
518 by (auto elim: natE) |
518 by (auto elim: natE) |
519 |
519 |
520 lemma succ_pred_eq_self: "[| 0<n; n \<in> nat |] ==> succ(n #- 1) = n" |
520 lemma succ_pred_eq_self: "[| 0<n; n \<in> nat |] ==> succ(n #- 1) = n" |
521 apply (subgoal_tac "1 le n") |
521 apply (subgoal_tac "1 \<le> n") |
522 apply (drule add_diff_inverse2, auto) |
522 apply (drule add_diff_inverse2, auto) |
523 done |
523 done |
524 |
524 |
525 text{*Specialized for use in the proof below.*} |
525 text{*Specialized for use in the proof below.*} |
526 lemma multiset_funrestict: |
526 lemma multiset_funrestict: |
534 lemma multiset_induct_aux: |
534 lemma multiset_induct_aux: |
535 assumes prem1: "!!M a. [| multiset(M); a\<notin>mset_of(M); P(M) |] ==> P(cons(<a, 1>, M))" |
535 assumes prem1: "!!M a. [| multiset(M); a\<notin>mset_of(M); P(M) |] ==> P(cons(<a, 1>, M))" |
536 and prem2: "!!M b. [| multiset(M); b \<in> mset_of(M); P(M) |] ==> P(M(b:= M`b #+ 1))" |
536 and prem2: "!!M b. [| multiset(M); b \<in> mset_of(M); P(M) |] ==> P(M(b:= M`b #+ 1))" |
537 shows |
537 shows |
538 "[| n \<in> nat; P(0) |] |
538 "[| n \<in> nat; P(0) |] |
539 ==> (\<forall>M. multiset(M)--> |
539 ==> (\<forall>M. multiset(M)\<longrightarrow> |
540 (setsum(%x. $# mcount(M, x), {x \<in> mset_of(M). 0 < M`x}) = $# n) --> P(M))" |
540 (setsum(%x. $# mcount(M, x), {x \<in> mset_of(M). 0 < M`x}) = $# n) \<longrightarrow> P(M))" |
541 apply (erule nat_induct, clarify) |
541 apply (erule nat_induct, clarify) |
542 apply (frule msize_eq_0_iff) |
542 apply (frule msize_eq_0_iff) |
543 apply (auto simp add: mset_of_def multiset_def multiset_fun_iff msize_def) |
543 apply (auto simp add: mset_of_def multiset_def multiset_fun_iff msize_def) |
544 apply (subgoal_tac "setsum (%x. $# mcount (M, x), A) =$# succ (x) ") |
544 apply (subgoal_tac "setsum (%x. $# mcount (M, x), A) =$# succ (x) ") |
545 apply (drule setsum_succD, auto) |
545 apply (drule setsum_succD, auto) |
560 apply (simp (no_asm_simp) add: mset_of_def mcount_def) |
560 apply (simp (no_asm_simp) add: mset_of_def mcount_def) |
561 apply (drule_tac x = "M (a := M ` a #- 1) " in spec) |
561 apply (drule_tac x = "M (a := M ` a #- 1) " in spec) |
562 apply (drule mp, drule_tac [2] mp, simp_all) |
562 apply (drule mp, drule_tac [2] mp, simp_all) |
563 apply (rule_tac x = A in exI) |
563 apply (rule_tac x = A in exI) |
564 apply (auto intro: update_type) |
564 apply (auto intro: update_type) |
565 apply (subgoal_tac "Finite ({x \<in> cons (a, A) . x\<noteq>a-->0<M`x}) ") |
565 apply (subgoal_tac "Finite ({x \<in> cons (a, A) . x\<noteq>a\<longrightarrow>0<M`x}) ") |
566 prefer 2 apply (blast intro: Collect_subset [THEN subset_Finite] Finite_cons) |
566 prefer 2 apply (blast intro: Collect_subset [THEN subset_Finite] Finite_cons) |
567 apply (drule_tac A = "{x \<in> cons (a, A) . x\<noteq>a-->0<M`x}" in setsum_decr) |
567 apply (drule_tac A = "{x \<in> cons (a, A) . x\<noteq>a\<longrightarrow>0<M`x}" in setsum_decr) |
568 apply (drule_tac x = M in spec) |
568 apply (drule_tac x = M in spec) |
569 apply (subgoal_tac "multiset (M) ") |
569 apply (subgoal_tac "multiset (M) ") |
570 prefer 2 |
570 prefer 2 |
571 apply (simp add: multiset_def multiset_fun_iff) |
571 apply (simp add: multiset_def multiset_fun_iff) |
572 apply (rule_tac x = A in exI, force) |
572 apply (rule_tac x = A in exI, force) |
629 lemma munion_single_case2: |
629 lemma munion_single_case2: |
630 "[| multiset(M); a \<in> mset_of(M) |] ==> M +# {#a#} = M(a:=M`a #+ 1)" |
630 "[| multiset(M); a \<in> mset_of(M) |] ==> M +# {#a#} = M(a:=M`a #+ 1)" |
631 apply (simp add: multiset_def) |
631 apply (simp add: multiset_def) |
632 apply (auto simp add: munion_def multiset_fun_iff msingle_def) |
632 apply (auto simp add: munion_def multiset_fun_iff msingle_def) |
633 apply (unfold mset_of_def, simp) |
633 apply (unfold mset_of_def, simp) |
634 apply (subgoal_tac "A Un {a} = A") |
634 apply (subgoal_tac "A \<union> {a} = A") |
635 apply (rule fun_extension) |
635 apply (rule fun_extension) |
636 apply (auto dest: domain_type intro: lam_type update_type) |
636 apply (auto dest: domain_type intro: lam_type update_type) |
637 done |
637 done |
638 |
638 |
639 (* Induction principle for multisets *) |
639 (* Induction principle for multisets *) |
663 lemma mset_of_MCollect [simp]: |
663 lemma mset_of_MCollect [simp]: |
664 "multiset(M) ==> mset_of({# x \<in> M. P(x) #}) \<subseteq> mset_of(M)" |
664 "multiset(M) ==> mset_of({# x \<in> M. P(x) #}) \<subseteq> mset_of(M)" |
665 by (auto simp add: mset_of_def MCollect_def multiset_def funrestrict_def) |
665 by (auto simp add: mset_of_def MCollect_def multiset_def funrestrict_def) |
666 |
666 |
667 lemma MCollect_mem_iff [iff]: |
667 lemma MCollect_mem_iff [iff]: |
668 "x \<in> mset_of({#x \<in> M. P(x)#}) <-> x \<in> mset_of(M) & P(x)" |
668 "x \<in> mset_of({#x \<in> M. P(x)#}) \<longleftrightarrow> x \<in> mset_of(M) & P(x)" |
669 by (simp add: MCollect_def mset_of_def) |
669 by (simp add: MCollect_def mset_of_def) |
670 |
670 |
671 lemma mcount_MCollect [simp]: |
671 lemma mcount_MCollect [simp]: |
672 "mcount({# x \<in> M. P(x) #}, a) = (if P(a) then mcount(M,a) else 0)" |
672 "mcount({# x \<in> M. P(x) #}, a) = (if P(a) then mcount(M,a) else 0)" |
673 by (simp add: mcount_def MCollect_def mset_of_def) |
673 by (simp add: mcount_def MCollect_def mset_of_def) |
680 by (auto simp add: multiset_def mset_of_def multiset_fun_iff) |
680 by (auto simp add: multiset_def mset_of_def multiset_fun_iff) |
681 |
681 |
682 (* and more algebraic laws on multisets *) |
682 (* and more algebraic laws on multisets *) |
683 |
683 |
684 lemma munion_eq_conv_diff: "[| multiset(M); multiset(N) |] |
684 lemma munion_eq_conv_diff: "[| multiset(M); multiset(N) |] |
685 ==> (M +# {#a#} = N +# {#b#}) <-> (M = N & a = b | |
685 ==> (M +# {#a#} = N +# {#b#}) \<longleftrightarrow> (M = N & a = b | |
686 M = N -# {#a#} +# {#b#} & N = M -# {#b#} +# {#a#})" |
686 M = N -# {#a#} +# {#b#} & N = M -# {#b#} +# {#a#})" |
687 apply (simp del: mcount_single add: multiset_equality) |
687 apply (simp del: mcount_single add: multiset_equality) |
688 apply (rule iffI, erule_tac [2] disjE, erule_tac [3] conjE) |
688 apply (rule iffI, erule_tac [2] disjE, erule_tac [3] conjE) |
689 apply (case_tac "a=b", auto) |
689 apply (case_tac "a=b", auto) |
690 apply (drule_tac x = a in spec) |
690 apply (drule_tac x = a in spec) |
695 apply (erule_tac [3] natE, erule natE, auto) |
695 apply (erule_tac [3] natE, erule natE, auto) |
696 done |
696 done |
697 |
697 |
698 lemma melem_diff_single: |
698 lemma melem_diff_single: |
699 "multiset(M) ==> |
699 "multiset(M) ==> |
700 k \<in> mset_of(M -# {#a#}) <-> (k=a & 1 < mcount(M,a)) | (k\<noteq> a & k \<in> mset_of(M))" |
700 k \<in> mset_of(M -# {#a#}) \<longleftrightarrow> (k=a & 1 < mcount(M,a)) | (k\<noteq> a & k \<in> mset_of(M))" |
701 apply (simp add: multiset_def) |
701 apply (simp add: multiset_def) |
702 apply (simp add: normalize_def mset_of_def msingle_def mdiff_def mcount_def) |
702 apply (simp add: normalize_def mset_of_def msingle_def mdiff_def mcount_def) |
703 apply (auto dest: domain_type intro: zero_less_diff [THEN iffD1] |
703 apply (auto dest: domain_type intro: zero_less_diff [THEN iffD1] |
704 simp add: multiset_fun_iff apply_iff) |
704 simp add: multiset_fun_iff apply_iff) |
705 apply (force intro!: lam_type) |
705 apply (force intro!: lam_type) |
707 apply (force intro!: lam_type) |
707 apply (force intro!: lam_type) |
708 done |
708 done |
709 |
709 |
710 lemma munion_eq_conv_exist: |
710 lemma munion_eq_conv_exist: |
711 "[| M \<in> Mult(A); N \<in> Mult(A) |] |
711 "[| M \<in> Mult(A); N \<in> Mult(A) |] |
712 ==> (M +# {#a#} = N +# {#b#}) <-> |
712 ==> (M +# {#a#} = N +# {#b#}) \<longleftrightarrow> |
713 (M=N & a=b | (\<exists>K \<in> Mult(A). M= K +# {#b#} & N=K +# {#a#}))" |
713 (M=N & a=b | (\<exists>K \<in> Mult(A). M= K +# {#b#} & N=K +# {#a#}))" |
714 by (auto simp add: Mult_iff_multiset melem_diff_single munion_eq_conv_diff) |
714 by (auto simp add: Mult_iff_multiset melem_diff_single munion_eq_conv_diff) |
715 |
715 |
716 |
716 |
717 subsection{*Multiset Orderings*} |
717 subsection{*Multiset Orderings*} |
726 |
726 |
727 lemma multirel1_0 [simp]: "multirel1(0, r) =0" |
727 lemma multirel1_0 [simp]: "multirel1(0, r) =0" |
728 by (auto simp add: multirel1_def) |
728 by (auto simp add: multirel1_def) |
729 |
729 |
730 lemma multirel1_iff: |
730 lemma multirel1_iff: |
731 " <N, M> \<in> multirel1(A, r) <-> |
731 " <N, M> \<in> multirel1(A, r) \<longleftrightarrow> |
732 (\<exists>a. a \<in> A & |
732 (\<exists>a. a \<in> A & |
733 (\<exists>M0. M0 \<in> Mult(A) & (\<exists>K. K \<in> Mult(A) & |
733 (\<exists>M0. M0 \<in> Mult(A) & (\<exists>K. K \<in> Mult(A) & |
734 M=M0 +# {#a#} & N=M0 +# K & (\<forall>b \<in> mset_of(K). <b,a> \<in> r))))" |
734 M=M0 +# {#a#} & N=M0 +# K & (\<forall>b \<in> mset_of(K). <b,a> \<in> r))))" |
735 by (auto simp add: multirel1_def Mult_iff_multiset Bex_def) |
735 by (auto simp add: multirel1_def Mult_iff_multiset Bex_def) |
736 |
736 |
787 done |
787 done |
788 |
788 |
789 lemma acc_0: "acc(0)=0" |
789 lemma acc_0: "acc(0)=0" |
790 by (auto intro!: equalityI dest: acc.dom_subset [THEN subsetD]) |
790 by (auto intro!: equalityI dest: acc.dom_subset [THEN subsetD]) |
791 |
791 |
792 lemma lemma1: "[| \<forall>b \<in> A. <b,a> \<in> r --> |
792 lemma lemma1: "[| \<forall>b \<in> A. <b,a> \<in> r \<longrightarrow> |
793 (\<forall>M \<in> acc(multirel1(A, r)). M +# {#b#}:acc(multirel1(A, r))); |
793 (\<forall>M \<in> acc(multirel1(A, r)). M +# {#b#}:acc(multirel1(A, r))); |
794 M0 \<in> acc(multirel1(A, r)); a \<in> A; |
794 M0 \<in> acc(multirel1(A, r)); a \<in> A; |
795 \<forall>M. <M,M0> \<in> multirel1(A, r) --> M +# {#a#} \<in> acc(multirel1(A, r)) |] |
795 \<forall>M. <M,M0> \<in> multirel1(A, r) \<longrightarrow> M +# {#a#} \<in> acc(multirel1(A, r)) |] |
796 ==> M0 +# {#a#} \<in> acc(multirel1(A, r))" |
796 ==> M0 +# {#a#} \<in> acc(multirel1(A, r))" |
797 apply (subgoal_tac "M0 \<in> Mult(A) ") |
797 apply (subgoal_tac "M0 \<in> Mult(A) ") |
798 prefer 2 |
798 prefer 2 |
799 apply (erule acc.cases) |
799 apply (erule acc.cases) |
800 apply (erule fieldE) |
800 apply (erule fieldE) |
820 (* subgoal 3: additional conditions *) |
820 (* subgoal 3: additional conditions *) |
821 apply (auto intro!: multirel1_base [THEN fieldI2] simp add: Mult_iff_multiset) |
821 apply (auto intro!: multirel1_base [THEN fieldI2] simp add: Mult_iff_multiset) |
822 done |
822 done |
823 |
823 |
824 lemma lemma2: "[| \<forall>b \<in> A. <b,a> \<in> r |
824 lemma lemma2: "[| \<forall>b \<in> A. <b,a> \<in> r |
825 --> (\<forall>M \<in> acc(multirel1(A, r)). M +# {#b#} :acc(multirel1(A, r))); |
825 \<longrightarrow> (\<forall>M \<in> acc(multirel1(A, r)). M +# {#b#} :acc(multirel1(A, r))); |
826 M \<in> acc(multirel1(A, r)); a \<in> A|] ==> M +# {#a#} \<in> acc(multirel1(A, r))" |
826 M \<in> acc(multirel1(A, r)); a \<in> A|] ==> M +# {#a#} \<in> acc(multirel1(A, r))" |
827 apply (erule acc_induct) |
827 apply (erule acc_induct) |
828 apply (blast intro: lemma1) |
828 apply (blast intro: lemma1) |
829 done |
829 done |
830 |
830 |
832 ==> \<forall>M \<in> acc(multirel1(A, r)). M +# {#a#} \<in> acc(multirel1(A, r))" |
832 ==> \<forall>M \<in> acc(multirel1(A, r)). M +# {#a#} \<in> acc(multirel1(A, r))" |
833 apply (erule_tac a = a in wf_on_induct, blast) |
833 apply (erule_tac a = a in wf_on_induct, blast) |
834 apply (blast intro: lemma2) |
834 apply (blast intro: lemma2) |
835 done |
835 done |
836 |
836 |
837 lemma lemma4: "multiset(M) ==> mset_of(M)\<subseteq>A --> |
837 lemma lemma4: "multiset(M) ==> mset_of(M)\<subseteq>A \<longrightarrow> |
838 wf[A](r) --> M \<in> field(multirel1(A, r)) --> M \<in> acc(multirel1(A, r))" |
838 wf[A](r) \<longrightarrow> M \<in> field(multirel1(A, r)) \<longrightarrow> M \<in> acc(multirel1(A, r))" |
839 apply (erule multiset_induct) |
839 apply (erule multiset_induct) |
840 (* proving the base case *) |
840 (* proving the base case *) |
841 apply clarify |
841 apply clarify |
842 apply (rule accI, force) |
842 apply (rule accI, force) |
843 apply (simp add: multirel1_def) |
843 apply (simp add: multirel1_def) |
897 apply (rule multirel1_mono, auto) |
897 apply (rule multirel1_mono, auto) |
898 done |
898 done |
899 |
899 |
900 (* Equivalence of multirel with the usual (closure-free) def *) |
900 (* Equivalence of multirel with the usual (closure-free) def *) |
901 |
901 |
902 lemma add_diff_eq: "k \<in> nat ==> 0 < k --> n #+ k #- 1 = n #+ (k #- 1)" |
902 lemma add_diff_eq: "k \<in> nat ==> 0 < k \<longrightarrow> n #+ k #- 1 = n #+ (k #- 1)" |
903 by (erule nat_induct, auto) |
903 by (erule nat_induct, auto) |
904 |
904 |
905 lemma mdiff_union_single_conv: "[|a \<in> mset_of(J); multiset(I); multiset(J) |] |
905 lemma mdiff_union_single_conv: "[|a \<in> mset_of(J); multiset(I); multiset(J) |] |
906 ==> I +# J -# {#a#} = I +# (J-# {#a#})" |
906 ==> I +# J -# {#a#} = I +# (J-# {#a#})" |
907 apply (simp (no_asm_simp) add: multiset_equality) |
907 apply (simp (no_asm_simp) add: multiset_equality) |
908 apply (case_tac "a \<notin> mset_of (I) ") |
908 apply (case_tac "a \<notin> mset_of (I) ") |
909 apply (auto simp add: mcount_def mset_of_def multiset_def multiset_fun_iff) |
909 apply (auto simp add: mcount_def mset_of_def multiset_def multiset_fun_iff) |
910 apply (auto dest: domain_type simp add: add_diff_eq) |
910 apply (auto dest: domain_type simp add: add_diff_eq) |
911 done |
911 done |
912 |
912 |
913 lemma diff_add_commute: "[| n le m; m \<in> nat; n \<in> nat; k \<in> nat |] ==> m #- n #+ k = m #+ k #- n" |
913 lemma diff_add_commute: "[| n \<le> m; m \<in> nat; n \<in> nat; k \<in> nat |] ==> m #- n #+ k = m #+ k #- n" |
914 by (auto simp add: le_iff less_iff_succ_add) |
914 by (auto simp add: le_iff less_iff_succ_add) |
915 |
915 |
916 (* One direction *) |
916 (* One direction *) |
917 |
917 |
918 lemma multirel_implies_one_step: |
918 lemma multirel_implies_one_step: |
919 "<M,N> \<in> multirel(A, r) ==> |
919 "<M,N> \<in> multirel(A, r) ==> |
920 trans[A](r) --> |
920 trans[A](r) \<longrightarrow> |
921 (\<exists>I J K. |
921 (\<exists>I J K. |
922 I \<in> Mult(A) & J \<in> Mult(A) & K \<in> Mult(A) & |
922 I \<in> Mult(A) & J \<in> Mult(A) & K \<in> Mult(A) & |
923 N = I +# J & M = I +# K & J \<noteq> 0 & |
923 N = I +# J & M = I +# K & J \<noteq> 0 & |
924 (\<forall>k \<in> mset_of(K). \<exists>j \<in> mset_of(J). <k,j> \<in> r))" |
924 (\<forall>k \<in> mset_of(K). \<exists>j \<in> mset_of(J). <k,j> \<in> r))" |
925 apply (simp add: multirel_def Ball_def Bex_def) |
925 apply (simp add: multirel_def Ball_def Bex_def) |
984 lemma one_step_implies_multirel_lemma [rule_format (no_asm)]: |
984 lemma one_step_implies_multirel_lemma [rule_format (no_asm)]: |
985 "n \<in> nat ==> |
985 "n \<in> nat ==> |
986 (\<forall>I J K. |
986 (\<forall>I J K. |
987 I \<in> Mult(A) & J \<in> Mult(A) & K \<in> Mult(A) & |
987 I \<in> Mult(A) & J \<in> Mult(A) & K \<in> Mult(A) & |
988 (msize(J) = $# n & J \<noteq>0 & (\<forall>k \<in> mset_of(K). \<exists>j \<in> mset_of(J). <k, j> \<in> r)) |
988 (msize(J) = $# n & J \<noteq>0 & (\<forall>k \<in> mset_of(K). \<exists>j \<in> mset_of(J). <k, j> \<in> r)) |
989 --> <I +# K, I +# J> \<in> multirel(A, r))" |
989 \<longrightarrow> <I +# K, I +# J> \<in> multirel(A, r))" |
990 apply (simp add: Mult_iff_multiset) |
990 apply (simp add: Mult_iff_multiset) |
991 apply (erule nat_induct, clarify) |
991 apply (erule nat_induct, clarify) |
992 apply (drule_tac M = J in msize_eq_0_iff, auto) |
992 apply (drule_tac M = J in msize_eq_0_iff, auto) |
993 (* one subgoal remains *) |
993 (* one subgoal remains *) |
994 apply (subgoal_tac "msize (J) =$# succ (x) ") |
994 apply (subgoal_tac "msize (J) =$# succ (x) ") |
1037 (** Proving that multisets are partially ordered **) |
1037 (** Proving that multisets are partially ordered **) |
1038 |
1038 |
1039 (*irreflexivity*) |
1039 (*irreflexivity*) |
1040 |
1040 |
1041 lemma multirel_irrefl_lemma: |
1041 lemma multirel_irrefl_lemma: |
1042 "Finite(A) ==> part_ord(A, r) --> (\<forall>x \<in> A. \<exists>y \<in> A. <x,y> \<in> r) -->A=0" |
1042 "Finite(A) ==> part_ord(A, r) \<longrightarrow> (\<forall>x \<in> A. \<exists>y \<in> A. <x,y> \<in> r) \<longrightarrow>A=0" |
1043 apply (erule Finite_induct) |
1043 apply (erule Finite_induct) |
1044 apply (auto dest: subset_consI [THEN [2] part_ord_subset]) |
1044 apply (auto dest: subset_consI [THEN [2] part_ord_subset]) |
1045 apply (auto simp add: part_ord_def irrefl_def) |
1045 apply (auto simp add: part_ord_def irrefl_def) |
1046 apply (drule_tac x = xa in bspec) |
1046 apply (drule_tac x = xa in bspec) |
1047 apply (drule_tac [2] a = xa and b = x in trans_onD, auto) |
1047 apply (drule_tac [2] a = xa and b = x in trans_onD, auto) |
1150 apply (auto simp add: Mult_iff_multiset) |
1150 apply (auto simp add: Mult_iff_multiset) |
1151 done |
1151 done |
1152 |
1152 |
1153 lemma munion_omultiset [simp]: "[| omultiset(M); omultiset(N) |] ==> omultiset(M +# N)" |
1153 lemma munion_omultiset [simp]: "[| omultiset(M); omultiset(N) |] ==> omultiset(M +# N)" |
1154 apply (simp add: omultiset_def, clarify) |
1154 apply (simp add: omultiset_def, clarify) |
1155 apply (rule_tac x = "i Un ia" in exI) |
1155 apply (rule_tac x = "i \<union> ia" in exI) |
1156 apply (simp add: Mult_iff_multiset Ord_Un Un_subset_iff) |
1156 apply (simp add: Mult_iff_multiset Ord_Un Un_subset_iff) |
1157 apply (blast intro: field_Memrel_mono) |
1157 apply (blast intro: field_Memrel_mono) |
1158 done |
1158 done |
1159 |
1159 |
1160 lemma mdiff_omultiset [simp]: "omultiset(M) ==> omultiset(M -# N)" |
1160 lemma mdiff_omultiset [simp]: "omultiset(M) ==> omultiset(M -# N)" |
1171 apply (subgoal_tac "Ord (x) ") |
1171 apply (subgoal_tac "Ord (x) ") |
1172 prefer 2 apply (blast intro: Ord_in_Ord) |
1172 prefer 2 apply (blast intro: Ord_in_Ord) |
1173 apply (drule_tac i = x in ltI [THEN lt_irrefl], auto) |
1173 apply (drule_tac i = x in ltI [THEN lt_irrefl], auto) |
1174 done |
1174 done |
1175 |
1175 |
1176 lemma trans_iff_trans_on: "trans(r) <-> trans[field(r)](r)" |
1176 lemma trans_iff_trans_on: "trans(r) \<longleftrightarrow> trans[field(r)](r)" |
1177 by (simp add: trans_on_def trans_def, auto) |
1177 by (simp add: trans_on_def trans_def, auto) |
1178 |
1178 |
1179 lemma part_ord_Memrel: "Ord(i) ==>part_ord(field(Memrel(i)), Memrel(i))" |
1179 lemma part_ord_Memrel: "Ord(i) ==>part_ord(field(Memrel(i)), Memrel(i))" |
1180 apply (simp add: part_ord_def) |
1180 apply (simp add: part_ord_def) |
1181 apply (simp (no_asm) add: trans_iff_trans_on [THEN iff_sym]) |
1181 apply (simp (no_asm) add: trans_iff_trans_on [THEN iff_sym]) |
1202 lemmas mless_irrefl = mless_not_refl [THEN notE, elim!] |
1202 lemmas mless_irrefl = mless_not_refl [THEN notE, elim!] |
1203 |
1203 |
1204 (*transitivity*) |
1204 (*transitivity*) |
1205 lemma mless_trans: "[| K <# M; M <# N |] ==> K <# N" |
1205 lemma mless_trans: "[| K <# M; M <# N |] ==> K <# N" |
1206 apply (simp add: mless_def, clarify) |
1206 apply (simp add: mless_def, clarify) |
1207 apply (rule_tac x = "i Un ia" in exI) |
1207 apply (rule_tac x = "i \<union> ia" in exI) |
1208 apply (blast dest: multirel_Memrel_mono [OF Un_upper1 Un_upper1, THEN subsetD] |
1208 apply (blast dest: multirel_Memrel_mono [OF Un_upper1 Un_upper1, THEN subsetD] |
1209 multirel_Memrel_mono [OF Un_upper2 Un_upper2, THEN subsetD] |
1209 multirel_Memrel_mono [OF Un_upper2 Un_upper2, THEN subsetD] |
1210 intro: multirel_trans Ord_Un) |
1210 intro: multirel_trans Ord_Un) |
1211 done |
1211 done |
1212 |
1212 |
1234 lemma mle_trans: "[| K <#= M; M <#= N |] ==> K <#= N" |
1234 lemma mle_trans: "[| K <#= M; M <#= N |] ==> K <#= N" |
1235 apply (simp add: mle_def) |
1235 apply (simp add: mle_def) |
1236 apply (blast intro: mless_trans) |
1236 apply (blast intro: mless_trans) |
1237 done |
1237 done |
1238 |
1238 |
1239 lemma mless_le_iff: "M <# N <-> (M <#= N & M \<noteq> N)" |
1239 lemma mless_le_iff: "M <# N \<longleftrightarrow> (M <#= N & M \<noteq> N)" |
1240 by (simp add: mle_def, auto) |
1240 by (simp add: mle_def, auto) |
1241 |
1241 |
1242 (** Monotonicity of mless **) |
1242 (** Monotonicity of mless **) |
1243 |
1243 |
1244 lemma munion_less_mono2: "[| M <# N; omultiset(K) |] ==> K +# M <# K +# N" |
1244 lemma munion_less_mono2: "[| M <# N; omultiset(K) |] ==> K +# M <# K +# N" |
1245 apply (simp add: mless_def omultiset_def, clarify) |
1245 apply (simp add: mless_def omultiset_def, clarify) |
1246 apply (rule_tac x = "i Un ia" in exI) |
1246 apply (rule_tac x = "i \<union> ia" in exI) |
1247 apply (simp add: Mult_iff_multiset Ord_Un Un_subset_iff) |
1247 apply (simp add: Mult_iff_multiset Ord_Un Un_subset_iff) |
1248 apply (rule munion_multirel_mono2) |
1248 apply (rule munion_multirel_mono2) |
1249 apply (blast intro: multirel_Memrel_mono [THEN subsetD]) |
1249 apply (blast intro: multirel_Memrel_mono [THEN subsetD]) |
1250 apply (simp add: Mult_iff_multiset) |
1250 apply (simp add: Mult_iff_multiset) |
1251 apply (blast intro: field_Memrel_mono [THEN subsetD]) |
1251 apply (blast intro: field_Memrel_mono [THEN subsetD]) |