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"; |