39 \ a: C(0); \ |
39 \ a: C(0); \ |
40 \ !!m z. [| m: nat; z: C(m) |] ==> b(m,z): C(succ(m)) \ |
40 \ !!m z. [| m: nat; z: C(m) |] ==> b(m,z): C(succ(m)) \ |
41 \ |] ==> rec(n,a,b) : C(n)"; |
41 \ |] ==> rec(n,a,b) : C(n)"; |
42 by (rtac (major RS nat_induct) 1); |
42 by (rtac (major RS nat_induct) 1); |
43 by (ALLGOALS |
43 by (ALLGOALS |
44 (asm_simp_tac (!simpset addsimps prems))); |
44 (asm_simp_tac (simpset() addsimps prems))); |
45 qed "rec_type"; |
45 qed "rec_type"; |
46 |
46 |
47 Addsimps [rec_type, nat_0_le, nat_le_refl]; |
47 Addsimps [rec_type, nat_0_le, nat_le_refl]; |
48 val nat_typechecks = [rec_type, nat_0I, nat_1I, nat_succI, Ord_nat]; |
48 val nat_typechecks = [rec_type, nat_0I, nat_1I, nat_succI, Ord_nat]; |
49 |
49 |
110 (*Must simplify BEFORE the induction!! (Else we get a critical pair) |
110 (*Must simplify BEFORE the induction!! (Else we get a critical pair) |
111 succ(m) #- succ(n) rewrites to pred(succ(m) #- n) *) |
111 succ(m) #- succ(n) rewrites to pred(succ(m) #- n) *) |
112 qed_goalw "diff_succ_succ" Arith.thy [diff_def] |
112 qed_goalw "diff_succ_succ" Arith.thy [diff_def] |
113 "[| m:nat; n:nat |] ==> succ(m) #- succ(n) = m #- n" |
113 "[| m:nat; n:nat |] ==> succ(m) #- succ(n) = m #- n" |
114 (fn prems=> |
114 (fn prems=> |
115 [ (asm_simp_tac (!simpset addsimps prems) 1), |
115 [ (asm_simp_tac (simpset() addsimps prems) 1), |
116 (nat_ind_tac "n" prems 1), |
116 (nat_ind_tac "n" prems 1), |
117 (ALLGOALS (asm_simp_tac (!simpset addsimps prems))) ]); |
117 (ALLGOALS (asm_simp_tac (simpset() addsimps prems))) ]); |
118 |
118 |
119 Addsimps [diff_0, diff_0_eq_0, diff_succ_succ]; |
119 Addsimps [diff_0, diff_0_eq_0, diff_succ_succ]; |
120 |
120 |
121 val prems = goal Arith.thy |
121 val prems = goal Arith.thy |
122 "[| m:nat; n:nat |] ==> m #- n le m"; |
122 "[| m:nat; n:nat |] ==> m #- n le m"; |
123 by (rtac (prems MRS diff_induct) 1); |
123 by (rtac (prems MRS diff_induct) 1); |
124 by (etac leE 3); |
124 by (etac leE 3); |
125 by (ALLGOALS |
125 by (ALLGOALS |
126 (asm_simp_tac (!simpset addsimps (prems @ [le_iff, nat_into_Ord])))); |
126 (asm_simp_tac (simpset() addsimps (prems @ [le_iff, nat_into_Ord])))); |
127 qed "diff_le_self"; |
127 qed "diff_le_self"; |
128 |
128 |
129 (*** Simplification over add, mult, diff ***) |
129 (*** Simplification over add, mult, diff ***) |
130 |
130 |
131 val arith_typechecks = [add_type, mult_type, diff_type]; |
131 val arith_typechecks = [add_type, mult_type, diff_type]; |
137 (*Associative law for addition*) |
137 (*Associative law for addition*) |
138 qed_goal "add_assoc" Arith.thy |
138 qed_goal "add_assoc" Arith.thy |
139 "m:nat ==> (m #+ n) #+ k = m #+ (n #+ k)" |
139 "m:nat ==> (m #+ n) #+ k = m #+ (n #+ k)" |
140 (fn prems=> |
140 (fn prems=> |
141 [ (nat_ind_tac "m" prems 1), |
141 [ (nat_ind_tac "m" prems 1), |
142 (ALLGOALS (asm_simp_tac (!simpset addsimps prems))) ]); |
142 (ALLGOALS (asm_simp_tac (simpset() addsimps prems))) ]); |
143 |
143 |
144 (*The following two lemmas are used for add_commute and sometimes |
144 (*The following two lemmas are used for add_commute and sometimes |
145 elsewhere, since they are safe for rewriting.*) |
145 elsewhere, since they are safe for rewriting.*) |
146 qed_goal "add_0_right" Arith.thy |
146 qed_goal "add_0_right" Arith.thy |
147 "m:nat ==> m #+ 0 = m" |
147 "m:nat ==> m #+ 0 = m" |
148 (fn prems=> |
148 (fn prems=> |
149 [ (nat_ind_tac "m" prems 1), |
149 [ (nat_ind_tac "m" prems 1), |
150 (ALLGOALS (asm_simp_tac (!simpset addsimps prems))) ]); |
150 (ALLGOALS (asm_simp_tac (simpset() addsimps prems))) ]); |
151 |
151 |
152 qed_goal "add_succ_right" Arith.thy |
152 qed_goal "add_succ_right" Arith.thy |
153 "m:nat ==> m #+ succ(n) = succ(m #+ n)" |
153 "m:nat ==> m #+ succ(n) = succ(m #+ n)" |
154 (fn prems=> |
154 (fn prems=> |
155 [ (nat_ind_tac "m" prems 1), |
155 [ (nat_ind_tac "m" prems 1), |
156 (ALLGOALS (asm_simp_tac (!simpset addsimps prems))) ]); |
156 (ALLGOALS (asm_simp_tac (simpset() addsimps prems))) ]); |
157 |
157 |
158 Addsimps [add_0_right, add_succ_right]; |
158 Addsimps [add_0_right, add_succ_right]; |
159 |
159 |
160 (*Commutative law for addition*) |
160 (*Commutative law for addition*) |
161 qed_goal "add_commute" Arith.thy |
161 qed_goal "add_commute" Arith.thy |
165 (ALLGOALS Asm_simp_tac) ]); |
165 (ALLGOALS Asm_simp_tac) ]); |
166 |
166 |
167 (*for a/c rewriting*) |
167 (*for a/c rewriting*) |
168 qed_goal "add_left_commute" Arith.thy |
168 qed_goal "add_left_commute" Arith.thy |
169 "!!m n k. [| m:nat; n:nat |] ==> m#+(n#+k)=n#+(m#+k)" |
169 "!!m n k. [| m:nat; n:nat |] ==> m#+(n#+k)=n#+(m#+k)" |
170 (fn _ => [asm_simp_tac(!simpset addsimps [add_assoc RS sym, add_commute]) 1]); |
170 (fn _ => [asm_simp_tac(simpset() addsimps [add_assoc RS sym, add_commute]) 1]); |
171 |
171 |
172 (*Addition is an AC-operator*) |
172 (*Addition is an AC-operator*) |
173 val add_ac = [add_assoc, add_commute, add_left_commute]; |
173 val add_ac = [add_assoc, add_commute, add_left_commute]; |
174 |
174 |
175 (*Cancellation law on the left*) |
175 (*Cancellation law on the left*) |
216 (*addition distributes over multiplication*) |
216 (*addition distributes over multiplication*) |
217 qed_goal "add_mult_distrib" Arith.thy |
217 qed_goal "add_mult_distrib" Arith.thy |
218 "!!m n. [| m:nat; k:nat |] ==> (m #+ n) #* k = (m #* k) #+ (n #* k)" |
218 "!!m n. [| m:nat; k:nat |] ==> (m #+ n) #* k = (m #* k) #+ (n #* k)" |
219 (fn _=> |
219 (fn _=> |
220 [ (etac nat_induct 1), |
220 [ (etac nat_induct 1), |
221 (ALLGOALS (asm_simp_tac (!simpset addsimps [add_assoc RS sym]))) ]); |
221 (ALLGOALS (asm_simp_tac (simpset() addsimps [add_assoc RS sym]))) ]); |
222 |
222 |
223 (*Distributive law on the left; requires an extra typing premise*) |
223 (*Distributive law on the left; requires an extra typing premise*) |
224 qed_goal "add_mult_distrib_left" Arith.thy |
224 qed_goal "add_mult_distrib_left" Arith.thy |
225 "!!m. [| m:nat; n:nat; k:nat |] ==> k #* (m #+ n) = (k #* m) #+ (k #* n)" |
225 "!!m. [| m:nat; n:nat; k:nat |] ==> k #* (m #+ n) = (k #* m) #+ (k #* n)" |
226 (fn prems=> |
226 (fn prems=> |
227 [ (nat_ind_tac "m" [] 1), |
227 [ (nat_ind_tac "m" [] 1), |
228 (Asm_simp_tac 1), |
228 (Asm_simp_tac 1), |
229 (asm_simp_tac (!simpset addsimps add_ac) 1) ]); |
229 (asm_simp_tac (simpset() addsimps add_ac) 1) ]); |
230 |
230 |
231 (*Associative law for multiplication*) |
231 (*Associative law for multiplication*) |
232 qed_goal "mult_assoc" Arith.thy |
232 qed_goal "mult_assoc" Arith.thy |
233 "!!m n k. [| m:nat; n:nat; k:nat |] ==> (m #* n) #* k = m #* (n #* k)" |
233 "!!m n k. [| m:nat; n:nat; k:nat |] ==> (m #* n) #* k = m #* (n #* k)" |
234 (fn _=> |
234 (fn _=> |
235 [ (etac nat_induct 1), |
235 [ (etac nat_induct 1), |
236 (ALLGOALS (asm_simp_tac (!simpset addsimps [add_mult_distrib]))) ]); |
236 (ALLGOALS (asm_simp_tac (simpset() addsimps [add_mult_distrib]))) ]); |
237 |
237 |
238 (*for a/c rewriting*) |
238 (*for a/c rewriting*) |
239 qed_goal "mult_left_commute" Arith.thy |
239 qed_goal "mult_left_commute" Arith.thy |
240 "!!m n k. [| m:nat; n:nat; k:nat |] ==> m #* (n #* k) = n #* (m #* k)" |
240 "!!m n k. [| m:nat; n:nat; k:nat |] ==> m #* (n #* k) = n #* (m #* k)" |
241 (fn _ => [rtac (mult_commute RS trans) 1, |
241 (fn _ => [rtac (mult_commute RS trans) 1, |
250 |
250 |
251 qed_goal "diff_self_eq_0" Arith.thy |
251 qed_goal "diff_self_eq_0" Arith.thy |
252 "m:nat ==> m #- m = 0" |
252 "m:nat ==> m #- m = 0" |
253 (fn prems=> |
253 (fn prems=> |
254 [ (nat_ind_tac "m" prems 1), |
254 [ (nat_ind_tac "m" prems 1), |
255 (ALLGOALS (asm_simp_tac (!simpset addsimps prems))) ]); |
255 (ALLGOALS (asm_simp_tac (simpset() addsimps prems))) ]); |
256 |
256 |
257 (*Addition is the inverse of subtraction*) |
257 (*Addition is the inverse of subtraction*) |
258 goal Arith.thy "!!m n. [| n le m; m:nat |] ==> n #+ (m#-n) = m"; |
258 goal Arith.thy "!!m n. [| n le m; m:nat |] ==> n #+ (m#-n) = m"; |
259 by (forward_tac [lt_nat_in_nat] 1); |
259 by (forward_tac [lt_nat_in_nat] 1); |
260 by (etac nat_succI 1); |
260 by (etac nat_succI 1); |
275 (** Subtraction is the inverse of addition. **) |
275 (** Subtraction is the inverse of addition. **) |
276 |
276 |
277 val [mnat,nnat] = goal Arith.thy |
277 val [mnat,nnat] = goal Arith.thy |
278 "[| m:nat; n:nat |] ==> (n#+m) #- n = m"; |
278 "[| m:nat; n:nat |] ==> (n#+m) #- n = m"; |
279 by (rtac (nnat RS nat_induct) 1); |
279 by (rtac (nnat RS nat_induct) 1); |
280 by (ALLGOALS (asm_simp_tac (!simpset addsimps [mnat]))); |
280 by (ALLGOALS (asm_simp_tac (simpset() addsimps [mnat]))); |
281 qed "diff_add_inverse"; |
281 qed "diff_add_inverse"; |
282 |
282 |
283 goal Arith.thy |
283 goal Arith.thy |
284 "!!m n. [| m:nat; n:nat |] ==> (m#+n) #- n = m"; |
284 "!!m n. [| m:nat; n:nat |] ==> (m#+n) #- n = m"; |
285 by (res_inst_tac [("m1","m")] (add_commute RS ssubst) 1); |
285 by (res_inst_tac [("m1","m")] (add_commute RS ssubst) 1); |
293 qed "diff_cancel"; |
293 qed "diff_cancel"; |
294 |
294 |
295 goal Arith.thy |
295 goal Arith.thy |
296 "!!n. [| k:nat; m: nat; n: nat |] ==> (m#+k) #- (n#+k) = m #- n"; |
296 "!!n. [| k:nat; m: nat; n: nat |] ==> (m#+k) #- (n#+k) = m #- n"; |
297 val add_commute_k = read_instantiate [("n","k")] add_commute; |
297 val add_commute_k = read_instantiate [("n","k")] add_commute; |
298 by (asm_simp_tac (!simpset addsimps [add_commute_k, diff_cancel]) 1); |
298 by (asm_simp_tac (simpset() addsimps [add_commute_k, diff_cancel]) 1); |
299 qed "diff_cancel2"; |
299 qed "diff_cancel2"; |
300 |
300 |
301 val [mnat,nnat] = goal Arith.thy |
301 val [mnat,nnat] = goal Arith.thy |
302 "[| m:nat; n:nat |] ==> n #- (n#+m) = 0"; |
302 "[| m:nat; n:nat |] ==> n #- (n#+m) = 0"; |
303 by (rtac (nnat RS nat_induct) 1); |
303 by (rtac (nnat RS nat_induct) 1); |
304 by (ALLGOALS (asm_simp_tac (!simpset addsimps [mnat]))); |
304 by (ALLGOALS (asm_simp_tac (simpset() addsimps [mnat]))); |
305 qed "diff_add_0"; |
305 qed "diff_add_0"; |
306 |
306 |
307 (** Difference distributes over multiplication **) |
307 (** Difference distributes over multiplication **) |
308 |
308 |
309 goal Arith.thy |
309 goal Arith.thy |
310 "!!m n. [| m:nat; n: nat; k:nat |] ==> (m #- n) #* k = (m #* k) #- (n #* k)"; |
310 "!!m n. [| m:nat; n: nat; k:nat |] ==> (m #- n) #* k = (m #* k) #- (n #* k)"; |
311 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); |
311 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); |
312 by (ALLGOALS (asm_simp_tac (!simpset addsimps [diff_cancel]))); |
312 by (ALLGOALS (asm_simp_tac (simpset() addsimps [diff_cancel]))); |
313 qed "diff_mult_distrib" ; |
313 qed "diff_mult_distrib" ; |
314 |
314 |
315 goal Arith.thy |
315 goal Arith.thy |
316 "!!m. [| m:nat; n: nat; k:nat |] ==> k #* (m #- n) = (k #* m) #- (k #* n)"; |
316 "!!m. [| m:nat; n: nat; k:nat |] ==> k #* (m #- n) = (k #* m) #- (k #* n)"; |
317 val mult_commute_k = read_instantiate [("m","k")] mult_commute; |
317 val mult_commute_k = read_instantiate [("m","k")] mult_commute; |
318 by (asm_simp_tac (!simpset addsimps |
318 by (asm_simp_tac (simpset() addsimps |
319 [mult_commute_k, diff_mult_distrib]) 1); |
319 [mult_commute_k, diff_mult_distrib]) 1); |
320 qed "diff_mult_distrib2" ; |
320 qed "diff_mult_distrib2" ; |
321 |
321 |
322 (*** Remainder ***) |
322 (*** Remainder ***) |
323 |
323 |
324 goal Arith.thy "!!m n. [| 0<n; n le m; m:nat |] ==> m #- n < m"; |
324 goal Arith.thy "!!m n. [| 0<n; n le m; m:nat |] ==> m #- n < m"; |
325 by (forward_tac [lt_nat_in_nat] 1 THEN etac nat_succI 1); |
325 by (forward_tac [lt_nat_in_nat] 1 THEN etac nat_succI 1); |
326 by (etac rev_mp 1); |
326 by (etac rev_mp 1); |
327 by (etac rev_mp 1); |
327 by (etac rev_mp 1); |
328 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); |
328 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); |
329 by (ALLGOALS (asm_simp_tac (!simpset addsimps [diff_le_self,diff_succ_succ]))); |
329 by (ALLGOALS (asm_simp_tac (simpset() addsimps [diff_le_self,diff_succ_succ]))); |
330 qed "div_termination"; |
330 qed "div_termination"; |
331 |
331 |
332 val div_rls = (*for mod and div*) |
332 val div_rls = (*for mod and div*) |
333 nat_typechecks @ |
333 nat_typechecks @ |
334 [Ord_transrec_type, apply_type, div_termination RS ltD, if_type, |
334 [Ord_transrec_type, apply_type, div_termination RS ltD, if_type, |
335 nat_into_Ord, not_lt_iff_le RS iffD1]; |
335 nat_into_Ord, not_lt_iff_le RS iffD1]; |
336 |
336 |
337 val div_ss = (!simpset) addsimps [nat_into_Ord, div_termination RS ltD, |
337 val div_ss = (simpset()) addsimps [nat_into_Ord, div_termination RS ltD, |
338 not_lt_iff_le RS iffD2]; |
338 not_lt_iff_le RS iffD2]; |
339 |
339 |
340 (*Type checking depends upon termination!*) |
340 (*Type checking depends upon termination!*) |
341 goalw Arith.thy [mod_def] "!!m n. [| 0<n; m:nat; n:nat |] ==> m mod n : nat"; |
341 goalw Arith.thy [mod_def] "!!m n. [| 0<n; m:nat; n:nat |] ==> m mod n : nat"; |
342 by (REPEAT (ares_tac div_rls 1 ORELSE etac lt_trans 1)); |
342 by (REPEAT (ares_tac div_rls 1 ORELSE etac lt_trans 1)); |
396 "!!m n. [| 0<n; m:nat; n:nat |] ==> \ |
396 "!!m n. [| 0<n; m:nat; n:nat |] ==> \ |
397 \ succ(m) mod n = if(succ(m mod n) = n, 0, succ(m mod n))"; |
397 \ succ(m) mod n = if(succ(m mod n) = n, 0, succ(m mod n))"; |
398 by (etac complete_induct 1); |
398 by (etac complete_induct 1); |
399 by (excluded_middle_tac "succ(x)<n" 1); |
399 by (excluded_middle_tac "succ(x)<n" 1); |
400 (* case succ(x) < n *) |
400 (* case succ(x) < n *) |
401 by (asm_simp_tac (!simpset addsimps [mod_less, nat_le_refl RS lt_trans, |
401 by (asm_simp_tac (simpset() addsimps [mod_less, nat_le_refl RS lt_trans, |
402 succ_neq_self]) 2); |
402 succ_neq_self]) 2); |
403 by (asm_simp_tac (!simpset addsimps [ltD RS mem_imp_not_eq]) 2); |
403 by (asm_simp_tac (simpset() addsimps [ltD RS mem_imp_not_eq]) 2); |
404 (* case n le succ(x) *) |
404 (* case n le succ(x) *) |
405 by (asm_full_simp_tac |
405 by (asm_full_simp_tac |
406 (!simpset addsimps [not_lt_iff_le, nat_into_Ord, mod_geq]) 1); |
406 (simpset() addsimps [not_lt_iff_le, nat_into_Ord, mod_geq]) 1); |
407 by (etac leE 1); |
407 by (etac leE 1); |
408 by (asm_simp_tac (!simpset addsimps [div_termination RS ltD, diff_succ, |
408 by (asm_simp_tac (simpset() addsimps [div_termination RS ltD, diff_succ, |
409 mod_geq]) 1); |
409 mod_geq]) 1); |
410 by (asm_simp_tac (!simpset addsimps [mod_less, diff_self_eq_0]) 1); |
410 by (asm_simp_tac (simpset() addsimps [mod_less, diff_self_eq_0]) 1); |
411 qed "mod_succ"; |
411 qed "mod_succ"; |
412 |
412 |
413 goal Arith.thy "!!m n. [| 0<n; m:nat; n:nat |] ==> m mod n < n"; |
413 goal Arith.thy "!!m n. [| 0<n; m:nat; n:nat |] ==> m mod n < n"; |
414 by (etac complete_induct 1); |
414 by (etac complete_induct 1); |
415 by (excluded_middle_tac "x<n" 1); |
415 by (excluded_middle_tac "x<n" 1); |
416 (*case x<n*) |
416 (*case x<n*) |
417 by (asm_simp_tac (!simpset addsimps [mod_less]) 2); |
417 by (asm_simp_tac (simpset() addsimps [mod_less]) 2); |
418 (*case n le x*) |
418 (*case n le x*) |
419 by (asm_full_simp_tac |
419 by (asm_full_simp_tac |
420 (!simpset addsimps [not_lt_iff_le, nat_into_Ord, |
420 (simpset() addsimps [not_lt_iff_le, nat_into_Ord, |
421 mod_geq, div_termination RS ltD]) 1); |
421 mod_geq, div_termination RS ltD]) 1); |
422 qed "mod_less_divisor"; |
422 qed "mod_less_divisor"; |
423 |
423 |
424 |
424 |
425 goal Arith.thy |
425 goal Arith.thy |
426 "!!k b. [| k: nat; b<2 |] ==> k mod 2 = b | k mod 2 = if(b=1,0,1)"; |
426 "!!k b. [| k: nat; b<2 |] ==> k mod 2 = b | k mod 2 = if(b=1,0,1)"; |
427 by (subgoal_tac "k mod 2: 2" 1); |
427 by (subgoal_tac "k mod 2: 2" 1); |
428 by (asm_simp_tac (!simpset addsimps [mod_less_divisor RS ltD]) 2); |
428 by (asm_simp_tac (simpset() addsimps [mod_less_divisor RS ltD]) 2); |
429 by (dtac ltD 1); |
429 by (dtac ltD 1); |
430 by (asm_simp_tac (!simpset setloop split_tac [expand_if]) 1); |
430 by (asm_simp_tac (simpset() setloop split_tac [expand_if]) 1); |
431 by (Blast_tac 1); |
431 by (Blast_tac 1); |
432 qed "mod2_cases"; |
432 qed "mod2_cases"; |
433 |
433 |
434 goal Arith.thy "!!m. m:nat ==> succ(succ(m)) mod 2 = m mod 2"; |
434 goal Arith.thy "!!m. m:nat ==> succ(succ(m)) mod 2 = m mod 2"; |
435 by (subgoal_tac "m mod 2: 2" 1); |
435 by (subgoal_tac "m mod 2: 2" 1); |
436 by (asm_simp_tac (!simpset addsimps [mod_less_divisor RS ltD]) 2); |
436 by (asm_simp_tac (simpset() addsimps [mod_less_divisor RS ltD]) 2); |
437 by (asm_simp_tac (!simpset addsimps [mod_succ] setloop Step_tac) 1); |
437 by (asm_simp_tac (simpset() addsimps [mod_succ] setloop Step_tac) 1); |
438 qed "mod2_succ_succ"; |
438 qed "mod2_succ_succ"; |
439 |
439 |
440 goal Arith.thy "!!m. m:nat ==> (m#+m) mod 2 = 0"; |
440 goal Arith.thy "!!m. m:nat ==> (m#+m) mod 2 = 0"; |
441 by (etac nat_induct 1); |
441 by (etac nat_induct 1); |
442 by (simp_tac (!simpset addsimps [mod_less]) 1); |
442 by (simp_tac (simpset() addsimps [mod_less]) 1); |
443 by (asm_simp_tac (!simpset addsimps [mod2_succ_succ, add_succ_right]) 1); |
443 by (asm_simp_tac (simpset() addsimps [mod2_succ_succ, add_succ_right]) 1); |
444 qed "mod2_add_self"; |
444 qed "mod2_add_self"; |
445 |
445 |
446 |
446 |
447 (**** Additional theorems about "le" ****) |
447 (**** Additional theorems about "le" ****) |
448 |
448 |
461 (*strict, in 1st argument; proof is by rule induction on 'less than'*) |
461 (*strict, in 1st argument; proof is by rule induction on 'less than'*) |
462 goal Arith.thy "!!i j k. [| i<j; j:nat; k:nat |] ==> i#+k < j#+k"; |
462 goal Arith.thy "!!i j k. [| i<j; j:nat; k:nat |] ==> i#+k < j#+k"; |
463 by (forward_tac [lt_nat_in_nat] 1); |
463 by (forward_tac [lt_nat_in_nat] 1); |
464 by (assume_tac 1); |
464 by (assume_tac 1); |
465 by (etac succ_lt_induct 1); |
465 by (etac succ_lt_induct 1); |
466 by (ALLGOALS (asm_simp_tac (!simpset addsimps [leI]))); |
466 by (ALLGOALS (asm_simp_tac (simpset() addsimps [leI]))); |
467 qed "add_lt_mono1"; |
467 qed "add_lt_mono1"; |
468 |
468 |
469 (*strict, in both arguments*) |
469 (*strict, in both arguments*) |
470 goal Arith.thy "!!i j k l. [| i<j; k<l; j:nat; l:nat |] ==> i#+k < j#+l"; |
470 goal Arith.thy "!!i j k l. [| i<j; k<l; j:nat; l:nat |] ==> i#+k < j#+l"; |
471 by (rtac (add_lt_mono1 RS lt_trans) 1); |
471 by (rtac (add_lt_mono1 RS lt_trans) 1); |
527 goal Arith.thy "!!i j k. [| i<j; 0<k; j:nat; k:nat |] ==> k#*i < k#*j"; |
527 goal Arith.thy "!!i j k. [| i<j; 0<k; j:nat; k:nat |] ==> k#*i < k#*j"; |
528 by (etac zero_lt_natE 1); |
528 by (etac zero_lt_natE 1); |
529 by (forward_tac [lt_nat_in_nat] 2); |
529 by (forward_tac [lt_nat_in_nat] 2); |
530 by (ALLGOALS Asm_simp_tac); |
530 by (ALLGOALS Asm_simp_tac); |
531 by (nat_ind_tac "x" [] 1); |
531 by (nat_ind_tac "x" [] 1); |
532 by (ALLGOALS (asm_simp_tac (!simpset addsimps [add_lt_mono]))); |
532 by (ALLGOALS (asm_simp_tac (simpset() addsimps [add_lt_mono]))); |
533 qed "mult_lt_mono2"; |
533 qed "mult_lt_mono2"; |
534 |
534 |
535 goal Arith.thy "!!k. [| m: nat; n: nat |] ==> 0 < m#*n <-> 0<m & 0<n"; |
535 goal Arith.thy "!!k. [| m: nat; n: nat |] ==> 0 < m#*n <-> 0<m & 0<n"; |
536 by (best_tac (!claset addEs [natE] addss (!simpset)) 1); |
536 by (best_tac (claset() addEs [natE] addss (simpset())) 1); |
537 qed "zero_lt_mult_iff"; |
537 qed "zero_lt_mult_iff"; |
538 |
538 |
539 goal Arith.thy "!!k. [| m: nat; n: nat |] ==> m#*n = 1 <-> m=1 & n=1"; |
539 goal Arith.thy "!!k. [| m: nat; n: nat |] ==> m#*n = 1 <-> m=1 & n=1"; |
540 by (best_tac (!claset addEs [natE] addss (!simpset)) 1); |
540 by (best_tac (claset() addEs [natE] addss (simpset())) 1); |
541 qed "mult_eq_1_iff"; |
541 qed "mult_eq_1_iff"; |
542 |
542 |
543 (*Cancellation law for division*) |
543 (*Cancellation law for division*) |
544 goal Arith.thy |
544 goal Arith.thy |
545 "!!k. [| 0<n; 0<k; k:nat; m:nat; n:nat |] ==> (k#*m) div (k#*n) = m div n"; |
545 "!!k. [| 0<n; 0<k; k:nat; m:nat; n:nat |] ==> (k#*m) div (k#*n) = m div n"; |
546 by (eres_inst_tac [("i","m")] complete_induct 1); |
546 by (eres_inst_tac [("i","m")] complete_induct 1); |
547 by (excluded_middle_tac "x<n" 1); |
547 by (excluded_middle_tac "x<n" 1); |
548 by (asm_simp_tac (!simpset addsimps [div_less, zero_lt_mult_iff, |
548 by (asm_simp_tac (simpset() addsimps [div_less, zero_lt_mult_iff, |
549 mult_lt_mono2]) 2); |
549 mult_lt_mono2]) 2); |
550 by (asm_full_simp_tac |
550 by (asm_full_simp_tac |
551 (!simpset addsimps [not_lt_iff_le, nat_into_Ord, |
551 (simpset() addsimps [not_lt_iff_le, nat_into_Ord, |
552 zero_lt_mult_iff, le_refl RS mult_le_mono, div_geq, |
552 zero_lt_mult_iff, le_refl RS mult_le_mono, div_geq, |
553 diff_mult_distrib2 RS sym, |
553 diff_mult_distrib2 RS sym, |
554 div_termination RS ltD]) 1); |
554 div_termination RS ltD]) 1); |
555 qed "div_cancel"; |
555 qed "div_cancel"; |
556 |
556 |
557 goal Arith.thy |
557 goal Arith.thy |
558 "!!k. [| 0<n; 0<k; k:nat; m:nat; n:nat |] ==> \ |
558 "!!k. [| 0<n; 0<k; k:nat; m:nat; n:nat |] ==> \ |
559 \ (k#*m) mod (k#*n) = k #* (m mod n)"; |
559 \ (k#*m) mod (k#*n) = k #* (m mod n)"; |
560 by (eres_inst_tac [("i","m")] complete_induct 1); |
560 by (eres_inst_tac [("i","m")] complete_induct 1); |
561 by (excluded_middle_tac "x<n" 1); |
561 by (excluded_middle_tac "x<n" 1); |
562 by (asm_simp_tac (!simpset addsimps [mod_less, zero_lt_mult_iff, |
562 by (asm_simp_tac (simpset() addsimps [mod_less, zero_lt_mult_iff, |
563 mult_lt_mono2]) 2); |
563 mult_lt_mono2]) 2); |
564 by (asm_full_simp_tac |
564 by (asm_full_simp_tac |
565 (!simpset addsimps [not_lt_iff_le, nat_into_Ord, |
565 (simpset() addsimps [not_lt_iff_le, nat_into_Ord, |
566 zero_lt_mult_iff, le_refl RS mult_le_mono, mod_geq, |
566 zero_lt_mult_iff, le_refl RS mult_le_mono, mod_geq, |
567 diff_mult_distrib2 RS sym, |
567 diff_mult_distrib2 RS sym, |
568 div_termination RS ltD]) 1); |
568 div_termination RS ltD]) 1); |
569 qed "mult_mod_distrib"; |
569 qed "mult_mod_distrib"; |
570 |
570 |
574 |
574 |
575 goal Arith.thy "!!m n. [| m = m#*n; m: nat; n: nat |] ==> n=1 | m=0"; |
575 goal Arith.thy "!!m n. [| m = m#*n; m: nat; n: nat |] ==> n=1 | m=0"; |
576 by (rtac disjCI 1); |
576 by (rtac disjCI 1); |
577 by (dtac sym 1); |
577 by (dtac sym 1); |
578 by (rtac Ord_linear_lt 1 THEN REPEAT_SOME (ares_tac [nat_into_Ord,nat_1I])); |
578 by (rtac Ord_linear_lt 1 THEN REPEAT_SOME (ares_tac [nat_into_Ord,nat_1I])); |
579 by (fast_tac (!claset addss (!simpset)) 1); |
579 by (fast_tac (claset() addss (simpset())) 1); |
580 by (fast_tac (le_cs addDs [mono_lemma] |
580 by (fast_tac (le_cs addDs [mono_lemma] |
581 addss (!simpset addsimps [mult_1_right])) 1); |
581 addss (simpset() addsimps [mult_1_right])) 1); |
582 qed "mult_eq_self_implies_10"; |
582 qed "mult_eq_self_implies_10"; |
583 |
583 |
584 |
584 |
585 (*Thanks to Sten Agerholm*) |
585 (*Thanks to Sten Agerholm*) |
586 goal Arith.thy (* add_le_elim1 *) |
586 goal Arith.thy (* add_le_elim1 *) |
587 "!!m n k. [|m#+n le m#+k; m:nat; n:nat; k:nat|] ==> n le k"; |
587 "!!m n k. [|m#+n le m#+k; m:nat; n:nat; k:nat|] ==> n le k"; |
588 by (etac rev_mp 1); |
588 by (etac rev_mp 1); |
589 by (eres_inst_tac [("n","n")] nat_induct 1); |
589 by (eres_inst_tac [("n","n")] nat_induct 1); |
590 by (Asm_simp_tac 1); |
590 by (Asm_simp_tac 1); |
591 by Safe_tac; |
591 by Safe_tac; |
592 by (asm_full_simp_tac (!simpset addsimps [not_le_iff_lt,nat_into_Ord]) 1); |
592 by (asm_full_simp_tac (simpset() addsimps [not_le_iff_lt,nat_into_Ord]) 1); |
593 by (etac lt_asym 1); |
593 by (etac lt_asym 1); |
594 by (assume_tac 1); |
594 by (assume_tac 1); |
595 by (Asm_full_simp_tac 1); |
595 by (Asm_full_simp_tac 1); |
596 by (asm_full_simp_tac (!simpset addsimps [le_iff, nat_into_Ord]) 1); |
596 by (asm_full_simp_tac (simpset() addsimps [le_iff, nat_into_Ord]) 1); |
597 by (Blast_tac 1); |
597 by (Blast_tac 1); |
598 qed "add_le_elim1"; |
598 qed "add_le_elim1"; |
599 |
599 |