src/ZF/Arith.ML
changeset 1461 6bcb44e4d6e5
parent 760 f0200e91b272
child 1609 5324067d993f
equal deleted inserted replaced
1460:5a6f2aabd538 1461:6bcb44e4d6e5
     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 For arith.thy.  Arithmetic operators and their definitions
     6 For arith.thy.  Arithmetic operators and their definitions
     7 
     7 
     8 Proofs about elementary arithmetic: addition, multiplication, etc.
     8 Proofs about elementary arithmetic: addition, multiplication, etc.
    45 val nat_le_refl = nat_into_Ord RS le_refl;
    45 val nat_le_refl = nat_into_Ord RS le_refl;
    46 
    46 
    47 val nat_typechecks = [rec_type, nat_0I, nat_1I, nat_succI, Ord_nat];
    47 val nat_typechecks = [rec_type, nat_0I, nat_1I, nat_succI, Ord_nat];
    48 
    48 
    49 val nat_simps = [rec_0, rec_succ, not_lt0, nat_0_le, le0_iff, succ_le_iff,
    49 val nat_simps = [rec_0, rec_succ, not_lt0, nat_0_le, le0_iff, succ_le_iff,
    50 		 nat_le_refl];
    50                  nat_le_refl];
    51 
    51 
    52 val nat_ss = ZF_ss addsimps (nat_simps @ nat_typechecks);
    52 val nat_ss = ZF_ss addsimps (nat_simps @ nat_typechecks);
    53 
    53 
    54 
    54 
    55 (** Addition **)
    55 (** Addition **)
   111 by (rtac (prems MRS diff_induct) 1);
   111 by (rtac (prems MRS diff_induct) 1);
   112 by (etac leE 3);
   112 by (etac leE 3);
   113 by (ALLGOALS
   113 by (ALLGOALS
   114     (asm_simp_tac
   114     (asm_simp_tac
   115      (nat_ss addsimps (prems @ [le_iff, diff_0, diff_0_eq_0, 
   115      (nat_ss addsimps (prems @ [le_iff, diff_0, diff_0_eq_0, 
   116 				diff_succ_succ, nat_into_Ord]))));
   116                                 diff_succ_succ, nat_into_Ord]))));
   117 qed "diff_le_self";
   117 qed "diff_le_self";
   118 
   118 
   119 (*** Simplification over add, mult, diff ***)
   119 (*** Simplification over add, mult, diff ***)
   120 
   120 
   121 val arith_typechecks = [add_type, mult_type, diff_type];
   121 val arith_typechecks = [add_type, mult_type, diff_type];
   122 val arith_simps = [add_0, add_succ,
   122 val arith_simps = [add_0, add_succ,
   123 		   mult_0, mult_succ,
   123                    mult_0, mult_succ,
   124 		   diff_0, diff_0_eq_0, diff_succ_succ];
   124                    diff_0, diff_0_eq_0, diff_succ_succ];
   125 
   125 
   126 val arith_ss = nat_ss addsimps (arith_simps@arith_typechecks);
   126 val arith_ss = nat_ss addsimps (arith_simps@arith_typechecks);
   127 
   127 
   128 (*** Addition ***)
   128 (*** Addition ***)
   129 
   129 
   193 qed_goal "mult_commute" Arith.thy 
   193 qed_goal "mult_commute" Arith.thy 
   194     "[| m:nat;  n:nat |] ==> m #* n = n #* m"
   194     "[| m:nat;  n:nat |] ==> m #* n = n #* m"
   195  (fn prems=>
   195  (fn prems=>
   196   [ (nat_ind_tac "m" prems 1),
   196   [ (nat_ind_tac "m" prems 1),
   197     (ALLGOALS (asm_simp_tac
   197     (ALLGOALS (asm_simp_tac
   198 	     (arith_ss addsimps (prems@[mult_0_right, mult_succ_right])))) ]);
   198              (arith_ss addsimps (prems@[mult_0_right, mult_succ_right])))) ]);
   199 
   199 
   200 (*addition distributes over multiplication*)
   200 (*addition distributes over multiplication*)
   201 qed_goal "add_mult_distrib" Arith.thy 
   201 qed_goal "add_mult_distrib" Arith.thy 
   202     "!!m n. [| m:nat;  k:nat |] ==> (m #+ n) #* k = (m #* k) #+ (n #* k)"
   202     "!!m n. [| m:nat;  k:nat |] ==> (m #+ n) #* k = (m #* k) #+ (n #* k)"
   203  (fn _=>
   203  (fn _=>
   222 (*for a/c rewriting*)
   222 (*for a/c rewriting*)
   223 qed_goal "mult_left_commute" Arith.thy 
   223 qed_goal "mult_left_commute" Arith.thy 
   224     "!!m n k. [| m:nat;  n:nat;  k:nat |] ==> m #* (n #* k) = n #* (m #* k)"
   224     "!!m n k. [| m:nat;  n:nat;  k:nat |] ==> m #* (n #* k) = n #* (m #* k)"
   225  (fn _ => [rtac (mult_commute RS trans) 1, 
   225  (fn _ => [rtac (mult_commute RS trans) 1, 
   226            rtac (mult_assoc RS trans) 3, 
   226            rtac (mult_assoc RS trans) 3, 
   227 	   rtac (mult_commute RS subst_context) 6,
   227            rtac (mult_commute RS subst_context) 6,
   228 	   REPEAT (ares_tac [mult_type] 1)]);
   228            REPEAT (ares_tac [mult_type] 1)]);
   229 
   229 
   230 val mult_ac = [mult_assoc,mult_commute,mult_left_commute];
   230 val mult_ac = [mult_assoc,mult_commute,mult_left_commute];
   231 
   231 
   232 
   232 
   233 (*** Difference ***)
   233 (*** Difference ***)
   275 by (etac rev_mp 1);
   275 by (etac rev_mp 1);
   276 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   276 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   277 by (ALLGOALS (asm_simp_tac (nat_ss addsimps [diff_le_self,diff_succ_succ])));
   277 by (ALLGOALS (asm_simp_tac (nat_ss addsimps [diff_le_self,diff_succ_succ])));
   278 qed "div_termination";
   278 qed "div_termination";
   279 
   279 
   280 val div_rls =	(*for mod and div*)
   280 val div_rls =   (*for mod and div*)
   281     nat_typechecks @
   281     nat_typechecks @
   282     [Ord_transrec_type, apply_type, div_termination RS ltD, if_type,
   282     [Ord_transrec_type, apply_type, div_termination RS ltD, if_type,
   283      nat_into_Ord, not_lt_iff_le RS iffD1];
   283      nat_into_Ord, not_lt_iff_le RS iffD1];
   284 
   284 
   285 val div_ss = ZF_ss addsimps [nat_into_Ord, div_termination RS ltD,
   285 val div_ss = ZF_ss addsimps [nat_into_Ord, div_termination RS ltD,
   286 			     not_lt_iff_le RS iffD2];
   286                              not_lt_iff_le RS iffD2];
   287 
   287 
   288 (*Type checking depends upon termination!*)
   288 (*Type checking depends upon termination!*)
   289 goalw Arith.thy [mod_def] "!!m n. [| 0<n;  m:nat;  n:nat |] ==> m mod n : nat";
   289 goalw Arith.thy [mod_def] "!!m n. [| 0<n;  m:nat;  n:nat |] ==> m mod n : nat";
   290 by (REPEAT (ares_tac div_rls 1 ORELSE etac lt_trans 1));
   290 by (REPEAT (ares_tac div_rls 1 ORELSE etac lt_trans 1));
   291 qed "mod_type";
   291 qed "mod_type";
   329 (*case x<n*)
   329 (*case x<n*)
   330 by (asm_simp_tac (arith_ss addsimps [mod_less, div_less]) 2);
   330 by (asm_simp_tac (arith_ss addsimps [mod_less, div_less]) 2);
   331 (*case n le x*)
   331 (*case n le x*)
   332 by (asm_full_simp_tac
   332 by (asm_full_simp_tac
   333      (arith_ss addsimps [not_lt_iff_le, nat_into_Ord,
   333      (arith_ss addsimps [not_lt_iff_le, nat_into_Ord,
   334 			 mod_geq, div_geq, add_assoc,
   334                          mod_geq, div_geq, add_assoc,
   335 			 div_termination RS ltD, add_diff_inverse]) 1);
   335                          div_termination RS ltD, add_diff_inverse]) 1);
   336 qed "mod_div_equality";
   336 qed "mod_div_equality";
   337 
   337 
   338 
   338 
   339 (**** Additional theorems about "le" ****)
   339 (**** Additional theorems about "le" ****)
   340 
   340 
   361 (*strict, in both arguments*)
   361 (*strict, in both arguments*)
   362 goal Arith.thy "!!i j k l. [| i<j; k<l; j:nat; l:nat |] ==> i#+k < j#+l";
   362 goal Arith.thy "!!i j k l. [| i<j; k<l; j:nat; l:nat |] ==> i#+k < j#+l";
   363 by (rtac (add_lt_mono1 RS lt_trans) 1);
   363 by (rtac (add_lt_mono1 RS lt_trans) 1);
   364 by (REPEAT (eresolve_tac [asm_rl, lt_nat_in_nat] 1));
   364 by (REPEAT (eresolve_tac [asm_rl, lt_nat_in_nat] 1));
   365 by (EVERY [rtac (add_commute RS ssubst) 1,
   365 by (EVERY [rtac (add_commute RS ssubst) 1,
   366 	   rtac (add_commute RS ssubst) 3,
   366            rtac (add_commute RS ssubst) 3,
   367 	   rtac add_lt_mono1 5]);
   367            rtac add_lt_mono1 5]);
   368 by (REPEAT (eresolve_tac [asm_rl, lt_nat_in_nat] 1));
   368 by (REPEAT (eresolve_tac [asm_rl, lt_nat_in_nat] 1));
   369 qed "add_lt_mono";
   369 qed "add_lt_mono";
   370 
   370 
   371 (*A [clumsy] way of lifting < monotonicity to le monotonicity *)
   371 (*A [clumsy] way of lifting < monotonicity to le monotonicity *)
   372 val lt_mono::ford::prems = goal Ordinal.thy
   372 val lt_mono::ford::prems = goal Ordinal.thy
   373      "[| !!i j. [| i<j; j:k |] ==> f(i) < f(j);	\
   373      "[| !!i j. [| i<j; j:k |] ==> f(i) < f(j); \
   374 \        !!i. i:k ==> Ord(f(i));		\
   374 \        !!i. i:k ==> Ord(f(i));                \
   375 \        i le j;  j:k				\
   375 \        i le j;  j:k                           \
   376 \     |] ==> f(i) le f(j)";
   376 \     |] ==> f(i) le f(j)";
   377 by (cut_facts_tac prems 1);
   377 by (cut_facts_tac prems 1);
   378 by (fast_tac (lt_cs addSIs [lt_mono,ford] addSEs [leE]) 1);
   378 by (fast_tac (lt_cs addSIs [lt_mono,ford] addSEs [leE]) 1);
   379 qed "Ord_lt_mono_imp_le_mono";
   379 qed "Ord_lt_mono_imp_le_mono";
   380 
   380 
   389 goal Arith.thy
   389 goal Arith.thy
   390     "!!i j k. [| i le j; k le l; j:nat; l:nat |] ==> i#+k le j#+l";
   390     "!!i j k. [| i le j; k le l; j:nat; l:nat |] ==> i#+k le j#+l";
   391 by (rtac (add_le_mono1 RS le_trans) 1);
   391 by (rtac (add_le_mono1 RS le_trans) 1);
   392 by (REPEAT (eresolve_tac [asm_rl, lt_nat_in_nat, nat_succI] 1));
   392 by (REPEAT (eresolve_tac [asm_rl, lt_nat_in_nat, nat_succI] 1));
   393 by (EVERY [rtac (add_commute RS ssubst) 1,
   393 by (EVERY [rtac (add_commute RS ssubst) 1,
   394 	   rtac (add_commute RS ssubst) 3,
   394            rtac (add_commute RS ssubst) 3,
   395 	   rtac add_le_mono1 5]);
   395            rtac add_le_mono1 5]);
   396 by (REPEAT (eresolve_tac [asm_rl, lt_nat_in_nat, nat_succI] 1));
   396 by (REPEAT (eresolve_tac [asm_rl, lt_nat_in_nat, nat_succI] 1));
   397 qed "add_le_mono";
   397 qed "add_le_mono";