src/ZF/Arith.ML
changeset 1793 09fff2f0d727
parent 1708 8f782b919043
child 2033 639de962ded4
equal deleted inserted replaced
1792:75c54074cd8c 1793:09fff2f0d727
     1 (*  Title:      ZF/arith.ML
     1 (*  Title:      ZF/Arith.ML
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     3     Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     4     Copyright   1992  University of Cambridge
     4     Copyright   1992  University of Cambridge
     5 
     5 
     6 Arithmetic operators and their definitions
     6 Arithmetic operators and their definitions
   195     "!!m n. [| m:nat;  n:nat |] ==> m #* succ(n) = m #+ (m #* n)"
   195     "!!m n. [| m:nat;  n:nat |] ==> m #* succ(n) = m #+ (m #* n)"
   196  (fn _ =>
   196  (fn _ =>
   197   [ (nat_ind_tac "m" [] 1),
   197   [ (nat_ind_tac "m" [] 1),
   198     (ALLGOALS (asm_simp_tac (arith_ss addsimps add_ac))) ]);
   198     (ALLGOALS (asm_simp_tac (arith_ss addsimps add_ac))) ]);
   199 
   199 
       
   200 goal Arith.thy "!!n. n:nat ==> 1 #* n = n";
       
   201 by (asm_simp_tac (arith_ss addsimps [add_0_right]) 1);
       
   202 qed "mult_1";
       
   203 
       
   204 goal Arith.thy "!!n. n:nat ==> n #* 1 = n";
       
   205 by (asm_simp_tac (arith_ss addsimps [mult_0_right, add_0_right, 
       
   206                                      mult_succ_right]) 1);
       
   207 qed "mult_1_right";
       
   208 
   200 (*Commutative law for multiplication*)
   209 (*Commutative law for multiplication*)
   201 qed_goal "mult_commute" Arith.thy 
   210 qed_goal "mult_commute" Arith.thy 
   202     "[| m:nat;  n:nat |] ==> m #* n = n #* m"
   211     "[| m:nat;  n:nat |] ==> m #* n = n #* m"
   203  (fn prems=>
   212  (fn prems=>
   204   [ (nat_ind_tac "m" prems 1),
   213   [ (nat_ind_tac "m" prems 1),
   306 
   315 
   307 goal Arith.thy 
   316 goal Arith.thy 
   308   "!!m. [| m:nat; n: nat; k:nat |] ==> k #* (m #- n) = (k #* m) #- (k #* n)";
   317   "!!m. [| m:nat; n: nat; k:nat |] ==> k #* (m #- n) = (k #* m) #- (k #* n)";
   309 val mult_commute_k = read_instantiate [("m","k")] mult_commute;
   318 val mult_commute_k = read_instantiate [("m","k")] mult_commute;
   310 by (asm_simp_tac (arith_ss addsimps 
   319 by (asm_simp_tac (arith_ss addsimps 
   311 		  [mult_commute_k, diff_mult_distrib]) 1);
   320                   [mult_commute_k, diff_mult_distrib]) 1);
   312 qed "diff_mult_distrib2" ;
   321 qed "diff_mult_distrib2" ;
   313 
   322 
   314 (*** Remainder ***)
   323 (*** Remainder ***)
   315 
   324 
   316 goal Arith.thy "!!m n. [| 0<n;  n le m;  m:nat |] ==> m #- n < m";
   325 goal Arith.thy "!!m n. [| 0<n;  n le m;  m:nat |] ==> m #- n < m";
   497 
   506 
   498 goal Arith.thy "!!i j k. [| i le j; j:nat; k:nat |] ==> i#*k le j#*k";
   507 goal Arith.thy "!!i j k. [| i le j; j:nat; k:nat |] ==> i#*k le j#*k";
   499 by (forward_tac [lt_nat_in_nat] 1);
   508 by (forward_tac [lt_nat_in_nat] 1);
   500 by (nat_ind_tac "k" [] 2);
   509 by (nat_ind_tac "k" [] 2);
   501 by (ALLGOALS (asm_simp_tac (arith_ss addsimps [mult_0_right, mult_succ_right,
   510 by (ALLGOALS (asm_simp_tac (arith_ss addsimps [mult_0_right, mult_succ_right,
   502 					       add_le_mono])));
   511                                                add_le_mono])));
   503 qed "mult_le_mono1";
   512 qed "mult_le_mono1";
   504 
   513 
   505 (* le monotonicity, BOTH arguments*)
   514 (* le monotonicity, BOTH arguments*)
   506 goal Arith.thy
   515 goal Arith.thy
   507     "!!i j k. [| i le j; k le l; j:nat; l:nat |] ==> i#*k le j#*l";
   516     "!!i j k. [| i le j; k le l; j:nat; l:nat |] ==> i#*k le j#*l";
   513 by (REPEAT (eresolve_tac [asm_rl, lt_nat_in_nat, nat_succI] 1));
   522 by (REPEAT (eresolve_tac [asm_rl, lt_nat_in_nat, nat_succI] 1));
   514 qed "mult_le_mono";
   523 qed "mult_le_mono";
   515 
   524 
   516 (*strict, in 1st argument; proof is by induction on k>0*)
   525 (*strict, in 1st argument; proof is by induction on k>0*)
   517 goal Arith.thy "!!i j k. [| i<j; 0<k; j:nat; k:nat |] ==> k#*i < k#*j";
   526 goal Arith.thy "!!i j k. [| i<j; 0<k; j:nat; k:nat |] ==> k#*i < k#*j";
   518 be zero_lt_natE 1;
   527 by (etac zero_lt_natE 1);
   519 by (forward_tac [lt_nat_in_nat] 2);
   528 by (forward_tac [lt_nat_in_nat] 2);
   520 by (ALLGOALS (asm_simp_tac arith_ss));
   529 by (ALLGOALS (asm_simp_tac arith_ss));
   521 by (nat_ind_tac "x" [] 1);
   530 by (nat_ind_tac "x" [] 1);
   522 by (ALLGOALS (asm_simp_tac (arith_ss addsimps [add_0_right, add_lt_mono])));
   531 by (ALLGOALS (asm_simp_tac (arith_ss addsimps [add_0_right, add_lt_mono])));
   523 qed "mult_lt_mono2";
   532 qed "mult_lt_mono2";
   524 
   533 
   525 goal Arith.thy "!!k. [| m: nat; n: nat |] ==> 0 < m#*n <-> 0<m & 0<n";
   534 goal Arith.thy "!!k. [| m: nat; n: nat |] ==> 0 < m#*n <-> 0<m & 0<n";
   526 by (etac nat_induct 1);
   535 by (best_tac (ZF_cs addEs [natE] addss (arith_ss addsimps [mult_0_right])) 1);
   527 by (etac nat_induct 2);
       
   528 by (ALLGOALS (asm_simp_tac (arith_ss addsimps [mult_0_right])));
       
   529 qed "zero_lt_mult_iff";
   536 qed "zero_lt_mult_iff";
       
   537 
       
   538 goal Arith.thy "!!k. [| m: nat; n: nat |] ==> m#*n = 1 <-> m=1 & n=1";
       
   539 by (best_tac (ZF_cs addEs [natE] addss (arith_ss addsimps [mult_0_right])) 1);
       
   540 qed "mult_eq_1_iff";
   530 
   541 
   531 (*Cancellation law for division*)
   542 (*Cancellation law for division*)
   532 goal Arith.thy
   543 goal Arith.thy
   533    "!!k. [| 0<n; 0<k; k:nat; m:nat; n:nat |] ==> (k#*m) div (k#*n) = m div n";
   544    "!!k. [| 0<n; 0<k; k:nat; m:nat; n:nat |] ==> (k#*m) div (k#*n) = m div n";
   534 by (eres_inst_tac [("i","m")] complete_induct 1);
   545 by (eres_inst_tac [("i","m")] complete_induct 1);
   535 by (excluded_middle_tac "x<n" 1);
   546 by (excluded_middle_tac "x<n" 1);
   536 by (asm_simp_tac (arith_ss addsimps [div_less, zero_lt_mult_iff, 
   547 by (asm_simp_tac (arith_ss addsimps [div_less, zero_lt_mult_iff, 
   537 				     mult_lt_mono2]) 2);
   548                                      mult_lt_mono2]) 2);
   538 by (asm_full_simp_tac
   549 by (asm_full_simp_tac
   539      (arith_ss addsimps [not_lt_iff_le, nat_into_Ord,
   550      (arith_ss addsimps [not_lt_iff_le, nat_into_Ord,
   540                          zero_lt_mult_iff, le_refl RS mult_le_mono, div_geq,
   551                          zero_lt_mult_iff, le_refl RS mult_le_mono, div_geq,
   541                          diff_mult_distrib2 RS sym,
   552                          diff_mult_distrib2 RS sym,
   542 			 div_termination RS ltD]) 1);
   553                          div_termination RS ltD]) 1);
   543 qed "div_cancel";
   554 qed "div_cancel";
   544 
   555 
   545 goal Arith.thy
   556 goal Arith.thy
   546    "!!k. [| 0<n; 0<k; k:nat; m:nat; n:nat |] ==> \
   557    "!!k. [| 0<n; 0<k; k:nat; m:nat; n:nat |] ==> \
   547 \        (k#*m) mod (k#*n) = k #* (m mod n)";
   558 \        (k#*m) mod (k#*n) = k #* (m mod n)";
   548 by (eres_inst_tac [("i","m")] complete_induct 1);
   559 by (eres_inst_tac [("i","m")] complete_induct 1);
   549 by (excluded_middle_tac "x<n" 1);
   560 by (excluded_middle_tac "x<n" 1);
   550 by (asm_simp_tac (arith_ss addsimps [mod_less, zero_lt_mult_iff, 
   561 by (asm_simp_tac (arith_ss addsimps [mod_less, zero_lt_mult_iff, 
   551 				     mult_lt_mono2]) 2);
   562                                      mult_lt_mono2]) 2);
   552 by (asm_full_simp_tac
   563 by (asm_full_simp_tac
   553      (arith_ss addsimps [not_lt_iff_le, nat_into_Ord,
   564      (arith_ss addsimps [not_lt_iff_le, nat_into_Ord,
   554                          zero_lt_mult_iff, le_refl RS mult_le_mono, mod_geq,
   565                          zero_lt_mult_iff, le_refl RS mult_le_mono, mod_geq,
   555                          diff_mult_distrib2 RS sym,
   566                          diff_mult_distrib2 RS sym,
   556 			 div_termination RS ltD]) 1);
   567                          div_termination RS ltD]) 1);
   557 qed "mult_mod_distrib";
   568 qed "mult_mod_distrib";
   558 
   569 
   559 
   570 (** Lemma for gcd **)
       
   571 
       
   572 val mono_lemma = (nat_into_Ord RS Ord_0_lt) RSN (2,mult_lt_mono2);
       
   573 
       
   574 goal Arith.thy "!!m n. [| m = m#*n; m: nat; n: nat |] ==> n=1 | m=0";
       
   575 by (rtac disjCI 1);
       
   576 by (dtac sym 1);
       
   577 by (rtac Ord_linear_lt 1 THEN REPEAT_SOME (ares_tac [nat_into_Ord,nat_1I]));
       
   578 by (fast_tac (lt_cs addss (arith_ss addsimps [mult_0_right])) 1);
       
   579 by (fast_tac (lt_cs addDs [mono_lemma] 
       
   580                     addss (arith_ss addsimps [mult_1_right])) 1);
       
   581 qed "mult_eq_self_implies_10";
   560 
   582 
   561 val arith_ss0 = arith_ss
   583 val arith_ss0 = arith_ss
   562 and arith_ss = arith_ss addsimps [add_0_right, add_succ_right,
   584 and arith_ss = arith_ss addsimps [add_0_right, add_succ_right,
   563                                   mult_0_right, mult_succ_right,
   585                                   mult_0_right, mult_succ_right,
   564 				  mod_type, div_type,
   586                                   mod_type, div_type,
   565                                   mod_less, mod_geq, div_less, div_geq];
   587                                   mod_less, mod_geq, div_less, div_geq];