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