src/HOL/Arith.ML
changeset 8935 548901d05a0e
parent 8859 b1ea21d70c85
child 9041 3730ae0f513a
equal deleted inserted replaced
8934:39d0cc787d47 8935:548901d05a0e
    10 (*** Basic rewrite rules for the arithmetic operators ***)
    10 (*** Basic rewrite rules for the arithmetic operators ***)
    11 
    11 
    12 
    12 
    13 (** Difference **)
    13 (** Difference **)
    14 
    14 
    15 Goal "0 - n = 0";
    15 Goal "0 - n = (0::nat)";
    16 by (induct_tac "n" 1);
    16 by (induct_tac "n" 1);
    17 by (ALLGOALS Asm_simp_tac);
    17 by (ALLGOALS Asm_simp_tac);
    18 qed "diff_0_eq_0";
    18 qed "diff_0_eq_0";
    19 
    19 
    20 (*Must simplify BEFORE the induction!  (Else we get a critical pair)
    20 (*Must simplify BEFORE the induction!  (Else we get a critical pair)
    40 
    40 
    41 (**** Inductive properties of the operators ****)
    41 (**** Inductive properties of the operators ****)
    42 
    42 
    43 (*** Addition ***)
    43 (*** Addition ***)
    44 
    44 
    45 Goal "m + 0 = m";
    45 Goal "m + 0 = (m::nat)";
    46 by (induct_tac "m" 1);
    46 by (induct_tac "m" 1);
    47 by (ALLGOALS Asm_simp_tac);
    47 by (ALLGOALS Asm_simp_tac);
    48 qed "add_0_right";
    48 qed "add_0_right";
    49 
    49 
    50 Goal "m + Suc(n) = Suc(m+n)";
    50 Goal "m + Suc(n) = Suc(m+n)";
   103 Addsimps [add_left_cancel, add_right_cancel,
   103 Addsimps [add_left_cancel, add_right_cancel,
   104           add_left_cancel_le, add_left_cancel_less];
   104           add_left_cancel_le, add_left_cancel_less];
   105 
   105 
   106 (** Reasoning about m+0=0, etc. **)
   106 (** Reasoning about m+0=0, etc. **)
   107 
   107 
   108 Goal "(m+n = 0) = (m=0 & n=0)";
   108 Goal "!!m::nat. (m+n = 0) = (m=0 & n=0)";
   109 by (case_tac "m" 1);
   109 by (case_tac "m" 1);
   110 by (Auto_tac);
   110 by (Auto_tac);
   111 qed "add_is_0";
   111 qed "add_is_0";
   112 AddIffs [add_is_0];
   112 AddIffs [add_is_0];
   113 
   113 
   114 Goal "(0 = m+n) = (m=0 & n=0)";
   114 Goal "!!m::nat. (0 = m+n) = (m=0 & n=0)";
   115 by (case_tac "m" 1);
   115 by (case_tac "m" 1);
   116 by (Auto_tac);
   116 by (Auto_tac);
   117 qed "zero_is_add";
   117 qed "zero_is_add";
   118 AddIffs [zero_is_add];
   118 AddIffs [zero_is_add];
   119 
   119 
   120 Goal "(m+n=1) = (m=1 & n=0 | m=0 & n=1)";
   120 Goal "!!m::nat. (m+n=1) = (m=1 & n=0 | m=0 & n=1)";
   121 by (case_tac "m" 1);
   121 by (case_tac "m" 1);
   122 by (Auto_tac);
   122 by (Auto_tac);
   123 qed "add_is_1";
   123 qed "add_is_1";
   124 
   124 
   125 Goal "(1=m+n) = (m=1 & n=0 | m=0 & n=1)";
   125 Goal "!!m::nat. (1=m+n) = (m=1 & n=0 | m=0 & n=1)";
   126 by (case_tac "m" 1);
   126 by (case_tac "m" 1);
   127 by (Auto_tac);
   127 by (Auto_tac);
   128 qed "one_is_add";
   128 qed "one_is_add";
   129 
   129 
   130 Goal "(0<m+n) = (0<m | 0<n)";
   130 Goal "!!m::nat. (0<m+n) = (0<m | 0<n)";
   131 by (simp_tac (simpset() delsimps [neq0_conv] addsimps [neq0_conv RS sym]) 1);
   131 by (simp_tac (simpset() delsimps [neq0_conv] addsimps [neq0_conv RS sym]) 1);
   132 qed "add_gr_0";
   132 qed "add_gr_0";
   133 AddIffs [add_gr_0];
   133 AddIffs [add_gr_0];
   134 
   134 
   135 (* Could be generalized, eg to "k<n ==> m+(n-(Suc k)) = (m+n)-(Suc k)" *)
   135 (* Could be generalized, eg to "k<n ==> m+(n-(Suc k)) = (m+n)-(Suc k)" *)
   136 Goal "0<n ==> m + (n-1) = (m+n)-1";
   136 Goal "!!m::nat. 0<n ==> m + (n-1) = (m+n)-1";
   137 by (case_tac "m" 1);
   137 by (case_tac "m" 1);
   138 by (ALLGOALS (asm_simp_tac (simpset() addsimps [diff_Suc, Suc_n_not_n]
   138 by (ALLGOALS (asm_simp_tac (simpset() addsimps [diff_Suc, Suc_n_not_n]
   139                                       addsplits [nat.split])));
   139                                       addsplits [nat.split])));
   140 qed "add_pred";
   140 qed "add_pred";
   141 Addsimps [add_pred];
   141 Addsimps [add_pred];
   142 
   142 
   143 Goal "m + n = m ==> n = 0";
   143 Goal "!!m::nat. m + n = m ==> n = 0";
   144 by (dtac (add_0_right RS ssubst) 1);
   144 by (dtac (add_0_right RS ssubst) 1);
   145 by (asm_full_simp_tac (simpset() addsimps [add_assoc]
   145 by (asm_full_simp_tac (simpset() addsimps [add_assoc]
   146                                  delsimps [add_0_right]) 1);
   146                                  delsimps [add_0_right]) 1);
   147 qed "add_eq_self_zero";
   147 qed "add_eq_self_zero";
   148 
   148 
   268 
   268 
   269 
   269 
   270 (*** Multiplication ***)
   270 (*** Multiplication ***)
   271 
   271 
   272 (*right annihilation in product*)
   272 (*right annihilation in product*)
   273 Goal "m * 0 = 0";
   273 Goal "!!m::nat. m * 0 = 0";
   274 by (induct_tac "m" 1);
   274 by (induct_tac "m" 1);
   275 by (ALLGOALS Asm_simp_tac);
   275 by (ALLGOALS Asm_simp_tac);
   276 qed "mult_0_right";
   276 qed "mult_0_right";
   277 
   277 
   278 (*right successor law for multiplication*)
   278 (*right successor law for multiplication*)
   322 by (rtac (mult_commute RS arg_cong) 1);
   322 by (rtac (mult_commute RS arg_cong) 1);
   323 qed "mult_left_commute";
   323 qed "mult_left_commute";
   324 
   324 
   325 bind_thms ("mult_ac", [mult_assoc,mult_commute,mult_left_commute]);
   325 bind_thms ("mult_ac", [mult_assoc,mult_commute,mult_left_commute]);
   326 
   326 
   327 Goal "(m*n = 0) = (m=0 | n=0)";
   327 Goal "!!m::nat. (m*n = 0) = (m=0 | n=0)";
   328 by (induct_tac "m" 1);
   328 by (induct_tac "m" 1);
   329 by (induct_tac "n" 2);
   329 by (induct_tac "n" 2);
   330 by (ALLGOALS Asm_simp_tac);
   330 by (ALLGOALS Asm_simp_tac);
   331 qed "mult_is_0";
   331 qed "mult_is_0";
   332 
   332 
   333 Goal "(0 = m*n) = (0=m | 0=n)";
   333 Goal "!!m::nat. (0 = m*n) = (0=m | 0=n)";
   334 by (cut_facts_tac [mult_is_0] 1);
   334 by (stac eq_commute 1 THEN stac mult_is_0 1);
   335 by (full_simp_tac (simpset() addsimps [eq_commute]) 1);
   335 by Auto_tac;
   336 qed "zero_is_mult";
   336 qed "zero_is_mult";
   337 
   337 
   338 Addsimps [mult_is_0, zero_is_mult];
   338 Addsimps [mult_is_0, zero_is_mult];
   339 
   339 
   340 
   340 
   341 (*** Difference ***)
   341 (*** Difference ***)
   342 
   342 
   343 Goal "m - m = 0";
   343 Goal "!!m::nat. m - m = 0";
   344 by (induct_tac "m" 1);
   344 by (induct_tac "m" 1);
   345 by (ALLGOALS Asm_simp_tac);
   345 by (ALLGOALS Asm_simp_tac);
   346 qed "diff_self_eq_0";
   346 qed "diff_self_eq_0";
   347 
   347 
   348 Addsimps [diff_self_eq_0];
   348 Addsimps [diff_self_eq_0];
   430 Goal "i <= (j::nat) ==> (j-i=k) = (j=k+i)";
   430 Goal "i <= (j::nat) ==> (j-i=k) = (j=k+i)";
   431 by Safe_tac;
   431 by Safe_tac;
   432 by (ALLGOALS (asm_simp_tac (simpset() addsimps [diff_add_inverse2])));
   432 by (ALLGOALS (asm_simp_tac (simpset() addsimps [diff_add_inverse2])));
   433 qed "le_imp_diff_is_add";
   433 qed "le_imp_diff_is_add";
   434 
   434 
   435 Goal "(m-n = 0) = (m <= n)";
   435 Goal "!!m::nat. (m-n = 0) = (m <= n)";
   436 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   436 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   437 by (ALLGOALS Asm_simp_tac);
   437 by (ALLGOALS Asm_simp_tac);
   438 qed "diff_is_0_eq";
   438 qed "diff_is_0_eq";
   439 
   439 
   440 Goal "(0 = m-n) = (m <= n)";
   440 Goal "!!m::nat. (0 = m-n) = (m <= n)";
   441 by (stac (diff_is_0_eq RS sym) 1);
   441 by (stac (diff_is_0_eq RS sym) 1);
   442 by (rtac eq_sym_conv 1);
   442 by (rtac eq_sym_conv 1);
   443 qed "zero_is_diff_eq";
   443 qed "zero_is_diff_eq";
   444 Addsimps [diff_is_0_eq, zero_is_diff_eq];
   444 Addsimps [diff_is_0_eq, zero_is_diff_eq];
   445 
   445 
   446 Goal "(0<n-m) = (m<n)";
   446 Goal "!!m::nat. (0<n-m) = (m<n)";
   447 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   447 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   448 by (ALLGOALS Asm_simp_tac);
   448 by (ALLGOALS Asm_simp_tac);
   449 qed "zero_less_diff";
   449 qed "zero_less_diff";
   450 Addsimps [zero_less_diff];
   450 Addsimps [zero_less_diff];
   451 
   451 
   452 Goal "i < j  ==> ? k. 0<k & i+k = j";
   452 Goal "i < j  ==> ? k::nat. 0<k & i+k = j";
   453 by (res_inst_tac [("x","j - i")] exI 1);
   453 by (res_inst_tac [("x","j - i")] exI 1);
   454 by (asm_simp_tac (simpset() addsimps [add_diff_inverse, less_not_sym]) 1);
   454 by (asm_simp_tac (simpset() addsimps [add_diff_inverse, less_not_sym]) 1);
   455 qed "less_imp_add_positive";
   455 qed "less_imp_add_positive";
   456 
   456 
   457 Goal "P(k) --> (!n. P(Suc(n))--> P(n)) --> P(k-i)";
   457 Goal "P(k) --> (!n. P(Suc(n))--> P(n)) --> P(k-i)";
   473 Goal "(m+k) - (n+k) = m - (n::nat)";
   473 Goal "(m+k) - (n+k) = m - (n::nat)";
   474 by (asm_simp_tac
   474 by (asm_simp_tac
   475     (simpset() addsimps [diff_cancel, inst "n" "k" add_commute]) 1);
   475     (simpset() addsimps [diff_cancel, inst "n" "k" add_commute]) 1);
   476 qed "diff_cancel2";
   476 qed "diff_cancel2";
   477 
   477 
   478 Goal "n - (n+m) = 0";
   478 Goal "n - (n+m) = (0::nat)";
   479 by (induct_tac "n" 1);
   479 by (induct_tac "n" 1);
   480 by (ALLGOALS Asm_simp_tac);
   480 by (ALLGOALS Asm_simp_tac);
   481 qed "diff_add_0";
   481 qed "diff_add_0";
   482 
   482 
   483 
   483 
   512 by (etac (mult_le_mono1 RS le_trans) 1);
   512 by (etac (mult_le_mono1 RS le_trans) 1);
   513 by (etac mult_le_mono2 1);
   513 by (etac mult_le_mono2 1);
   514 qed "mult_le_mono";
   514 qed "mult_le_mono";
   515 
   515 
   516 (*strict, in 1st argument; proof is by induction on k>0*)
   516 (*strict, in 1st argument; proof is by induction on k>0*)
   517 Goal "[| i<j; 0<k |] ==> k*i < k*j";
   517 Goal "!!i::nat. [| i<j; 0<k |] ==> k*i < k*j";
   518 by (eres_inst_tac [("m1","0")] (less_eq_Suc_add RS exE) 1);
   518 by (eres_inst_tac [("m1","0")] (less_eq_Suc_add RS exE) 1);
   519 by (Asm_simp_tac 1);
   519 by (Asm_simp_tac 1);
   520 by (induct_tac "x" 1);
   520 by (induct_tac "x" 1);
   521 by (ALLGOALS (asm_simp_tac (simpset() addsimps [add_less_mono])));
   521 by (ALLGOALS (asm_simp_tac (simpset() addsimps [add_less_mono])));
   522 qed "mult_less_mono2";
   522 qed "mult_less_mono2";
   523 
   523 
   524 Goal "[| i<j; 0<k |] ==> i*k < j*k";
   524 Goal "!!i::nat. [| i<j; 0<k |] ==> i*k < j*k";
   525 by (dtac mult_less_mono2 1);
   525 by (dtac mult_less_mono2 1);
   526 by (ALLGOALS (asm_full_simp_tac (simpset() addsimps [mult_commute])));
   526 by (ALLGOALS (asm_full_simp_tac (simpset() addsimps [mult_commute])));
   527 qed "mult_less_mono1";
   527 qed "mult_less_mono1";
   528 
   528 
   529 Goal "(0 < m*n) = (0<m & 0<n)";
   529 Goal "!!m::nat. (0 < m*n) = (0<m & 0<n)";
   530 by (induct_tac "m" 1);
   530 by (induct_tac "m" 1);
   531 by (case_tac "n" 2);
   531 by (case_tac "n" 2);
   532 by (ALLGOALS Asm_simp_tac);
   532 by (ALLGOALS Asm_simp_tac);
   533 qed "zero_less_mult_iff";
   533 qed "zero_less_mult_iff";
   534 Addsimps [zero_less_mult_iff];
   534 Addsimps [zero_less_mult_iff];
   547 by (Simp_tac 1);
   547 by (Simp_tac 1);
   548 by (fast_tac (claset() addss simpset()) 1);
   548 by (fast_tac (claset() addss simpset()) 1);
   549 qed "mult_eq_1_iff";
   549 qed "mult_eq_1_iff";
   550 Addsimps [mult_eq_1_iff];
   550 Addsimps [mult_eq_1_iff];
   551 
   551 
   552 Goal "0<k ==> (m*k < n*k) = (m<n)";
   552 Goal "!!m::nat. 0<k ==> (m*k < n*k) = (m<n)";
   553 by (safe_tac (claset() addSIs [mult_less_mono1]));
   553 by (safe_tac (claset() addSIs [mult_less_mono1]));
   554 by (cut_facts_tac [less_linear] 1);
   554 by (cut_facts_tac [less_linear] 1);
   555 by (blast_tac (claset() addIs [mult_less_mono1] addEs [less_asym]) 1);
   555 by (blast_tac (claset() addIs [mult_less_mono1] addEs [less_asym]) 1);
   556 qed "mult_less_cancel2";
   556 qed "mult_less_cancel2";
   557 
   557 
   558 Goal "0<k ==> (k*m < k*n) = (m<n)";
   558 Goal "!!m::nat. 0<k ==> (k*m < k*n) = (m<n)";
   559 by (dtac mult_less_cancel2 1);
   559 by (dtac mult_less_cancel2 1);
   560 by (asm_full_simp_tac (simpset() addsimps [mult_commute]) 1);
   560 by (etac subst 1);
       
   561 by (simp_tac (simpset() addsimps [mult_commute]) 1);
   561 qed "mult_less_cancel1";
   562 qed "mult_less_cancel1";
   562 Addsimps [mult_less_cancel1, mult_less_cancel2];
   563 Addsimps [mult_less_cancel1, mult_less_cancel2];
   563 
   564 
   564 Goal "0<k ==> (m*k <= n*k) = (m<=n)";
   565 Goal "!!m::nat. 0<k ==> (m*k <= n*k) = (m<=n)";
   565 by (asm_full_simp_tac (simpset() addsimps [linorder_not_less RS sym]) 1);
   566 by (asm_full_simp_tac (simpset() addsimps [linorder_not_less RS sym]) 1);
   566 qed "mult_le_cancel2";
   567 qed "mult_le_cancel2";
   567 
   568 
   568 Goal "0<k ==> (k*m <= k*n) = (m<=n)";
   569 Goal "!!m::nat. 0<k ==> (k*m <= k*n) = (m<=n)";
   569 by (asm_full_simp_tac (simpset() addsimps [linorder_not_less RS sym]) 1);
   570 by (asm_full_simp_tac (simpset() addsimps [linorder_not_less RS sym]) 1);
   570 qed "mult_le_cancel1";
   571 qed "mult_le_cancel1";
   571 Addsimps [mult_le_cancel1, mult_le_cancel2];
   572 Addsimps [mult_le_cancel1, mult_le_cancel2];
   572 
   573 
   573 Goal "(Suc k * m < Suc k * n) = (m < n)";
   574 Goal "(Suc k * m < Suc k * n) = (m < n)";
   578 Goalw [le_def] "(Suc k * m <= Suc k * n) = (m <= n)";
   579 Goalw [le_def] "(Suc k * m <= Suc k * n) = (m <= n)";
   579 by (simp_tac (simpset_of HOL.thy) 1);
   580 by (simp_tac (simpset_of HOL.thy) 1);
   580 by (rtac Suc_mult_less_cancel1 1);
   581 by (rtac Suc_mult_less_cancel1 1);
   581 qed "Suc_mult_le_cancel1";
   582 qed "Suc_mult_le_cancel1";
   582 
   583 
   583 Goal "0<k ==> (m*k = n*k) = (m=n)";
   584 Goal "0 < (k::nat) ==> (m*k = n*k) = (m=n)";
   584 by (cut_facts_tac [less_linear] 1);
   585 by (cut_facts_tac [less_linear] 1);
   585 by Safe_tac;
   586 by Safe_tac;
   586 by (assume_tac 2);
   587 by (assume_tac 2);
   587 by (ALLGOALS (dtac mult_less_mono1 THEN' assume_tac));
   588 by (ALLGOALS (dtac mult_less_mono1 THEN' assume_tac));
   588 by (ALLGOALS Asm_full_simp_tac);
   589 by (ALLGOALS Asm_full_simp_tac);
   589 qed "mult_cancel2";
   590 qed "mult_cancel2";
   590 
   591 
   591 Goal "0<k ==> (k*m = k*n) = (m=n)";
   592 Goal "0 < (k::nat) ==> (k*m = k*n) = (m=n)";
   592 by (dtac mult_cancel2 1);
   593 by (dtac mult_cancel2 1);
   593 by (asm_full_simp_tac (simpset() addsimps [mult_commute]) 1);
   594 by (asm_full_simp_tac (simpset() addsimps [mult_commute]) 1);
   594 qed "mult_cancel1";
   595 qed "mult_cancel1";
   595 Addsimps [mult_cancel1, mult_cancel2];
   596 Addsimps [mult_cancel1, mult_cancel2];
   596 
   597 
   599 by (Simp_tac 1);
   600 by (Simp_tac 1);
   600 qed "Suc_mult_cancel1";
   601 qed "Suc_mult_cancel1";
   601 
   602 
   602 
   603 
   603 (*Lemma for gcd*)
   604 (*Lemma for gcd*)
   604 Goal "m = m*n ==> n=1 | m=0";
   605 Goal "!!m::nat. m = m*n ==> n=1 | m=0";
   605 by (dtac sym 1);
   606 by (dtac sym 1);
   606 by (rtac disjCI 1);
   607 by (rtac disjCI 1);
   607 by (rtac nat_less_cases 1 THEN assume_tac 2);
   608 by (rtac nat_less_cases 1 THEN assume_tac 2);
   608 by (fast_tac (claset() addSEs [less_SucE] addss simpset()) 1);
   609 by (fast_tac (claset() addSEs [less_SucE] addss simpset()) 1);
   609 by (best_tac (claset() addDs [mult_less_mono2] addss simpset()) 1);
   610 by (best_tac (claset() addDs [mult_less_mono2] addss simpset()) 1);
  1086 Goal "n - Suc i <= n - i";
  1087 Goal "n - Suc i <= n - i";
  1087 by (arith_tac 1);
  1088 by (arith_tac 1);
  1088 qed "diff_Suc_le_diff";
  1089 qed "diff_Suc_le_diff";
  1089 AddIffs [diff_Suc_le_diff];
  1090 AddIffs [diff_Suc_le_diff];
  1090 
  1091 
  1091 Goal "0 < n ==> (m <= n-1) = (m<n)";
  1092 Goal "!!m::nat. 0 < n ==> (m <= n-1) = (m<n)";
  1092 by (arith_tac 1);
  1093 by (arith_tac 1);
  1093 qed "le_pred_eq";
  1094 qed "le_pred_eq";
  1094 
  1095 
  1095 Goal "0 < n ==> (m-1 < n) = (m<=n)";
  1096 Goal "!!m::nat. 0 < n ==> (m-1 < n) = (m<=n)";
  1096 by (arith_tac 1);
  1097 by (arith_tac 1);
  1097 qed "less_pred_eq";
  1098 qed "less_pred_eq";
  1098 
  1099 
  1099 (*Replaces the previous diff_less and le_diff_less, which had the stronger
  1100 (*Replaces the previous diff_less and le_diff_less, which had the stronger
  1100   second premise n<=m*)
  1101   second premise n<=m*)
  1101 Goal "[| 0<n; 0<m |] ==> m - n < m";
  1102 Goal "!!m::nat. [| 0<n; 0<m |] ==> m - n < m";
  1102 by (arith_tac 1);
  1103 by (arith_tac 1);
  1103 qed "diff_less";
  1104 qed "diff_less";
  1104 
  1105 
  1105 Goal "j <= (k::nat) ==> (j+i)-k = i-(k-j)";
  1106 Goal "j <= (k::nat) ==> (j+i)-k = i-(k-j)";
  1106 by (asm_simp_tac (simpset() addsplits [nat_diff_split]) 1);
  1107 by (asm_simp_tac (simpset() addsplits [nat_diff_split]) 1);
  1157 
  1158 
  1158 Goal "[| m < (n::nat); m<l |] ==> (l-n) < (l-m)";
  1159 Goal "[| m < (n::nat); m<l |] ==> (l-n) < (l-m)";
  1159 by (asm_simp_tac (simpset() addsplits [nat_diff_split]) 1);
  1160 by (asm_simp_tac (simpset() addsplits [nat_diff_split]) 1);
  1160 qed "diff_less_mono2";
  1161 qed "diff_less_mono2";
  1161 
  1162 
  1162 Goal "[| m-n = 0; n-m = 0 |] ==>  m=n";
  1163 Goal "!!m::nat. [| m-n = 0; n-m = 0 |] ==>  m=n";
  1163 by (asm_full_simp_tac (simpset() addsplits [nat_diff_split]) 1);
  1164 by (asm_full_simp_tac (simpset() addsplits [nat_diff_split]) 1);
  1164 qed "diffs0_imp_equal";
  1165 qed "diffs0_imp_equal";
  1165 
  1166 
  1166 (** Lemmas for ex/Factorization **)
  1167 (** Lemmas for ex/Factorization **)
  1167 
  1168 
  1168 Goal "[| 1<n; 1<m |] ==> 1<m*n";
  1169 Goal "!!m::nat. [| 1<n; 1<m |] ==> 1<m*n";
  1169 by (case_tac "m" 1);
  1170 by (case_tac "m" 1);
  1170 by Auto_tac;
  1171 by Auto_tac;
  1171 qed "one_less_mult"; 
  1172 qed "one_less_mult"; 
  1172 
  1173 
  1173 Goal "[| 1<n; 1<m |] ==> n<m*n";
  1174 Goal "!!m::nat. [| 1<n; 1<m |] ==> n<m*n";
  1174 by (case_tac "m" 1);
  1175 by (case_tac "m" 1);
  1175 by Auto_tac;
  1176 by Auto_tac;
  1176 qed "n_less_m_mult_n"; 
  1177 qed "n_less_m_mult_n"; 
  1177 
  1178 
  1178 Goal "[| 1<n; 1<m |] ==> n<n*m";
  1179 Goal "!!m::nat. [| 1<n; 1<m |] ==> n<n*m";
  1179 by (case_tac "m" 1);
  1180 by (case_tac "m" 1);
  1180 by Auto_tac;
  1181 by Auto_tac;
  1181 qed "n_less_n_mult_m"; 
  1182 qed "n_less_n_mult_m"; 
  1182 
  1183 
  1183 
  1184