src/HOL/Induct/Multiset.ML
changeset 9017 ff259b415c4d
parent 9004 45c3c2cf2386
child 9089 96dcdd84f1e1
equal deleted inserted replaced
9016:d61c76716984 9017:ff259b415c4d
    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 = {#}";
   147 Addsimps [set_of_union];
   148 Addsimps [set_of_union];
   148 
   149 
   149 Goalw [set_of_def, empty_def, count_def] "(set_of M = {}) = (M = {#})";
   150 Goalw [set_of_def, empty_def, count_def] "(set_of M = {}) = (M = {#})";
   150 by Auto_tac;
   151 by Auto_tac;
   151 qed "set_of_eq_empty_iff";
   152 qed "set_of_eq_empty_iff";
       
   153 
       
   154 Goalw [set_of_def] "(x : set_of M) = (x :# M)";
       
   155 by Auto_tac; 
       
   156 qed "mem_set_of_iff";
   152 
   157 
   153 (* size *)
   158 (* size *)
   154 
   159 
   155 Goalw [size_def] "size {#} = 0";
   160 Goalw [size_def] "size {#} = 0";
   156 by (Simp_tac 1);
   161 by (Simp_tac 1);
   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)";
   287 by (REPEAT(ares_tac prems 1));
   303 by (REPEAT(ares_tac prems 1));
   288 qed "finite_psubset_induct";
   304 qed "finite_psubset_induct";
   289 
   305 
   290 Better: use wf_finite_psubset in WF_Rel
   306 Better: use wf_finite_psubset in WF_Rel
   291 *)
   307 *)
       
   308 
   292 
   309 
   293 (** Towards the induction rule **)
   310 (** Towards the induction rule **)
   294 
   311 
   295 Goal "[| finite F; 0 < f a |] ==> \
   312 Goal "[| finite F; 0 < f a |] ==> \
   296 \     setsum (f(a:=f(a)-1)) F = (if a:F then setsum f F - 1 else setsum f F)";
   313 \     setsum (f(a:=f(a)-1)) F = (if a:F then setsum f F - 1 else setsum f F)";
   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";