44 by (dres_inst_tac [("f","Abs_multiset")] arg_cong 1); |
44 by (dres_inst_tac [("f","Abs_multiset")] arg_cong 1); |
45 by (Asm_full_simp_tac 1); |
45 by (Asm_full_simp_tac 1); |
46 qed "multiset_eq_conv_Rep_eq"; |
46 qed "multiset_eq_conv_Rep_eq"; |
47 Addsimps [multiset_eq_conv_Rep_eq]; |
47 Addsimps [multiset_eq_conv_Rep_eq]; |
48 Addsimps [expand_fun_eq]; |
48 Addsimps [expand_fun_eq]; |
|
49 |
49 (* |
50 (* |
50 Goal |
51 Goal |
51 "[| f : multiset; g : multiset |] ==> \ |
52 "[| f : multiset; g : multiset |] ==> \ |
52 \ (Abs_multiset f = Abs_multiset g) = (!x. f x = g x)"; |
53 \ (Abs_multiset f = Abs_multiset g) = (!x. f x = g x)"; |
53 by (rtac iffI 1); |
54 by (rtac iffI 1); |
72 Addsimps [union_empty]; |
73 Addsimps [union_empty]; |
73 |
74 |
74 Goalw [union_def] |
75 Goalw [union_def] |
75 "(M::'a multiset) + N = N + M"; |
76 "(M::'a multiset) + N = N + M"; |
76 by (simp_tac (simpset() addsimps add_ac) 1); |
77 by (simp_tac (simpset() addsimps add_ac) 1); |
77 qed "union_comm"; |
78 qed "union_commute"; |
78 |
79 |
79 Goalw [union_def] |
80 Goalw [union_def] |
80 "((M::'a multiset)+N)+K = M+(N+K)"; |
81 "((M::'a multiset)+N)+K = M+(N+K)"; |
81 by (simp_tac (simpset() addsimps add_ac) 1); |
82 by (simp_tac (simpset() addsimps add_ac) 1); |
82 qed "union_assoc"; |
83 qed "union_assoc"; |
83 |
84 |
84 qed_goal "union_lcomm" thy "M+(N+K) = N+((M+K)::'a multiset)" |
85 qed_goal "union_lcomm" thy "M+(N+K) = N+((M+K)::'a multiset)" |
85 (fn _ => [rtac (union_comm RS trans) 1, rtac (union_assoc RS trans) 1, |
86 (fn _ => [rtac (union_commute RS trans) 1, rtac (union_assoc RS trans) 1, |
86 rtac (union_comm RS arg_cong) 1]); |
87 rtac (union_commute RS arg_cong) 1]); |
87 |
88 |
88 bind_thms ("union_ac", [union_assoc, union_comm, union_lcomm]); |
89 bind_thms ("union_ac", [union_assoc, union_commute, union_lcomm]); |
89 |
90 |
90 (* diff *) |
91 (* diff *) |
91 |
92 |
92 Goalw [empty_def,diff_def] |
93 Goalw [empty_def,diff_def] |
93 "M-{#} = M & {#}-M = {#}"; |
94 "M-{#} = M & {#}-M = {#}"; |
183 (simpset() addsimps [setsum_Un, setsum_addf, setsum_count_Int]) 1); |
188 (simpset() addsimps [setsum_Un, setsum_addf, setsum_count_Int]) 1); |
184 by (stac Int_commute 1); |
189 by (stac Int_commute 1); |
185 by (asm_simp_tac (simpset() addsimps [setsum_count_Int]) 1); |
190 by (asm_simp_tac (simpset() addsimps [setsum_count_Int]) 1); |
186 qed "size_union"; |
191 qed "size_union"; |
187 Addsimps [size_union]; |
192 Addsimps [size_union]; |
|
193 |
|
194 Goalw [size_def, empty_def, count_def] "(size M = 0) = (M = {#})"; |
|
195 by Auto_tac; |
|
196 by (asm_full_simp_tac (simpset() addsimps [set_of_def, count_def]) 1); |
|
197 qed "size_eq_0_iff_empty"; |
|
198 AddIffs [size_eq_0_iff_empty]; |
|
199 |
|
200 Goalw [size_def] "size M = Suc n ==> EX a. a :# M"; |
|
201 by (dtac setsum_SucD 1); |
|
202 by Auto_tac; |
|
203 qed "size_eq_Suc_imp_elem"; |
188 |
204 |
189 |
205 |
190 (* equalities *) |
206 (* equalities *) |
191 |
207 |
192 Goalw [count_def] "(M = N) = (!a. count M a = count N a)"; |
208 Goalw [count_def] "(M = N) = (!a. count M a = count N a)"; |
360 by (etac ssubst 1); |
377 by (etac ssubst 1); |
361 by (etac (Abs_multiset_inverse RS subst) 1); |
378 by (etac (Abs_multiset_inverse RS subst) 1); |
362 by (etac(simplify (simpset()) prem2)1); |
379 by (etac(simplify (simpset()) prem2)1); |
363 qed "multiset_induct"; |
380 qed "multiset_induct"; |
364 |
381 |
|
382 Goal "M : multiset ==> (%x. if P x then M x else 0) : multiset"; |
|
383 by (asm_full_simp_tac (simpset() addsimps [multiset_def]) 1); |
|
384 by (rtac finite_subset 1); |
|
385 by Auto_tac; |
|
386 qed "MCollect_preserves_multiset"; |
|
387 |
|
388 Goalw [count_def,MCollect_def] |
|
389 "count {# x:M. P x #} a = (if P a then count M a else 0)"; |
|
390 by (asm_full_simp_tac (simpset() addsimps [MCollect_preserves_multiset]) 1); |
|
391 qed "count_MCollect"; |
|
392 Addsimps [count_MCollect]; |
|
393 |
|
394 Goalw [set_of_def] |
|
395 "set_of {# x:M. P x #} = set_of M Int {x. P x}"; |
|
396 by Auto_tac; |
|
397 qed "set_of_MCollect"; |
|
398 Addsimps [set_of_MCollect]; |
|
399 |
|
400 Goal "M = {# x:M. P x #} + {# x:M. ~ P x #}"; |
|
401 by (stac multiset_eq_conv_count_eq 1); |
|
402 by Auto_tac; |
|
403 qed "multiset_partition"; |
|
404 |
365 Delsimps [multiset_eq_conv_Rep_eq, expand_fun_eq]; |
405 Delsimps [multiset_eq_conv_Rep_eq, expand_fun_eq]; |
366 Delsimps [Abs_multiset_inverse,Rep_multiset_inverse,Rep_multiset]; |
406 Delsimps [Abs_multiset_inverse,Rep_multiset_inverse,Rep_multiset]; |
367 |
407 |
368 Goal |
408 Goal |
369 "(M+{#a#} = N+{#b#}) = (M = N & a = b | (? K. M = K+{#b#} & N = K+{#a#}))"; |
409 "(M+{#a#} = N+{#b#}) = (M = N & a = b | (? K. M = K+{#b#} & N = K+{#a#}))"; |
379 AddIffs [not_less_empty]; |
419 AddIffs [not_less_empty]; |
380 |
420 |
381 Goalw [mult1_def] |
421 Goalw [mult1_def] |
382 "(N,M0 + {#a#}) : mult1(r) = \ |
422 "(N,M0 + {#a#}) : mult1(r) = \ |
383 \ ((? M. (M,M0) : mult1(r) & N = M + {#a#}) | \ |
423 \ ((? M. (M,M0) : mult1(r) & N = M + {#a#}) | \ |
384 \ (? K. (!b. K :# b --> (b,a) : r) & N = M0 + K))"; |
424 \ (? K. (!b. b :# K --> (b,a) : r) & N = M0 + K))"; |
385 by (rtac iffI 1); |
425 by (rtac iffI 1); |
386 by (asm_full_simp_tac (simpset() addsimps [add_eq_conv_ex]) 1); |
426 by (asm_full_simp_tac (simpset() addsimps [add_eq_conv_ex]) 1); |
387 by (Clarify_tac 1); |
427 by (Clarify_tac 1); |
388 by (etac disjE 1); |
428 by (etac disjE 1); |
389 by (Blast_tac 1); |
429 by (Blast_tac 1); |
453 |
493 |
454 (** Equivalence of mult with the usual (closure-free) def **) |
494 (** Equivalence of mult with the usual (closure-free) def **) |
455 |
495 |
456 (* Badly needed: a linear arithmetic tactic for multisets *) |
496 (* Badly needed: a linear arithmetic tactic for multisets *) |
457 |
497 |
458 Goal "J :# a ==> I+J - {#a#} = I + (J-{#a#})"; |
498 Goal "a :# J ==> I+J - {#a#} = I + (J-{#a#})"; |
459 by (asm_simp_tac (simpset() addsimps [multiset_eq_conv_count_eq]) 1); |
499 by (asm_simp_tac (simpset() addsimps [multiset_eq_conv_count_eq]) 1); |
460 qed "diff_union_single_conv"; |
500 qed "diff_union_single_conv"; |
461 |
501 |
462 (* One direction *) |
502 (* One direction *) |
463 Goalw [mult_def,mult1_def,set_of_def] |
503 Goalw [mult_def,mult1_def,set_of_def] |
467 by (etac converse_trancl_induct 1); |
507 by (etac converse_trancl_induct 1); |
468 by (Clarify_tac 1); |
508 by (Clarify_tac 1); |
469 by (res_inst_tac [("x","M0")] exI 1); |
509 by (res_inst_tac [("x","M0")] exI 1); |
470 by (Simp_tac 1); |
510 by (Simp_tac 1); |
471 by (Clarify_tac 1); |
511 by (Clarify_tac 1); |
472 by (case_tac "K :# a" 1); |
512 by (case_tac "a :# K" 1); |
473 by (res_inst_tac [("x","I")] exI 1); |
513 by (res_inst_tac [("x","I")] exI 1); |
474 by (Simp_tac 1); |
514 by (Simp_tac 1); |
475 by (res_inst_tac [("x","(K - {#a#}) + Ka")] exI 1); |
515 by (res_inst_tac [("x","(K - {#a#}) + Ka")] exI 1); |
476 by (asm_simp_tac (simpset() addsimps [union_assoc RS sym]) 1); |
516 by (asm_simp_tac (simpset() addsimps [union_assoc RS sym]) 1); |
477 by (dres_inst_tac[("f","%M. M-{#a#}")] arg_cong 1); |
517 by (dres_inst_tac[("f","%M. M-{#a#}")] arg_cong 1); |
478 by (asm_full_simp_tac (simpset() addsimps [diff_union_single_conv]) 1); |
518 by (asm_full_simp_tac (simpset() addsimps [diff_union_single_conv]) 1); |
479 by (full_simp_tac (simpset() addsimps [trans_def]) 1); |
519 by (full_simp_tac (simpset() addsimps [trans_def]) 1); |
480 by (Blast_tac 1); |
520 by (Blast_tac 1); |
481 by (subgoal_tac "I :# a" 1); |
521 by (subgoal_tac "a :# I" 1); |
482 by (res_inst_tac [("x","I-{#a#}")] exI 1); |
522 by (res_inst_tac [("x","I-{#a#}")] exI 1); |
483 by (res_inst_tac [("x","J+{#a#}")] exI 1); |
523 by (res_inst_tac [("x","J+{#a#}")] exI 1); |
484 by (res_inst_tac [("x","K + Ka")] exI 1); |
524 by (res_inst_tac [("x","K + Ka")] exI 1); |
485 by (rtac conjI 1); |
525 by (rtac conjI 1); |
486 by (asm_simp_tac (simpset() addsimps [multiset_eq_conv_count_eq] |
526 by (asm_simp_tac (simpset() addsimps [multiset_eq_conv_count_eq] |
490 by (Asm_full_simp_tac 1); |
530 by (Asm_full_simp_tac 1); |
491 by (asm_simp_tac (simpset() addsimps [multiset_eq_conv_count_eq] |
531 by (asm_simp_tac (simpset() addsimps [multiset_eq_conv_count_eq] |
492 addsplits [nat_diff_split]) 1); |
532 addsplits [nat_diff_split]) 1); |
493 by (full_simp_tac (simpset() addsimps [trans_def]) 1); |
533 by (full_simp_tac (simpset() addsimps [trans_def]) 1); |
494 by (Blast_tac 1); |
534 by (Blast_tac 1); |
495 by (subgoal_tac "(M0 +{#a#}) :# a" 1); |
535 by (subgoal_tac "a :# (M0 +{#a#})" 1); |
496 by (Asm_full_simp_tac 1); |
536 by (Asm_full_simp_tac 1); |
497 by (Simp_tac 1); |
537 by (Simp_tac 1); |
498 qed "mult_implies_one_step"; |
538 qed "mult_implies_one_step"; |
|
539 |
|
540 Goal "a :# M ==> M = M - {#a#} + {#a#}"; |
|
541 by (asm_simp_tac (simpset() addsimps [multiset_eq_conv_count_eq]) 1); |
|
542 qed "elem_imp_eq_diff_union"; |
|
543 |
|
544 Goal "size M = Suc n ==> EX a N. M = N + {#a#}"; |
|
545 by (etac (size_eq_Suc_imp_elem RS exE) 1); |
|
546 by (dtac elem_imp_eq_diff_union 1); |
|
547 by Auto_tac; |
|
548 qed "size_eq_Suc_imp_eq_union"; |
|
549 |
|
550 |
|
551 Goal "trans r ==> \ |
|
552 \ ALL I J K. \ |
|
553 \ (size J = n & J ~= {#} & \ |
|
554 \ (! k : set_of K. ? j : set_of J. (k,j) : r)) --> (I+K, I+J) : mult r"; |
|
555 by (induct_tac "n" 1); |
|
556 by Auto_tac; |
|
557 by (ftac size_eq_Suc_imp_eq_union 1); |
|
558 by (Clarify_tac 1); |
|
559 ren "J'" 1; |
|
560 by (Asm_full_simp_tac 1); |
|
561 by (etac notE 1); |
|
562 by Auto_tac; |
|
563 by (case_tac "J' = {#}" 1); |
|
564 by (asm_full_simp_tac (simpset() addsimps [mult_def]) 1); |
|
565 by (rtac r_into_trancl 1); |
|
566 by (asm_full_simp_tac (simpset() addsimps [mult1_def,set_of_def]) 1); |
|
567 by (Blast_tac 1); |
|
568 (*Now we know J' ~= {#}*) |
|
569 by (cut_inst_tac [("M","K"),("P", "%x. (x,a):r")] multiset_partition 1); |
|
570 by (eres_inst_tac [("P", "ALL k : set_of K. ?P k")] rev_mp 1); |
|
571 by (etac ssubst 1); |
|
572 by (asm_full_simp_tac (simpset() addsimps [Ball_def]) 1); |
|
573 by Auto_tac; |
|
574 by (subgoal_tac "((I + {# x : K. (x, a) : r#}) + {# x : K. (x, a) ~: r#}, \ |
|
575 \ (I + {# x : K. (x, a) : r#}) + J') : mult r" 1); |
|
576 by (Force_tac 2); |
|
577 by (full_simp_tac (simpset() addsimps [union_assoc RS sym, mult_def]) 1); |
|
578 by (etac trancl_trans 1); |
|
579 by (rtac r_into_trancl 1); |
|
580 by (asm_full_simp_tac (simpset() addsimps [mult1_def,set_of_def]) 1); |
|
581 by (res_inst_tac [("x", "a")] exI 1); |
|
582 by (res_inst_tac [("x", "I + J'")] exI 1); |
|
583 by (asm_simp_tac (simpset() addsimps union_ac) 1); |
|
584 qed_spec_mp "one_step_implies_mult_lemma"; |
|
585 |
|
586 Goal "[| trans r; J ~= {#}; \ |
|
587 \ ALL k : set_of K. EX j : set_of J. (k,j) : r |] \ |
|
588 \ ==> (I+K, I+J) : mult r"; |
|
589 by (rtac one_step_implies_mult_lemma 1); |
|
590 by Auto_tac; |
|
591 qed "one_step_implies_mult"; |
499 |
592 |
500 |
593 |
501 (** Proving that multisets are partially ordered **) |
594 (** Proving that multisets are partially ordered **) |
502 |
595 |
503 Goalw [trans_def] "trans {(x',x). x' < (x::'a::order)}"; |
596 Goalw [trans_def] "trans {(x',x). x' < (x::'a::order)}"; |
530 qed "mult_less_trans"; |
623 qed "mult_less_trans"; |
531 |
624 |
532 (*asymmetry*) |
625 (*asymmetry*) |
533 Goal "M < N ==> ~ N < (M :: ('a::order)multiset)"; |
626 Goal "M < N ==> ~ N < (M :: ('a::order)multiset)"; |
534 by Auto_tac; |
627 by Auto_tac; |
535 br (mult_less_not_refl RS notE) 1; |
628 by (rtac (mult_less_not_refl RS notE) 1); |
536 by (etac mult_less_trans 1); |
629 by (etac mult_less_trans 1); |
537 by (assume_tac 1); |
630 by (assume_tac 1); |
538 qed "mult_less_not_sym"; |
631 qed "mult_less_not_sym"; |
539 |
632 |
540 (* [| M<N; ~P ==> N<M |] ==> P *) |
633 (* [| M<N; ~P ==> N<M |] ==> P *) |
541 bind_thm ("mult_less_asym", mult_less_not_sym RS swap); |
634 bind_thm ("mult_less_asym", mult_less_not_sym RS swap); |
542 |
635 |
543 Goalw [mult_le_def] "M <= (M :: ('a::order)multiset)"; |
636 Goalw [mult_le_def] "M <= (M :: ('a::order)multiset)"; |
544 by Auto_tac; |
637 by Auto_tac; |
545 qed "mult_le_refl"; |
638 qed "mult_le_refl"; |
|
639 AddIffs [mult_le_refl]; |
546 |
640 |
547 (*anti-symmetry*) |
641 (*anti-symmetry*) |
548 Goalw [mult_le_def] "[| M <= N; N <= M |] ==> M = (N :: ('a::order)multiset)"; |
642 Goalw [mult_le_def] "[| M <= N; N <= M |] ==> M = (N :: ('a::order)multiset)"; |
549 by (blast_tac (claset() addDs [mult_less_not_sym]) 1); |
643 by (blast_tac (claset() addDs [mult_less_not_sym]) 1); |
550 qed "mult_le_antisym"; |
644 qed "mult_le_antisym"; |
556 qed "mult_le_trans"; |
650 qed "mult_le_trans"; |
557 |
651 |
558 Goalw [mult_le_def] "M < N = (M <= N & M ~= (N :: ('a::order)multiset))"; |
652 Goalw [mult_le_def] "M < N = (M <= N & M ~= (N :: ('a::order)multiset))"; |
559 by Auto_tac; |
653 by Auto_tac; |
560 qed "mult_less_le"; |
654 qed "mult_less_le"; |
|
655 |
|
656 |
|
657 (** Monotonicity of multiset union **) |
|
658 |
|
659 Goalw [mult1_def] |
|
660 "[| (B,D) : mult1 r; trans r |] ==> (C + B, C + D) : mult1 r"; |
|
661 by Auto_tac; |
|
662 by (res_inst_tac [("x", "a")] exI 1); |
|
663 by (res_inst_tac [("x", "C+M0")] exI 1); |
|
664 by (asm_simp_tac (simpset() addsimps [union_assoc]) 1); |
|
665 qed "mult1_union"; |
|
666 |
|
667 Goalw [mult_less_def, mult_def] |
|
668 "!!C:: ('a::order) multiset. B<D ==> C+B < C+D"; |
|
669 by (etac trancl_induct 1); |
|
670 by (blast_tac (claset() addIs [mult1_union, transI, order_less_trans, |
|
671 r_into_trancl]) 1); |
|
672 by (blast_tac (claset() addIs [mult1_union, transI, order_less_trans, |
|
673 r_into_trancl, trancl_trans]) 1); |
|
674 qed "union_less_mono2"; |
|
675 |
|
676 Goal "!!C:: ('a::order) multiset. B<D ==> B+C < D+C"; |
|
677 by (simp_tac (simpset() addsimps [union_commute]) 1); |
|
678 by (etac union_less_mono2 1); |
|
679 qed "union_less_mono1"; |
|
680 |
|
681 Goal "!!C:: ('a::order) multiset. [| A<C; B<D |] ==> A+B < C+D"; |
|
682 by (blast_tac (claset() addIs [union_less_mono1, union_less_mono2, |
|
683 mult_less_trans]) 1); |
|
684 qed "union_less_mono"; |
|
685 |
|
686 Goalw [mult_le_def] |
|
687 "!!D:: ('a::order) multiset. [| A<=C; B<=D |] ==> A+B <= C+D"; |
|
688 by (blast_tac (claset() addIs [union_less_mono, union_less_mono1, |
|
689 union_less_mono2]) 1); |
|
690 qed "union_le_mono"; |
|
691 |
|
692 |
|
693 |
|
694 Goalw [mult_le_def, mult_less_def] |
|
695 "{#} <= (M :: ('a::order) multiset)"; |
|
696 by (case_tac "M={#}" 1); |
|
697 by (subgoal_tac "({#} + {#}, {#} + M) : mult(Collect (split op <))" 2); |
|
698 by (rtac one_step_implies_mult 3); |
|
699 bw trans_def; |
|
700 by Auto_tac; |
|
701 by (blast_tac (claset() addIs [order_less_trans]) 1); |
|
702 qed "empty_leI"; |
|
703 AddIffs [empty_leI]; |
|
704 |
|
705 |
|
706 Goal "!!A:: ('a::order) multiset. A <= A+B"; |
|
707 by (subgoal_tac "A+{#} <= A+B" 1); |
|
708 by (rtac union_le_mono 2); |
|
709 by Auto_tac; |
|
710 qed "union_upper1"; |
|
711 |
|
712 Goal "!!A:: ('a::order) multiset. B <= A+B"; |
|
713 by (stac union_commute 1 THEN rtac union_upper1 1); |
|
714 qed "union_upper2"; |