1 (* Title: ZF/Induct/Multiset.thy |
1 (* Title: ZF/Induct/Multiset |
2 ID: $Id$ |
2 ID: $Id$ |
3 Author: Sidi O Ehmety, Cambridge University Computer Laboratory |
3 Author: Sidi O Ehmety, Cambridge University Computer Laboratory |
4 |
4 |
5 A definitional theory of multisets, including a wellfoundedness |
5 A definitional theory of multisets, including a wellfoundedness |
6 proof for the multiset order. |
6 proof for the multiset order. |
7 |
7 |
8 The theory features ordinal multisets and the usual ordering. |
8 The theory features ordinal multisets and the usual ordering. |
9 |
9 |
10 *) |
10 *) |
|
11 |
|
12 (* Properties of the original "restrict" from ZF.thy. *) |
|
13 |
|
14 Goalw [funrestrict_def,lam_def] |
|
15 "[| f: Pi(C,B); A<=C |] ==> funrestrict(f,A) <= f"; |
|
16 by (blast_tac (claset() addIs [apply_Pair]) 1); |
|
17 qed "funrestrict_subset"; |
|
18 |
|
19 val prems = Goalw [funrestrict_def] |
|
20 "[| !!x. x:A ==> f`x: B(x) |] ==> funrestrict(f,A) : Pi(A,B)"; |
|
21 by (rtac lam_type 1); |
|
22 by (eresolve_tac prems 1); |
|
23 qed "funrestrict_type"; |
|
24 |
|
25 Goal "[| f: Pi(C,B); A<=C |] ==> funrestrict(f,A) : Pi(A,B)"; |
|
26 by (blast_tac (claset() addIs [apply_type, funrestrict_type]) 1); |
|
27 qed "funrestrict_type2"; |
|
28 |
|
29 Goalw [funrestrict_def] "a : A ==> funrestrict(f,A) ` a = f`a"; |
|
30 by (etac beta 1); |
|
31 qed "funrestrict"; |
|
32 |
|
33 Goalw [funrestrict_def] "funrestrict(f,0) = 0"; |
|
34 by (Simp_tac 1); |
|
35 qed "funrestrict_empty"; |
|
36 |
|
37 Addsimps [funrestrict, funrestrict_empty]; |
|
38 |
|
39 Goalw [funrestrict_def, lam_def] "domain(funrestrict(f,C)) = C"; |
|
40 by (Blast_tac 1); |
|
41 qed "domain_funrestrict"; |
|
42 Addsimps [domain_funrestrict]; |
|
43 |
|
44 Goal "f : cons(a, b) -> B ==> f = cons(<a, f ` a>, funrestrict(f, b))"; |
|
45 by (rtac equalityI 1); |
|
46 by (blast_tac (claset() addIs [apply_Pair, impOfSubs funrestrict_subset]) 2); |
|
47 by (auto_tac (claset() addSDs [Pi_memberD], |
|
48 simpset() addsimps [funrestrict_def, lam_def])); |
|
49 qed "fun_cons_funrestrict_eq"; |
11 |
50 |
12 Addsimps [domain_of_fun]; |
51 Addsimps [domain_of_fun]; |
13 Delrules [domainE]; |
52 Delrules [domainE]; |
14 |
53 |
15 (* The following tactic moves the condition `simp_cond' to the begining |
54 (* The following tactic moves the condition `simp_cond' to the begining |
144 qed "msingle_multiset"; |
183 qed "msingle_multiset"; |
145 AddIffs [msingle_multiset]; |
184 AddIffs [msingle_multiset]; |
146 |
185 |
147 (** normalize **) |
186 (** normalize **) |
148 |
187 |
149 Goalw [normalize_def, restrict_def, mset_of_def] |
188 Goalw [normalize_def, funrestrict_def, mset_of_def] |
150 "normalize(normalize(f)) = normalize(f)"; |
189 "normalize(normalize(f)) = normalize(f)"; |
151 by Auto_tac; |
190 by Auto_tac; |
152 qed "normalize_idem"; |
191 qed "normalize_idem"; |
153 AddIffs [normalize_idem]; |
192 AddIffs [normalize_idem]; |
154 |
193 |
155 Goalw [multiset_def] |
194 Goalw [multiset_def] |
156 "multiset(M) ==> normalize(M) = M"; |
195 "multiset(M) ==> normalize(M) = M"; |
157 by (rewrite_goals_tac [normalize_def, mset_of_def]); |
196 by (rewrite_goals_tac [normalize_def, mset_of_def]); |
158 by (auto_tac (claset(), simpset() |
197 by (auto_tac (claset(), simpset() |
159 addsimps [restrict_def, multiset_fun_iff])); |
198 addsimps [funrestrict_def, multiset_fun_iff])); |
160 qed "normalize_multiset"; |
199 qed "normalize_multiset"; |
161 Addsimps [normalize_multiset]; |
200 Addsimps [normalize_multiset]; |
162 |
201 |
163 Goalw [multiset_def] |
202 Goalw [multiset_def] |
164 "[| f:A -> nat; Finite(A) |] ==> multiset(normalize(f))"; |
203 "[| f:A -> nat; Finite(A) |] ==> multiset(normalize(f))"; |
165 by (rewrite_goals_tac [normalize_def, mset_of_def]); |
204 by (rewrite_goals_tac [normalize_def, mset_of_def]); |
166 by Auto_tac; |
205 by Auto_tac; |
167 by (res_inst_tac [("x", "{x:A . 0<f`x}")] exI 1); |
206 by (res_inst_tac [("x", "{x:A . 0<f`x}")] exI 1); |
168 by (auto_tac (claset() addIs [Collect_subset RS subset_Finite, |
207 by (auto_tac (claset() addIs [Collect_subset RS subset_Finite, |
169 restrict_type], simpset())); |
208 funrestrict_type], simpset())); |
170 qed "normalize_multiset"; |
209 qed "normalize_multiset"; |
171 |
210 |
172 (** Typechecking rules for union and difference of multisets **) |
211 (** Typechecking rules for union and difference of multisets **) |
173 |
212 |
174 Goal "[| n:nat; m:nat |] ==> 0 < m #+ n <-> (0 < m | 0 < n)"; |
213 Goal "[| n:nat; m:nat |] ==> 0 < m #+ n <-> (0 < m | 0 < n)"; |
241 AddIffs [mdiff_self_eq_0]; |
280 AddIffs [mdiff_self_eq_0]; |
242 |
281 |
243 Goalw [multiset_def] "multiset(M) ==> M -# 0 = M & 0 -# M = 0"; |
282 Goalw [multiset_def] "multiset(M) ==> M -# 0 = M & 0 -# M = 0"; |
244 by (rewrite_goals_tac [mdiff_def, normalize_def]); |
283 by (rewrite_goals_tac [mdiff_def, normalize_def]); |
245 by (auto_tac (claset(), simpset() |
284 by (auto_tac (claset(), simpset() |
246 addsimps [multiset_fun_iff, mset_of_def, restrict_def])); |
285 addsimps [multiset_fun_iff, mset_of_def, funrestrict_def])); |
247 qed "mdiff_0"; |
286 qed "mdiff_0"; |
248 Addsimps [mdiff_0]; |
287 Addsimps [mdiff_0]; |
249 |
288 |
250 Goalw [multiset_def] "multiset(M) ==> M +# {#a#} -# {#a#} = M"; |
289 Goalw [multiset_def] "multiset(M) ==> M +# {#a#} -# {#a#} = M"; |
251 by (rewrite_goals_tac [munion_def, mdiff_def, |
290 by (rewrite_goals_tac [munion_def, mdiff_def, |
252 msingle_def, normalize_def, mset_of_def]); |
291 msingle_def, normalize_def, mset_of_def]); |
253 by (auto_tac (claset(), simpset() addsimps [multiset_fun_iff])); |
292 by (auto_tac (claset(), simpset() addsimps [multiset_fun_iff])); |
254 by (rtac fun_extension 1); |
293 by (rtac fun_extension 1); |
255 by Auto_tac; |
294 by Auto_tac; |
256 by (res_inst_tac [("P", "%x. ?u : Pi(x, ?v)")] subst 1); |
295 by (res_inst_tac [("P", "%x. ?u : Pi(x, ?v)")] subst 1); |
257 by (rtac restrict_type 2); |
296 by (rtac funrestrict_type 2); |
258 by (rtac equalityI 1); |
297 by (rtac equalityI 1); |
259 by (ALLGOALS(Clarify_tac)); |
298 by (ALLGOALS(Clarify_tac)); |
260 by Auto_tac; |
299 by Auto_tac; |
261 by (res_inst_tac [("Pa", "~(1<?u)")] swap 1); |
300 by (res_inst_tac [("Pa", "~(1<?u)")] swap 1); |
262 by (case_tac "x=a" 3); |
301 by (case_tac "x=a" 3); |
510 (*FIXME: we should not have to rename x to x' below! There's a bug in the |
549 (*FIXME: we should not have to rename x to x' below! There's a bug in the |
511 interaction between simproc inteq_cancel_numerals and the simplifier.*) |
550 interaction between simproc inteq_cancel_numerals and the simplifier.*) |
512 Goalw [multiset_def] |
551 Goalw [multiset_def] |
513 "Finite(A) \ |
552 "Finite(A) \ |
514 \ ==> ALL M. multiset(M) --> (ALL a:mset_of(M). \ |
553 \ ==> ALL M. multiset(M) --> (ALL a:mset_of(M). \ |
515 \ setsum(%x'. $# mcount(restrict(M, mset_of(M)-{a}), x'), A) = \ |
554 \ setsum(%x'. $# mcount(funrestrict(M, mset_of(M)-{a}), x'), A) = \ |
516 \ (if a:A then setsum(%x'. $# mcount(M, x'), A) $- $# M`a \ |
555 \ (if a:A then setsum(%x'. $# mcount(M, x'), A) $- $# M`a \ |
517 \ else setsum(%x'. $# mcount(M, x'), A)))"; |
556 \ else setsum(%x'. $# mcount(M, x'), A)))"; |
518 by (etac Finite_induct 1); |
557 by (etac Finite_induct 1); |
519 by (auto_tac (claset(), |
558 by (auto_tac (claset(), |
520 simpset() addsimps [multiset_fun_iff, |
559 simpset() addsimps [multiset_fun_iff, |
521 mcount_def, mset_of_def])); |
560 mcount_def, mset_of_def])); |
522 qed "setsum_decr2"; |
561 qed "setsum_decr2"; |
523 |
562 |
524 Goal "[| Finite(A); multiset(M); a:mset_of(M) |] \ |
563 Goal "[| Finite(A); multiset(M); a:mset_of(M) |] \ |
525 \ ==> setsum(%x. $# mcount(restrict(M, mset_of(M)-{a}), x), A - {a}) = \ |
564 \ ==> setsum(%x. $# mcount(funrestrict(M, mset_of(M)-{a}), x), A - {a}) = \ |
526 \ (if a:A then setsum(%x. $# mcount(M, x), A) $- $# M`a\ |
565 \ (if a:A then setsum(%x. $# mcount(M, x), A) $- $# M`a\ |
527 \ else setsum(%x. $# mcount(M, x), A))"; |
566 \ else setsum(%x. $# mcount(M, x), A))"; |
528 by (subgoal_tac "setsum(%x. $# mcount(restrict(M, mset_of(M)-{a}),x),A-{a}) = \ |
567 by (subgoal_tac "setsum(%x. $# mcount(funrestrict(M, mset_of(M)-{a}),x),A-{a}) = \ |
529 \ setsum(%x. $# mcount(restrict(M, mset_of(M)-{a}),x),A)" 1); |
568 \ setsum(%x. $# mcount(funrestrict(M, mset_of(M)-{a}),x),A)" 1); |
530 by (rtac (setsum_Diff RS sym) 2); |
569 by (rtac (setsum_Diff RS sym) 2); |
531 by (REPEAT(asm_simp_tac (simpset() addsimps [mcount_def, mset_of_def]) 2)); |
570 by (REPEAT(asm_simp_tac (simpset() addsimps [mcount_def, mset_of_def]) 2)); |
532 by (rtac sym 1 THEN rtac ssubst 1); |
571 by (rtac sym 1 THEN rtac ssubst 1); |
533 by (Blast_tac 1); |
572 by (Blast_tac 1); |
534 by (rtac sym 1 THEN dtac setsum_decr2 1); |
573 by (rtac sym 1 THEN dtac setsum_decr2 1); |
597 by (subgoal_tac "cons(a, A)= A" 1); |
636 by (subgoal_tac "cons(a, A)= A" 1); |
598 by (Blast_tac 2); |
637 by (Blast_tac 2); |
599 by (rotate_simp_tac "cons(a, A) = A" 1); |
638 by (rotate_simp_tac "cons(a, A) = A" 1); |
600 by (rotate_simp_tac "ALL x:A. ?u(x)" 1); |
639 by (rotate_simp_tac "ALL x:A. ?u(x)" 1); |
601 by (rotate_simp_tac "ALL x:A. ?u(x)" 2); |
640 by (rotate_simp_tac "ALL x:A. ?u(x)" 2); |
602 by (subgoal_tac "M=cons(<a, M`a>, restrict(M, A-{a}))" 1); |
641 by (subgoal_tac "M=cons(<a, M`a>, funrestrict(M, A-{a}))" 1); |
603 by (rtac fun_cons_restrict_eq 2); |
642 by (rtac fun_cons_funrestrict_eq 2); |
604 by (subgoal_tac "cons(a, A-{a}) = A" 2); |
643 by (subgoal_tac "cons(a, A-{a}) = A" 2); |
605 by (REPEAT(Force_tac 2)); |
644 by (REPEAT(Force_tac 2)); |
606 by (res_inst_tac [("a", "cons(<a, 1>, restrict(M, A - {a}))")] ssubst 1); |
645 by (res_inst_tac [("a", "cons(<a, 1>, funrestrict(M, A - {a}))")] ssubst 1); |
607 by (Asm_full_simp_tac 1); |
646 by (Asm_full_simp_tac 1); |
608 by (subgoal_tac "multiset(restrict(M, A - {a}))" 1); |
647 by (subgoal_tac "multiset(funrestrict(M, A - {a}))" 1); |
609 by (simp_tac (simpset() addsimps [multiset_def, multiset_fun_iff]) 2); |
648 by (simp_tac (simpset() addsimps [multiset_def, multiset_fun_iff]) 2); |
610 by (res_inst_tac [("x", "A-{a}")] exI 2); |
649 by (res_inst_tac [("x", "A-{a}")] exI 2); |
611 by Safe_tac; |
650 by Safe_tac; |
612 by (res_inst_tac [("A", "A-{a}")] apply_type 3); |
651 by (res_inst_tac [("A", "A-{a}")] apply_type 3); |
613 by (asm_simp_tac (simpset() addsimps [restrict]) 5); |
652 by (asm_simp_tac (simpset() addsimps [funrestrict]) 5); |
614 by (REPEAT(blast_tac (claset() addIs [Finite_Diff, restrict_type]) 2));; |
653 by (REPEAT(blast_tac (claset() addIs [Finite_Diff, funrestrict_type]) 2));; |
615 by (resolve_tac prems 1); |
654 by (resolve_tac prems 1); |
616 by (assume_tac 1); |
655 by (assume_tac 1); |
617 by (asm_full_simp_tac (simpset() addsimps [mset_of_def]) 1); |
656 by (asm_full_simp_tac (simpset() addsimps [mset_of_def]) 1); |
618 by (dres_inst_tac [("x", "restrict(M, A-{a})")] spec 1); |
657 by (dres_inst_tac [("x", "funrestrict(M, A-{a})")] spec 1); |
619 by (dtac mp 1); |
658 by (dtac mp 1); |
620 by (res_inst_tac [("x", "A-{a}")] exI 1); |
659 by (res_inst_tac [("x", "A-{a}")] exI 1); |
621 by (auto_tac (claset() addIs [Finite_Diff, restrict_type], |
660 by (auto_tac (claset() addIs [Finite_Diff, funrestrict_type], |
622 simpset() addsimps [restrict])); |
661 simpset() addsimps [funrestrict])); |
623 by (forw_inst_tac [("A", "A"), ("M", "M"), ("a", "a")] setsum_decr3 1); |
662 by (forw_inst_tac [("A", "A"), ("M", "M"), ("a", "a")] setsum_decr3 1); |
624 by (asm_simp_tac (simpset() addsimps [multiset_def, multiset_fun_iff]) 1); |
663 by (asm_simp_tac (simpset() addsimps [multiset_def, multiset_fun_iff]) 1); |
625 by (Blast_tac 1); |
664 by (Blast_tac 1); |
626 by (asm_simp_tac (simpset() addsimps [mset_of_def]) 1); |
665 by (asm_simp_tac (simpset() addsimps [mset_of_def]) 1); |
627 by (dres_inst_tac [("b", "if ?u then ?v else ?w")] sym 1); |
666 by (dres_inst_tac [("b", "if ?u then ?v else ?w")] sym 1); |
628 by (ALLGOALS(rotate_simp_tac "ALL x:A. ?u(x)")); |
667 by (ALLGOALS(rotate_simp_tac "ALL x:A. ?u(x)")); |
629 by (subgoal_tac "{x:A - {a} . 0 < restrict(M, A - {x}) ` x} = A - {a}" 1); |
668 by (subgoal_tac "{x:A - {a} . 0 < funrestrict(M, A - {x}) ` x} = A - {a}" 1); |
630 by (auto_tac (claset() addSIs [setsum_cong], |
669 by (auto_tac (claset() addSIs [setsum_cong], |
631 simpset() addsimps [zdiff_eq_iff, |
670 simpset() addsimps [zdiff_eq_iff, |
632 zadd_commute, multiset_def, multiset_fun_iff,mset_of_def])); |
671 zadd_commute, multiset_def, multiset_fun_iff,mset_of_def])); |
633 qed "multiset_induct_aux"; |
672 qed "multiset_induct_aux"; |
634 |
673 |
701 "multiset(M) ==> multiset({# x:M. P(x)#})"; |
740 "multiset(M) ==> multiset({# x:M. P(x)#})"; |
702 by (Clarify_tac 1); |
741 by (Clarify_tac 1); |
703 by (res_inst_tac [("x", "{x:A. P(x)}")] exI 1); |
742 by (res_inst_tac [("x", "{x:A. P(x)}")] exI 1); |
704 by (auto_tac (claset() addDs [CollectD1 RSN (2,apply_type)] |
743 by (auto_tac (claset() addDs [CollectD1 RSN (2,apply_type)] |
705 addIs [Collect_subset RS subset_Finite, |
744 addIs [Collect_subset RS subset_Finite, |
706 restrict_type], |
745 funrestrict_type], |
707 simpset())); |
746 simpset())); |
708 qed "MCollect_multiset"; |
747 qed "MCollect_multiset"; |
709 Addsimps [MCollect_multiset]; |
748 Addsimps [MCollect_multiset]; |
710 |
749 |
711 Goalw [mset_of_def, MCollect_def] |
750 Goalw [mset_of_def, MCollect_def] |
712 "multiset(M) ==> mset_of({# x:M. P(x) #}) <= mset_of(M)"; |
751 "multiset(M) ==> mset_of({# x:M. P(x) #}) <= mset_of(M)"; |
713 by (auto_tac (claset(), |
752 by (auto_tac (claset(), |
714 simpset() addsimps [multiset_def, restrict_def])); |
753 simpset() addsimps [multiset_def, funrestrict_def])); |
715 qed "mset_of_MCollect"; |
754 qed "mset_of_MCollect"; |
716 Addsimps [mset_of_MCollect]; |
755 Addsimps [mset_of_MCollect]; |
717 |
756 |
718 Goalw [MCollect_def, mset_of_def] |
757 Goalw [MCollect_def, mset_of_def] |
719 "x:mset_of({#x:M. P(x)#}) <-> x:mset_of(M) & P(x)"; |
758 "x:mset_of({#x:M. P(x)#}) <-> x:mset_of(M) & P(x)"; |