src/ZF/Arith.ML
changeset 760 f0200e91b272
parent 437 435875e4b21d
child 1461 6bcb44e4d6e5
equal deleted inserted replaced
759:e0b172d01c37 760:f0200e91b272
    23 val rec_trans = rec_def RS def_transrec RS trans;
    23 val rec_trans = rec_def RS def_transrec RS trans;
    24 
    24 
    25 goal Arith.thy "rec(0,a,b) = a";
    25 goal Arith.thy "rec(0,a,b) = a";
    26 by (rtac rec_trans 1);
    26 by (rtac rec_trans 1);
    27 by (rtac nat_case_0 1);
    27 by (rtac nat_case_0 1);
    28 val rec_0 = result();
    28 qed "rec_0";
    29 
    29 
    30 goal Arith.thy "rec(succ(m),a,b) = b(m, rec(m,a,b))";
    30 goal Arith.thy "rec(succ(m),a,b) = b(m, rec(m,a,b))";
    31 by (rtac rec_trans 1);
    31 by (rtac rec_trans 1);
    32 by (simp_tac (ZF_ss addsimps [nat_case_succ, nat_succI]) 1);
    32 by (simp_tac (ZF_ss addsimps [nat_case_succ, nat_succI]) 1);
    33 val rec_succ = result();
    33 qed "rec_succ";
    34 
    34 
    35 val major::prems = goal Arith.thy
    35 val major::prems = goal Arith.thy
    36     "[| n: nat;  \
    36     "[| n: nat;  \
    37 \       a: C(0);  \
    37 \       a: C(0);  \
    38 \       !!m z. [| m: nat;  z: C(m) |] ==> b(m,z): C(succ(m))  \
    38 \       !!m z. [| m: nat;  z: C(m) |] ==> b(m,z): C(succ(m))  \
    39 \    |] ==> rec(n,a,b) : C(n)";
    39 \    |] ==> rec(n,a,b) : C(n)";
    40 by (rtac (major RS nat_induct) 1);
    40 by (rtac (major RS nat_induct) 1);
    41 by (ALLGOALS
    41 by (ALLGOALS
    42     (asm_simp_tac (ZF_ss addsimps (prems@[rec_0,rec_succ]))));
    42     (asm_simp_tac (ZF_ss addsimps (prems@[rec_0,rec_succ]))));
    43 val rec_type = result();
    43 qed "rec_type";
    44 
    44 
    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 
    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 **)
    56 
    56 
    57 val add_type = prove_goalw Arith.thy [add_def]
    57 qed_goalw "add_type" Arith.thy [add_def]
    58     "[| m:nat;  n:nat |] ==> m #+ n : nat"
    58     "[| m:nat;  n:nat |] ==> m #+ n : nat"
    59  (fn prems=> [ (typechk_tac (prems@nat_typechecks@ZF_typechecks)) ]);
    59  (fn prems=> [ (typechk_tac (prems@nat_typechecks@ZF_typechecks)) ]);
    60 
    60 
    61 val add_0 = prove_goalw Arith.thy [add_def]
    61 qed_goalw "add_0" Arith.thy [add_def]
    62     "0 #+ n = n"
    62     "0 #+ n = n"
    63  (fn _ => [ (rtac rec_0 1) ]);
    63  (fn _ => [ (rtac rec_0 1) ]);
    64 
    64 
    65 val add_succ = prove_goalw Arith.thy [add_def]
    65 qed_goalw "add_succ" Arith.thy [add_def]
    66     "succ(m) #+ n = succ(m #+ n)"
    66     "succ(m) #+ n = succ(m #+ n)"
    67  (fn _=> [ (rtac rec_succ 1) ]); 
    67  (fn _=> [ (rtac rec_succ 1) ]); 
    68 
    68 
    69 (** Multiplication **)
    69 (** Multiplication **)
    70 
    70 
    71 val mult_type = prove_goalw Arith.thy [mult_def]
    71 qed_goalw "mult_type" Arith.thy [mult_def]
    72     "[| m:nat;  n:nat |] ==> m #* n : nat"
    72     "[| m:nat;  n:nat |] ==> m #* n : nat"
    73  (fn prems=>
    73  (fn prems=>
    74   [ (typechk_tac (prems@[add_type]@nat_typechecks@ZF_typechecks)) ]);
    74   [ (typechk_tac (prems@[add_type]@nat_typechecks@ZF_typechecks)) ]);
    75 
    75 
    76 val mult_0 = prove_goalw Arith.thy [mult_def]
    76 qed_goalw "mult_0" Arith.thy [mult_def]
    77     "0 #* n = 0"
    77     "0 #* n = 0"
    78  (fn _ => [ (rtac rec_0 1) ]);
    78  (fn _ => [ (rtac rec_0 1) ]);
    79 
    79 
    80 val mult_succ = prove_goalw Arith.thy [mult_def]
    80 qed_goalw "mult_succ" Arith.thy [mult_def]
    81     "succ(m) #* n = n #+ (m #* n)"
    81     "succ(m) #* n = n #+ (m #* n)"
    82  (fn _ => [ (rtac rec_succ 1) ]); 
    82  (fn _ => [ (rtac rec_succ 1) ]); 
    83 
    83 
    84 (** Difference **)
    84 (** Difference **)
    85 
    85 
    86 val diff_type = prove_goalw Arith.thy [diff_def]
    86 qed_goalw "diff_type" Arith.thy [diff_def]
    87     "[| m:nat;  n:nat |] ==> m #- n : nat"
    87     "[| m:nat;  n:nat |] ==> m #- n : nat"
    88  (fn prems=> [ (typechk_tac (prems@nat_typechecks@ZF_typechecks)) ]);
    88  (fn prems=> [ (typechk_tac (prems@nat_typechecks@ZF_typechecks)) ]);
    89 
    89 
    90 val diff_0 = prove_goalw Arith.thy [diff_def]
    90 qed_goalw "diff_0" Arith.thy [diff_def]
    91     "m #- 0 = m"
    91     "m #- 0 = m"
    92  (fn _ => [ (rtac rec_0 1) ]);
    92  (fn _ => [ (rtac rec_0 1) ]);
    93 
    93 
    94 val diff_0_eq_0 = prove_goalw Arith.thy [diff_def]
    94 qed_goalw "diff_0_eq_0" Arith.thy [diff_def]
    95     "n:nat ==> 0 #- n = 0"
    95     "n:nat ==> 0 #- n = 0"
    96  (fn [prem]=>
    96  (fn [prem]=>
    97   [ (rtac (prem RS nat_induct) 1),
    97   [ (rtac (prem RS nat_induct) 1),
    98     (ALLGOALS (asm_simp_tac nat_ss)) ]);
    98     (ALLGOALS (asm_simp_tac nat_ss)) ]);
    99 
    99 
   100 (*Must simplify BEFORE the induction!!  (Else we get a critical pair)
   100 (*Must simplify BEFORE the induction!!  (Else we get a critical pair)
   101   succ(m) #- succ(n)   rewrites to   pred(succ(m) #- n)  *)
   101   succ(m) #- succ(n)   rewrites to   pred(succ(m) #- n)  *)
   102 val diff_succ_succ = prove_goalw Arith.thy [diff_def]
   102 qed_goalw "diff_succ_succ" Arith.thy [diff_def]
   103     "[| m:nat;  n:nat |] ==> succ(m) #- succ(n) = m #- n"
   103     "[| m:nat;  n:nat |] ==> succ(m) #- succ(n) = m #- n"
   104  (fn prems=>
   104  (fn prems=>
   105   [ (asm_simp_tac (nat_ss addsimps prems) 1),
   105   [ (asm_simp_tac (nat_ss addsimps prems) 1),
   106     (nat_ind_tac "n" prems 1),
   106     (nat_ind_tac "n" prems 1),
   107     (ALLGOALS (asm_simp_tac (nat_ss addsimps prems))) ]);
   107     (ALLGOALS (asm_simp_tac (nat_ss addsimps prems))) ]);
   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 val diff_le_self = result();
   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,
   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 
   130 (*Associative law for addition*)
   130 (*Associative law for addition*)
   131 val add_assoc = prove_goal Arith.thy 
   131 qed_goal "add_assoc" Arith.thy 
   132     "m:nat ==> (m #+ n) #+ k = m #+ (n #+ k)"
   132     "m:nat ==> (m #+ n) #+ k = m #+ (n #+ k)"
   133  (fn prems=>
   133  (fn prems=>
   134   [ (nat_ind_tac "m" prems 1),
   134   [ (nat_ind_tac "m" prems 1),
   135     (ALLGOALS (asm_simp_tac (arith_ss addsimps prems))) ]);
   135     (ALLGOALS (asm_simp_tac (arith_ss addsimps prems))) ]);
   136 
   136 
   137 (*The following two lemmas are used for add_commute and sometimes
   137 (*The following two lemmas are used for add_commute and sometimes
   138   elsewhere, since they are safe for rewriting.*)
   138   elsewhere, since they are safe for rewriting.*)
   139 val add_0_right = prove_goal Arith.thy
   139 qed_goal "add_0_right" Arith.thy
   140     "m:nat ==> m #+ 0 = m"
   140     "m:nat ==> m #+ 0 = m"
   141  (fn prems=>
   141  (fn prems=>
   142   [ (nat_ind_tac "m" prems 1),
   142   [ (nat_ind_tac "m" prems 1),
   143     (ALLGOALS (asm_simp_tac (arith_ss addsimps prems))) ]); 
   143     (ALLGOALS (asm_simp_tac (arith_ss addsimps prems))) ]); 
   144 
   144 
   145 val add_succ_right = prove_goal Arith.thy
   145 qed_goal "add_succ_right" Arith.thy
   146     "m:nat ==> m #+ succ(n) = succ(m #+ n)"
   146     "m:nat ==> m #+ succ(n) = succ(m #+ n)"
   147  (fn prems=>
   147  (fn prems=>
   148   [ (nat_ind_tac "m" prems 1),
   148   [ (nat_ind_tac "m" prems 1),
   149     (ALLGOALS (asm_simp_tac (arith_ss addsimps prems))) ]); 
   149     (ALLGOALS (asm_simp_tac (arith_ss addsimps prems))) ]); 
   150 
   150 
   151 (*Commutative law for addition*)  
   151 (*Commutative law for addition*)  
   152 val add_commute = prove_goal Arith.thy 
   152 qed_goal "add_commute" Arith.thy 
   153     "!!m n. [| m:nat;  n:nat |] ==> m #+ n = n #+ m"
   153     "!!m n. [| m:nat;  n:nat |] ==> m #+ n = n #+ m"
   154  (fn _ =>
   154  (fn _ =>
   155   [ (nat_ind_tac "n" [] 1),
   155   [ (nat_ind_tac "n" [] 1),
   156     (ALLGOALS
   156     (ALLGOALS
   157      (asm_simp_tac (arith_ss addsimps [add_0_right, add_succ_right]))) ]);
   157      (asm_simp_tac (arith_ss addsimps [add_0_right, add_succ_right]))) ]);
   158 
   158 
   159 (*for a/c rewriting*)
   159 (*for a/c rewriting*)
   160 val add_left_commute = prove_goal Arith.thy
   160 qed_goal "add_left_commute" Arith.thy
   161     "!!m n k. [| m:nat;  n:nat |] ==> m#+(n#+k)=n#+(m#+k)"
   161     "!!m n k. [| m:nat;  n:nat |] ==> m#+(n#+k)=n#+(m#+k)"
   162  (fn _ => [asm_simp_tac (ZF_ss addsimps [add_assoc RS sym, add_commute]) 1]);
   162  (fn _ => [asm_simp_tac (ZF_ss addsimps [add_assoc RS sym, add_commute]) 1]);
   163 
   163 
   164 (*Addition is an AC-operator*)
   164 (*Addition is an AC-operator*)
   165 val add_ac = [add_assoc, add_commute, add_left_commute];
   165 val add_ac = [add_assoc, add_commute, add_left_commute];
   169     "[| k #+ m = k #+ n;  k:nat |] ==> m=n";
   169     "[| k #+ m = k #+ n;  k:nat |] ==> m=n";
   170 by (rtac (eqn RS rev_mp) 1);
   170 by (rtac (eqn RS rev_mp) 1);
   171 by (nat_ind_tac "k" [knat] 1);
   171 by (nat_ind_tac "k" [knat] 1);
   172 by (ALLGOALS (simp_tac arith_ss));
   172 by (ALLGOALS (simp_tac arith_ss));
   173 by (fast_tac ZF_cs 1);
   173 by (fast_tac ZF_cs 1);
   174 val add_left_cancel = result();
   174 qed "add_left_cancel";
   175 
   175 
   176 (*** Multiplication ***)
   176 (*** Multiplication ***)
   177 
   177 
   178 (*right annihilation in product*)
   178 (*right annihilation in product*)
   179 val mult_0_right = prove_goal Arith.thy 
   179 qed_goal "mult_0_right" Arith.thy 
   180     "!!m. m:nat ==> m #* 0 = 0"
   180     "!!m. m:nat ==> m #* 0 = 0"
   181  (fn _=>
   181  (fn _=>
   182   [ (nat_ind_tac "m" [] 1),
   182   [ (nat_ind_tac "m" [] 1),
   183     (ALLGOALS (asm_simp_tac arith_ss))  ]);
   183     (ALLGOALS (asm_simp_tac arith_ss))  ]);
   184 
   184 
   185 (*right successor law for multiplication*)
   185 (*right successor law for multiplication*)
   186 val mult_succ_right = prove_goal Arith.thy 
   186 qed_goal "mult_succ_right" Arith.thy 
   187     "!!m n. [| m:nat;  n:nat |] ==> m #* succ(n) = m #+ (m #* n)"
   187     "!!m n. [| m:nat;  n:nat |] ==> m #* succ(n) = m #+ (m #* n)"
   188  (fn _ =>
   188  (fn _ =>
   189   [ (nat_ind_tac "m" [] 1),
   189   [ (nat_ind_tac "m" [] 1),
   190     (ALLGOALS (asm_simp_tac (arith_ss addsimps add_ac))) ]);
   190     (ALLGOALS (asm_simp_tac (arith_ss addsimps add_ac))) ]);
   191 
   191 
   192 (*Commutative law for multiplication*)
   192 (*Commutative law for multiplication*)
   193 val mult_commute = prove_goal 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 val add_mult_distrib = prove_goal 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 _=>
   204   [ (etac nat_induct 1),
   204   [ (etac nat_induct 1),
   205     (ALLGOALS (asm_simp_tac (arith_ss addsimps [add_assoc RS sym]))) ]);
   205     (ALLGOALS (asm_simp_tac (arith_ss addsimps [add_assoc RS sym]))) ]);
   206 
   206 
   207 (*Distributive law on the left; requires an extra typing premise*)
   207 (*Distributive law on the left; requires an extra typing premise*)
   208 val add_mult_distrib_left = prove_goal Arith.thy 
   208 qed_goal "add_mult_distrib_left" Arith.thy 
   209     "!!m. [| m:nat;  n:nat;  k:nat |] ==> k #* (m #+ n) = (k #* m) #+ (k #* n)"
   209     "!!m. [| m:nat;  n:nat;  k:nat |] ==> k #* (m #+ n) = (k #* m) #+ (k #* n)"
   210  (fn prems=>
   210  (fn prems=>
   211   [ (nat_ind_tac "m" [] 1),
   211   [ (nat_ind_tac "m" [] 1),
   212     (asm_simp_tac (arith_ss addsimps [mult_0_right]) 1),
   212     (asm_simp_tac (arith_ss addsimps [mult_0_right]) 1),
   213     (asm_simp_tac (arith_ss addsimps ([mult_succ_right] @ add_ac)) 1) ]);
   213     (asm_simp_tac (arith_ss addsimps ([mult_succ_right] @ add_ac)) 1) ]);
   214 
   214 
   215 (*Associative law for multiplication*)
   215 (*Associative law for multiplication*)
   216 val mult_assoc = prove_goal Arith.thy 
   216 qed_goal "mult_assoc" Arith.thy 
   217     "!!m n k. [| m:nat;  n:nat;  k:nat |] ==> (m #* n) #* k = m #* (n #* k)"
   217     "!!m n k. [| m:nat;  n:nat;  k:nat |] ==> (m #* n) #* k = m #* (n #* k)"
   218  (fn _=>
   218  (fn _=>
   219   [ (etac nat_induct 1),
   219   [ (etac nat_induct 1),
   220     (ALLGOALS (asm_simp_tac (arith_ss addsimps [add_mult_distrib]))) ]);
   220     (ALLGOALS (asm_simp_tac (arith_ss addsimps [add_mult_distrib]))) ]);
   221 
   221 
   222 (*for a/c rewriting*)
   222 (*for a/c rewriting*)
   223 val mult_left_commute = prove_goal 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)]);
   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 ***)
   234 
   234 
   235 val diff_self_eq_0 = prove_goal Arith.thy 
   235 qed_goal "diff_self_eq_0" Arith.thy 
   236     "m:nat ==> m #- m = 0"
   236     "m:nat ==> m #- m = 0"
   237  (fn prems=>
   237  (fn prems=>
   238   [ (nat_ind_tac "m" prems 1),
   238   [ (nat_ind_tac "m" prems 1),
   239     (ALLGOALS (asm_simp_tac (arith_ss addsimps prems))) ]);
   239     (ALLGOALS (asm_simp_tac (arith_ss addsimps prems))) ]);
   240 
   240 
   243 by (forward_tac [lt_nat_in_nat] 1);
   243 by (forward_tac [lt_nat_in_nat] 1);
   244 by (etac nat_succI 1);
   244 by (etac nat_succI 1);
   245 by (etac rev_mp 1);
   245 by (etac rev_mp 1);
   246 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   246 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   247 by (ALLGOALS (asm_simp_tac arith_ss));
   247 by (ALLGOALS (asm_simp_tac arith_ss));
   248 val add_diff_inverse = result();
   248 qed "add_diff_inverse";
   249 
   249 
   250 (*Subtraction is the inverse of addition. *)
   250 (*Subtraction is the inverse of addition. *)
   251 val [mnat,nnat] = goal Arith.thy
   251 val [mnat,nnat] = goal Arith.thy
   252     "[| m:nat;  n:nat |] ==> (n#+m) #- n = m";
   252     "[| m:nat;  n:nat |] ==> (n#+m) #- n = m";
   253 by (rtac (nnat RS nat_induct) 1);
   253 by (rtac (nnat RS nat_induct) 1);
   254 by (ALLGOALS (asm_simp_tac (arith_ss addsimps [mnat])));
   254 by (ALLGOALS (asm_simp_tac (arith_ss addsimps [mnat])));
   255 val diff_add_inverse = result();
   255 qed "diff_add_inverse";
   256 
   256 
   257 goal Arith.thy
   257 goal Arith.thy
   258     "!!m n. [| m:nat;  n:nat |] ==> (m#+n) #- n = m";
   258     "!!m n. [| m:nat;  n:nat |] ==> (m#+n) #- n = m";
   259 by (res_inst_tac [("m1","m")] (add_commute RS ssubst) 1);
   259 by (res_inst_tac [("m1","m")] (add_commute RS ssubst) 1);
   260 by (REPEAT (ares_tac [diff_add_inverse] 1));
   260 by (REPEAT (ares_tac [diff_add_inverse] 1));
   261 val diff_add_inverse2 = result();
   261 qed "diff_add_inverse2";
   262 
   262 
   263 val [mnat,nnat] = goal Arith.thy
   263 val [mnat,nnat] = goal Arith.thy
   264     "[| m:nat;  n:nat |] ==> n #- (n#+m) = 0";
   264     "[| m:nat;  n:nat |] ==> n #- (n#+m) = 0";
   265 by (rtac (nnat RS nat_induct) 1);
   265 by (rtac (nnat RS nat_induct) 1);
   266 by (ALLGOALS (asm_simp_tac (arith_ss addsimps [mnat])));
   266 by (ALLGOALS (asm_simp_tac (arith_ss addsimps [mnat])));
   267 val diff_add_0 = result();
   267 qed "diff_add_0";
   268 
   268 
   269 
   269 
   270 (*** Remainder ***)
   270 (*** Remainder ***)
   271 
   271 
   272 goal Arith.thy "!!m n. [| 0<n;  n le m;  m:nat |] ==> m #- n < m";
   272 goal Arith.thy "!!m n. [| 0<n;  n le m;  m:nat |] ==> m #- n < m";
   273 by (forward_tac [lt_nat_in_nat] 1 THEN etac nat_succI 1);
   273 by (forward_tac [lt_nat_in_nat] 1 THEN etac nat_succI 1);
   274 by (etac rev_mp 1);
   274 by (etac rev_mp 1);
   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 val div_termination = result();
   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];
   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 val mod_type = result();
   291 qed "mod_type";
   292 
   292 
   293 goal Arith.thy "!!m n. [| 0<n;  m<n |] ==> m mod n = m";
   293 goal Arith.thy "!!m n. [| 0<n;  m<n |] ==> m mod n = m";
   294 by (rtac (mod_def RS def_transrec RS trans) 1);
   294 by (rtac (mod_def RS def_transrec RS trans) 1);
   295 by (asm_simp_tac div_ss 1);
   295 by (asm_simp_tac div_ss 1);
   296 val mod_less = result();
   296 qed "mod_less";
   297 
   297 
   298 goal Arith.thy "!!m n. [| 0<n;  n le m;  m:nat |] ==> m mod n = (m#-n) mod n";
   298 goal Arith.thy "!!m n. [| 0<n;  n le m;  m:nat |] ==> m mod n = (m#-n) mod n";
   299 by (forward_tac [lt_nat_in_nat] 1 THEN etac nat_succI 1);
   299 by (forward_tac [lt_nat_in_nat] 1 THEN etac nat_succI 1);
   300 by (rtac (mod_def RS def_transrec RS trans) 1);
   300 by (rtac (mod_def RS def_transrec RS trans) 1);
   301 by (asm_simp_tac div_ss 1);
   301 by (asm_simp_tac div_ss 1);
   302 val mod_geq = result();
   302 qed "mod_geq";
   303 
   303 
   304 (*** Quotient ***)
   304 (*** Quotient ***)
   305 
   305 
   306 (*Type checking depends upon termination!*)
   306 (*Type checking depends upon termination!*)
   307 goalw Arith.thy [div_def]
   307 goalw Arith.thy [div_def]
   308     "!!m n. [| 0<n;  m:nat;  n:nat |] ==> m div n : nat";
   308     "!!m n. [| 0<n;  m:nat;  n:nat |] ==> m div n : nat";
   309 by (REPEAT (ares_tac div_rls 1 ORELSE etac lt_trans 1));
   309 by (REPEAT (ares_tac div_rls 1 ORELSE etac lt_trans 1));
   310 val div_type = result();
   310 qed "div_type";
   311 
   311 
   312 goal Arith.thy "!!m n. [| 0<n;  m<n |] ==> m div n = 0";
   312 goal Arith.thy "!!m n. [| 0<n;  m<n |] ==> m div n = 0";
   313 by (rtac (div_def RS def_transrec RS trans) 1);
   313 by (rtac (div_def RS def_transrec RS trans) 1);
   314 by (asm_simp_tac div_ss 1);
   314 by (asm_simp_tac div_ss 1);
   315 val div_less = result();
   315 qed "div_less";
   316 
   316 
   317 goal Arith.thy
   317 goal Arith.thy
   318  "!!m n. [| 0<n;  n le m;  m:nat |] ==> m div n = succ((m#-n) div n)";
   318  "!!m n. [| 0<n;  n le m;  m:nat |] ==> m div n = succ((m#-n) div n)";
   319 by (forward_tac [lt_nat_in_nat] 1 THEN etac nat_succI 1);
   319 by (forward_tac [lt_nat_in_nat] 1 THEN etac nat_succI 1);
   320 by (rtac (div_def RS def_transrec RS trans) 1);
   320 by (rtac (div_def RS def_transrec RS trans) 1);
   321 by (asm_simp_tac div_ss 1);
   321 by (asm_simp_tac div_ss 1);
   322 val div_geq = result();
   322 qed "div_geq";
   323 
   323 
   324 (*Main Result.*)
   324 (*Main Result.*)
   325 goal Arith.thy
   325 goal Arith.thy
   326     "!!m n. [| 0<n;  m:nat;  n:nat |] ==> (m div n)#*n #+ m mod n = m";
   326     "!!m n. [| 0<n;  m:nat;  n:nat |] ==> (m div n)#*n #+ m mod n = m";
   327 by (etac complete_induct 1);
   327 by (etac complete_induct 1);
   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 val mod_div_equality = result();
   336 qed "mod_div_equality";
   337 
   337 
   338 
   338 
   339 (**** Additional theorems about "le" ****)
   339 (**** Additional theorems about "le" ****)
   340 
   340 
   341 goal Arith.thy "!!m n. [| m:nat;  n:nat |] ==> m le m #+ n";
   341 goal Arith.thy "!!m n. [| m:nat;  n:nat |] ==> m le m #+ n";
   342 by (etac nat_induct 1);
   342 by (etac nat_induct 1);
   343 by (ALLGOALS (asm_simp_tac arith_ss));
   343 by (ALLGOALS (asm_simp_tac arith_ss));
   344 val add_le_self = result();
   344 qed "add_le_self";
   345 
   345 
   346 goal Arith.thy "!!m n. [| m:nat;  n:nat |] ==> m le n #+ m";
   346 goal Arith.thy "!!m n. [| m:nat;  n:nat |] ==> m le n #+ m";
   347 by (rtac (add_commute RS ssubst) 1);
   347 by (rtac (add_commute RS ssubst) 1);
   348 by (REPEAT (ares_tac [add_le_self] 1));
   348 by (REPEAT (ares_tac [add_le_self] 1));
   349 val add_le_self2 = result();
   349 qed "add_le_self2";
   350 
   350 
   351 (** Monotonicity of addition **)
   351 (** Monotonicity of addition **)
   352 
   352 
   353 (*strict, in 1st argument*)
   353 (*strict, in 1st argument*)
   354 goal Arith.thy "!!i j k. [| i<j; j:nat; k:nat |] ==> i#+k < j#+k";
   354 goal Arith.thy "!!i j k. [| i<j; j:nat; k:nat |] ==> i#+k < j#+k";
   355 by (forward_tac [lt_nat_in_nat] 1);
   355 by (forward_tac [lt_nat_in_nat] 1);
   356 by (assume_tac 1);
   356 by (assume_tac 1);
   357 by (etac succ_lt_induct 1);
   357 by (etac succ_lt_induct 1);
   358 by (ALLGOALS (asm_simp_tac (arith_ss addsimps [leI])));
   358 by (ALLGOALS (asm_simp_tac (arith_ss addsimps [leI])));
   359 val add_lt_mono1 = result();
   359 qed "add_lt_mono1";
   360 
   360 
   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 val add_lt_mono = result();
   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 val Ord_lt_mono_imp_le_mono = result();
   379 qed "Ord_lt_mono_imp_le_mono";
   380 
   380 
   381 (*le monotonicity, 1st argument*)
   381 (*le monotonicity, 1st argument*)
   382 goal Arith.thy
   382 goal Arith.thy
   383     "!!i j k. [| i le j; j:nat; k:nat |] ==> i#+k le j#+k";
   383     "!!i j k. [| i le j; j:nat; k:nat |] ==> i#+k le j#+k";
   384 by (res_inst_tac [("f", "%j.j#+k")] Ord_lt_mono_imp_le_mono 1);
   384 by (res_inst_tac [("f", "%j.j#+k")] Ord_lt_mono_imp_le_mono 1);
   385 by (REPEAT (ares_tac [add_lt_mono1, add_type RS nat_into_Ord] 1));
   385 by (REPEAT (ares_tac [add_lt_mono1, add_type RS nat_into_Ord] 1));
   386 val add_le_mono1 = result();
   386 qed "add_le_mono1";
   387 
   387 
   388 (* le monotonicity, BOTH arguments*)
   388 (* le monotonicity, BOTH arguments*)
   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 val add_le_mono = result();
   397 qed "add_le_mono";