src/ZF/Induct/Multiset.ML
changeset 12891 92af5c3a10fb
parent 12860 7fc3fbfed8ef
child 13175 81082cfa5618
equal deleted inserted replaced
12890:75b254b1c8ba 12891:92af5c3a10fb
     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)";