| changeset 266 | b1b47d28c295 | 
| parent 265 | fa3c214559b0 | 
| child 269 | fa40fd8abb54 | 
| 265:fa3c214559b0 | 266:b1b47d28c295 | 
|---|---|
176 | "arity (Id m n) = m"  | 
176 | "arity (Id m n) = m"  | 
177 | "arity (Cn n f gs) = n"  | 
177 | "arity (Cn n f gs) = n"  | 
178 | "arity (Pr n f g) = Suc n"  | 
178 | "arity (Pr n f g) = Suc n"  | 
179 | "arity (Mn n f) = n"  | 
179 | "arity (Mn n f) = n"  | 
180  | 
180  | 
181 text {* Abbreviations for calculating the arity of the constructors *}  | 
|
182  | 
|
181 abbreviation  | 
183 abbreviation  | 
182 "CN f gs \<equiv> Cn (arity (hd gs)) f gs"  | 
184 "CN f gs \<equiv> Cn (arity (hd gs)) f gs"  | 
183  | 
185  | 
184 abbreviation  | 
186 abbreviation  | 
185 "PR f g \<equiv> Pr (arity f) f g"  | 
187 "PR f g \<equiv> Pr (arity f) f g"  | 
186  | 
188  | 
187 abbreviation  | 
189 abbreviation  | 
188 "MN f \<equiv> Mn (arity f - 1) f"  | 
190 "MN f \<equiv> Mn (arity f - 1) f"  | 
191  | 
|
192 text {* the evaluation function and termination relation *}  | 
|
189  | 
193  | 
190 fun rec_eval :: "recf \<Rightarrow> nat list \<Rightarrow> nat"  | 
194 fun rec_eval :: "recf \<Rightarrow> nat list \<Rightarrow> nat"  | 
191 where  | 
195 where  | 
192 "rec_eval Z xs = 0"  | 
196 "rec_eval Z xs = 0"  | 
193 | "rec_eval S xs = Suc (xs ! 0)"  | 
197 | "rec_eval S xs = Suc (xs ! 0)"  | 
213 | termi_mn: "\<lbrakk>length xs = n; terminates f (r # xs);  | 
217 | termi_mn: "\<lbrakk>length xs = n; terminates f (r # xs);  | 
214 rec_eval f (r # xs) = 0;  | 
218 rec_eval f (r # xs) = 0;  | 
215 \<forall> i < r. terminates f (i # xs) \<and> rec_eval f (i # xs) > 0\<rbrakk> \<Longrightarrow> terminates (Mn n f) xs"  | 
219 \<forall> i < r. terminates f (i # xs) \<and> rec_eval f (i # xs) > 0\<rbrakk> \<Longrightarrow> terminates (Mn n f) xs"  | 
216  | 
220  | 
217  | 
221  | 
218 section {* Recursive Function Definitions *}  | 
222 section {* Arithmetic Functions *}  | 
219  | 
223  | 
220 text {*  | 
224 text {*  | 
221 @{text "constn n"} is the recursive function which computes  | 
225 @{text "constn n"} is the recursive function which computes  | 
222 natural number @{text "n"}.  | 
226 natural number @{text "n"}.  | 
223 *}  | 
227 *}  | 
245 "rec_pred = CN (PR Z (Id 3 0)) [Id 1 0, Id 1 0]"  | 
249 "rec_pred = CN (PR Z (Id 3 0)) [Id 1 0, Id 1 0]"  | 
246  | 
250  | 
247 definition  | 
251 definition  | 
248 "rec_minus = rec_swap (PR (Id 1 0) (CN rec_pred [Id 3 1]))"  | 
252 "rec_minus = rec_swap (PR (Id 1 0) (CN rec_pred [Id 3 1]))"  | 
249  | 
253  | 
254 lemma constn_lemma [simp]:  | 
|
255 "rec_eval (constn n) xs = n"  | 
|
256 by (induct n) (simp_all)  | 
|
257  | 
|
258 lemma swap_lemma [simp]:  | 
|
259 "rec_eval (rec_swap f) [x, y] = rec_eval f [y, x]"  | 
|
260 by (simp add: rec_swap_def)  | 
|
261  | 
|
262 lemma add_lemma [simp]:  | 
|
263 "rec_eval rec_add [x, y] = x + y"  | 
|
264 by (induct x) (simp_all add: rec_add_def)  | 
|
265  | 
|
266 lemma mult_lemma [simp]:  | 
|
267 "rec_eval rec_mult [x, y] = x * y"  | 
|
268 by (induct x) (simp_all add: rec_mult_def)  | 
|
269  | 
|
270 lemma power_lemma [simp]:  | 
|
271 "rec_eval rec_power [x, y] = x ^ y"  | 
|
272 by (induct y) (simp_all add: rec_power_def)  | 
|
273  | 
|
274 lemma fact_lemma [simp]:  | 
|
275 "rec_eval rec_fact [x] = fact x"  | 
|
276 by (induct x) (simp_all add: rec_fact_def)  | 
|
277  | 
|
278 lemma pred_lemma [simp]:  | 
|
279 "rec_eval rec_pred [x] = x - 1"  | 
|
280 by (induct x) (simp_all add: rec_pred_def)  | 
|
281  | 
|
282 lemma minus_lemma [simp]:  | 
|
283 "rec_eval rec_minus [x, y] = x - y"  | 
|
284 by (induct y) (simp_all add: rec_minus_def)  | 
|
285  | 
|
286  | 
|
287 section {* Logical functions *}  | 
|
250  | 
288  | 
251 text {*  | 
289 text {*  | 
252 The @{text "sign"} function returns 1 when the input argument  | 
290 The @{text "sign"} function returns 1 when the input argument  | 
253 is greater than @{text "0"}. *}  | 
291 is greater than @{text "0"}. *}  | 
254  | 
292  | 
284 "rec_ifz = PR (Id 2 0) (Id 4 3)"  | 
322 "rec_ifz = PR (Id 2 0) (Id 4 3)"  | 
285  | 
323  | 
286 definition  | 
324 definition  | 
287 "rec_if = CN rec_ifz [CN rec_not [Id 3 0], Id 3 1, Id 3 2]"  | 
325 "rec_if = CN rec_ifz [CN rec_not [Id 3 0], Id 3 1, Id 3 2]"  | 
288  | 
326  | 
327  | 
|
328 lemma sign_lemma [simp]:  | 
|
329 "rec_eval rec_sign [x] = (if x = 0 then 0 else 1)"  | 
|
330 by (simp add: rec_sign_def)  | 
|
331  | 
|
332 lemma not_lemma [simp]:  | 
|
333 "rec_eval rec_not [x] = (if x = 0 then 1 else 0)"  | 
|
334 by (simp add: rec_not_def)  | 
|
335  | 
|
336 lemma eq_lemma [simp]:  | 
|
337 "rec_eval rec_eq [x, y] = (if x = y then 1 else 0)"  | 
|
338 by (simp add: rec_eq_def)  | 
|
339  | 
|
340 lemma noteq_lemma [simp]:  | 
|
341 "rec_eval rec_noteq [x, y] = (if x \<noteq> y then 1 else 0)"  | 
|
342 by (simp add: rec_noteq_def)  | 
|
343  | 
|
344 lemma conj_lemma [simp]:  | 
|
345 "rec_eval rec_conj [x, y] = (if x = 0 \<or> y = 0 then 0 else 1)"  | 
|
346 by (simp add: rec_conj_def)  | 
|
347  | 
|
348 lemma disj_lemma [simp]:  | 
|
349 "rec_eval rec_disj [x, y] = (if x = 0 \<and> y = 0 then 0 else 1)"  | 
|
350 by (simp add: rec_disj_def)  | 
|
351  | 
|
352 lemma imp_lemma [simp]:  | 
|
353 "rec_eval rec_imp [x, y] = (if 0 < x \<and> y = 0 then 0 else 1)"  | 
|
354 by (simp add: rec_imp_def)  | 
|
355  | 
|
356 lemma ifz_lemma [simp]:  | 
|
357 "rec_eval rec_ifz [z, x, y] = (if z = 0 then x else y)"  | 
|
358 by (case_tac z) (simp_all add: rec_ifz_def)  | 
|
359  | 
|
360 lemma if_lemma [simp]:  | 
|
361 "rec_eval rec_if [z, x, y] = (if 0 < z then x else y)"  | 
|
362 by (simp add: rec_if_def)  | 
|
363  | 
|
364 section {* Less and Le Relations *}  | 
|
365  | 
|
289 text {*  | 
366 text {*  | 
290 @{text "rec_less"} compares two arguments and returns @{text "1"} if  | 
367 @{text "rec_less"} compares two arguments and returns @{text "1"} if  | 
291 the first is less than the second; otherwise returns @{text "0"}. *}  | 
368 the first is less than the second; otherwise returns @{text "0"}. *}  | 
292  | 
369  | 
293 definition  | 
370 definition  | 
294 "rec_less = CN rec_sign [rec_swap rec_minus]"  | 
371 "rec_less = CN rec_sign [rec_swap rec_minus]"  | 
295  | 
372  | 
296 definition  | 
373 definition  | 
297 "rec_le = CN rec_disj [rec_less, rec_eq]"  | 
374 "rec_le = CN rec_disj [rec_less, rec_eq]"  | 
298  | 
375  | 
299 text {* Sigma and Accum for function with one and two arguments *}  | 
376 lemma less_lemma [simp]:  | 
377 "rec_eval rec_less [x, y] = (if x < y then 1 else 0)"  | 
|
378 by (simp add: rec_less_def)  | 
|
379  | 
|
380 lemma le_lemma [simp]:  | 
|
381 "rec_eval rec_le [x, y] = (if (x \<le> y) then 1 else 0)"  | 
|
382 by(simp add: rec_le_def)  | 
|
383  | 
|
384  | 
|
385 section {* Summation and Product Functions *}  | 
|
300  | 
386  | 
301 definition  | 
387 definition  | 
302 "rec_sigma1 f = PR (CN f [Z, Id 1 0]) (CN rec_add [Id 3 1, CN f [S, Id 3 2]])"  | 
388 "rec_sigma1 f = PR (CN f [Z, Id 1 0]) (CN rec_add [Id 3 1, CN f [S, Id 3 2]])"  | 
303  | 
389  | 
304 definition  | 
390 definition  | 
313 definition  | 
399 definition  | 
314 "rec_accum3 f = PR (CN f [Z, Id 3 0, Id 3 1, Id 3 2])  | 
400 "rec_accum3 f = PR (CN f [Z, Id 3 0, Id 3 1, Id 3 2])  | 
315 (CN rec_mult [Id 5 1, CN f [S, Id 5 2, Id 5 3, Id 5 4]])"  | 
401 (CN rec_mult [Id 5 1, CN f [S, Id 5 2, Id 5 3, Id 5 4]])"  | 
316  | 
402  | 
317  | 
403  | 
318 text {* Bounded quantifiers for one and two arguments *}  | 
404 lemma sigma1_lemma [simp]:  | 
405 shows "rec_eval (rec_sigma1 f) [x, y] = (\<Sum> z \<le> x. (rec_eval f) [z, y])"  | 
|
406 by (induct x) (simp_all add: rec_sigma1_def)  | 
|
407  | 
|
408 lemma sigma2_lemma [simp]:  | 
|
409 shows "rec_eval (rec_sigma2 f) [x, y1, y2] = (\<Sum> z \<le> x. (rec_eval f) [z, y1, y2])"  | 
|
410 by (induct x) (simp_all add: rec_sigma2_def)  | 
|
411  | 
|
412 lemma accum1_lemma [simp]:  | 
|
413 shows "rec_eval (rec_accum1 f) [x, y] = (\<Prod> z \<le> x. (rec_eval f) [z, y])"  | 
|
414 by (induct x) (simp_all add: rec_accum1_def)  | 
|
415  | 
|
416 lemma accum2_lemma [simp]:  | 
|
417 shows "rec_eval (rec_accum2 f) [x, y1, y2] = (\<Prod> z \<le> x. (rec_eval f) [z, y1, y2])"  | 
|
418 by (induct x) (simp_all add: rec_accum2_def)  | 
|
419  | 
|
420 lemma accum3_lemma [simp]:  | 
|
421 shows "rec_eval (rec_accum3 f) [x, y1, y2, y3] = (\<Prod> z \<le> x. (rec_eval f) [z, y1, y2, y3])"  | 
|
422 by (induct x) (simp_all add: rec_accum3_def)  | 
|
423  | 
|
424  | 
|
425 section {* Bounded Quantifiers *}  | 
|
319  | 
426  | 
320 definition  | 
427 definition  | 
321 "rec_all1 f = CN rec_sign [rec_accum1 f]"  | 
428 "rec_all1 f = CN rec_sign [rec_accum1 f]"  | 
322  | 
429  | 
323 definition  | 
430 definition  | 
329 definition  | 
436 definition  | 
330 "rec_all1_less f = (let f' = CN rec_disj [CN rec_eq [Id 3 0, Id 3 1], CN f [Id 3 0, Id 3 2]]  | 
437 "rec_all1_less f = (let f' = CN rec_disj [CN rec_eq [Id 3 0, Id 3 1], CN f [Id 3 0, Id 3 2]]  | 
331 in CN (rec_all2 f') [Id 2 0, Id 2 0, Id 2 1])"  | 
438 in CN (rec_all2 f') [Id 2 0, Id 2 0, Id 2 1])"  | 
332  | 
439  | 
333 definition  | 
440 definition  | 
334 "rec_all2_less f = (let f' = CN rec_disj [CN rec_eq [Id 4 0, Id 4 1], CN f [Id 4 0, Id 4 2, Id 4 3]]  | 
441 "rec_all2_less f = (let cond1 = CN rec_eq [Id 4 0, Id 4 1] in  | 
335 in CN (rec_all3 f') [Id 3 0, Id 3 0, Id 3 1, Id 3 2])"  | 
442 let cond2 = CN f [Id 4 0, Id 4 2, Id 4 3] in  | 
443 CN (rec_all3 (CN rec_disj [cond1, cond2])) [Id 3 0, Id 3 0, Id 3 1, Id 3 2])"  | 
|
336  | 
444  | 
337 definition  | 
445 definition  | 
338 "rec_ex1 f = CN rec_sign [rec_sigma1 f]"  | 
446 "rec_ex1 f = CN rec_sign [rec_sigma1 f]"  | 
339  | 
447  | 
340 definition  | 
448 definition  | 
341 "rec_ex2 f = CN rec_sign [rec_sigma2 f]"  | 
449 "rec_ex2 f = CN rec_sign [rec_sigma2 f]"  | 
342  | 
450  | 
343 text {* Dvd, Quotient, Modulo *}  | 
451  | 
344  | 
452 lemma ex1_lemma [simp]:  | 
345 (* FIXME: probably all not needed *)  | 
453 "rec_eval (rec_ex1 f) [x, y] = (if (\<exists>z \<le> x. 0 < rec_eval f [z, y]) then 1 else 0)"  | 
346 definition  | 
454 by (simp add: rec_ex1_def)  | 
347 "rec_dvd =  | 
455  | 
348 rec_swap (CN (rec_ex2 (CN rec_eq [Id 3 2, CN rec_mult [Id 3 1, Id 3 0]])) [Id 2 0, Id 2 1, Id 2 0])"  | 
456 lemma ex2_lemma [simp]:  | 
457 "rec_eval (rec_ex2 f) [x, y1, y2] = (if (\<exists>z \<le> x. 0 < rec_eval f [z, y1, y2]) then 1 else 0)"  | 
|
458 by (simp add: rec_ex2_def)  | 
|
459  | 
|
460 lemma all1_lemma [simp]:  | 
|
461 "rec_eval (rec_all1 f) [x, y] = (if (\<forall>z \<le> x. 0 < rec_eval f [z, y]) then 1 else 0)"  | 
|
462 by (simp add: rec_all1_def)  | 
|
463  | 
|
464 lemma all2_lemma [simp]:  | 
|
465 "rec_eval (rec_all2 f) [x, y1, y2] = (if (\<forall>z \<le> x. 0 < rec_eval f [z, y1, y2]) then 1 else 0)"  | 
|
466 by (simp add: rec_all2_def)  | 
|
467  | 
|
468 lemma all3_lemma [simp]:  | 
|
469 "rec_eval (rec_all3 f) [x, y1, y2, y3] = (if (\<forall>z \<le> x. 0 < rec_eval f [z, y1, y2, y3]) then 1 else 0)"  | 
|
470 by (simp add: rec_all3_def)  | 
|
471  | 
|
472 lemma all1_less_lemma [simp]:  | 
|
473 "rec_eval (rec_all1_less f) [x, y] = (if (\<forall>z < x. 0 < rec_eval f [z, y]) then 1 else 0)"  | 
|
474 apply(auto simp add: Let_def rec_all1_less_def)  | 
|
475 apply (metis nat_less_le)+  | 
|
476 done  | 
|
477  | 
|
478 lemma all2_less_lemma [simp]:  | 
|
479 "rec_eval (rec_all2_less f) [x, y1, y2] = (if (\<forall>z < x. 0 < rec_eval f [z, y1, y2]) then 1 else 0)"  | 
|
480 apply(auto simp add: Let_def rec_all2_less_def)  | 
|
481 apply(metis nat_less_le)+  | 
|
482 done  | 
|
483  | 
|
484 section {* Quotients *}  | 
|
349  | 
485  | 
350 definition  | 
486 definition  | 
351 "rec_quo = (let lhs = CN S [Id 3 0] in  | 
487 "rec_quo = (let lhs = CN S [Id 3 0] in  | 
352 let rhs = CN rec_mult [Id 3 2, CN S [Id 3 1]] in  | 
488 let rhs = CN rec_mult [Id 3 2, CN S [Id 3 1]] in  | 
353 let cond = CN rec_eq [lhs, rhs] in  | 
489 let cond = CN rec_eq [lhs, rhs] in  | 
354 let if_stmt = CN rec_if [cond, CN S [Id 3 1], Id 3 1]  | 
490 let if_stmt = CN rec_if [cond, CN S [Id 3 1], Id 3 1]  | 
355 in PR Z if_stmt)"  | 
491 in PR Z if_stmt)"  | 
356  | 
492  | 
357 definition  | 
|
358 "rec_mod = CN rec_minus [Id 2 0, CN rec_mult [Id 2 1, rec_quo]]"  | 
|
359  | 
|
360 text {* Iteration *}  | 
|
361  | 
|
362 definition  | 
|
363 "rec_iter f = PR (Id 2 0) (CN f [Id 3 1])"  | 
|
364  | 
|
365 fun Iter where  | 
|
366 "Iter f 0 = id"  | 
|
367 | "Iter f (Suc n) = f \<circ> (Iter f n)"  | 
|
368  | 
|
369 lemma Iter_comm:  | 
|
370 "(Iter f n) (f x) = f ((Iter f n) x)"  | 
|
371 by (induct n) (simp_all)  | 
|
372  | 
|
373 lemma iter_lemma [simp]:  | 
|
374 "rec_eval (rec_iter f) [n, x] = Iter (\<lambda>x. rec_eval f [x]) n x"  | 
|
375 by (induct n) (simp_all add: rec_iter_def)  | 
|
376  | 
|
377 section {* Correctness of Recursive Functions *}  | 
|
378  | 
|
379 lemma constn_lemma [simp]:  | 
|
380 "rec_eval (constn n) xs = n"  | 
|
381 by (induct n) (simp_all)  | 
|
382  | 
|
383 lemma swap_lemma [simp]:  | 
|
384 "rec_eval (rec_swap f) [x, y] = rec_eval f [y, x]"  | 
|
385 by (simp add: rec_swap_def)  | 
|
386  | 
|
387 lemma add_lemma [simp]:  | 
|
388 "rec_eval rec_add [x, y] = x + y"  | 
|
389 by (induct x) (simp_all add: rec_add_def)  | 
|
390  | 
|
391 lemma mult_lemma [simp]:  | 
|
392 "rec_eval rec_mult [x, y] = x * y"  | 
|
393 by (induct x) (simp_all add: rec_mult_def)  | 
|
394  | 
|
395 lemma power_lemma [simp]:  | 
|
396 "rec_eval rec_power [x, y] = x ^ y"  | 
|
397 by (induct y) (simp_all add: rec_power_def)  | 
|
398  | 
|
399 lemma fact_lemma [simp]:  | 
|
400 "rec_eval rec_fact [x] = fact x"  | 
|
401 by (induct x) (simp_all add: rec_fact_def)  | 
|
402  | 
|
403 lemma pred_lemma [simp]:  | 
|
404 "rec_eval rec_pred [x] = x - 1"  | 
|
405 by (induct x) (simp_all add: rec_pred_def)  | 
|
406  | 
|
407 lemma minus_lemma [simp]:  | 
|
408 "rec_eval rec_minus [x, y] = x - y"  | 
|
409 by (induct y) (simp_all add: rec_minus_def)  | 
|
410  | 
|
411 lemma sign_lemma [simp]:  | 
|
412 "rec_eval rec_sign [x] = (if x = 0 then 0 else 1)"  | 
|
413 by (simp add: rec_sign_def)  | 
|
414  | 
|
415 lemma not_lemma [simp]:  | 
|
416 "rec_eval rec_not [x] = (if x = 0 then 1 else 0)"  | 
|
417 by (simp add: rec_not_def)  | 
|
418  | 
|
419 lemma eq_lemma [simp]:  | 
|
420 "rec_eval rec_eq [x, y] = (if x = y then 1 else 0)"  | 
|
421 by (simp add: rec_eq_def)  | 
|
422  | 
|
423 lemma noteq_lemma [simp]:  | 
|
424 "rec_eval rec_noteq [x, y] = (if x \<noteq> y then 1 else 0)"  | 
|
425 by (simp add: rec_noteq_def)  | 
|
426  | 
|
427 lemma conj_lemma [simp]:  | 
|
428 "rec_eval rec_conj [x, y] = (if x = 0 \<or> y = 0 then 0 else 1)"  | 
|
429 by (simp add: rec_conj_def)  | 
|
430  | 
|
431 lemma disj_lemma [simp]:  | 
|
432 "rec_eval rec_disj [x, y] = (if x = 0 \<and> y = 0 then 0 else 1)"  | 
|
433 by (simp add: rec_disj_def)  | 
|
434  | 
|
435 lemma imp_lemma [simp]:  | 
|
436 "rec_eval rec_imp [x, y] = (if 0 < x \<and> y = 0 then 0 else 1)"  | 
|
437 by (simp add: rec_imp_def)  | 
|
438  | 
|
439 lemma less_lemma [simp]:  | 
|
440 "rec_eval rec_less [x, y] = (if x < y then 1 else 0)"  | 
|
441 by (simp add: rec_less_def)  | 
|
442  | 
|
443 lemma le_lemma [simp]:  | 
|
444 "rec_eval rec_le [x, y] = (if (x \<le> y) then 1 else 0)"  | 
|
445 by(simp add: rec_le_def)  | 
|
446  | 
|
447 lemma ifz_lemma [simp]:  | 
|
448 "rec_eval rec_ifz [z, x, y] = (if z = 0 then x else y)"  | 
|
449 by (case_tac z) (simp_all add: rec_ifz_def)  | 
|
450  | 
|
451 lemma if_lemma [simp]:  | 
|
452 "rec_eval rec_if [z, x, y] = (if 0 < z then x else y)"  | 
|
453 by (simp add: rec_if_def)  | 
|
454  | 
|
455 lemma sigma1_lemma [simp]:  | 
|
456 shows "rec_eval (rec_sigma1 f) [x, y] = (\<Sum> z \<le> x. (rec_eval f) [z, y])"  | 
|
457 by (induct x) (simp_all add: rec_sigma1_def)  | 
|
458  | 
|
459 lemma sigma2_lemma [simp]:  | 
|
460 shows "rec_eval (rec_sigma2 f) [x, y1, y2] = (\<Sum> z \<le> x. (rec_eval f) [z, y1, y2])"  | 
|
461 by (induct x) (simp_all add: rec_sigma2_def)  | 
|
462  | 
|
463 lemma accum1_lemma [simp]:  | 
|
464 shows "rec_eval (rec_accum1 f) [x, y] = (\<Prod> z \<le> x. (rec_eval f) [z, y])"  | 
|
465 by (induct x) (simp_all add: rec_accum1_def)  | 
|
466  | 
|
467 lemma accum2_lemma [simp]:  | 
|
468 shows "rec_eval (rec_accum2 f) [x, y1, y2] = (\<Prod> z \<le> x. (rec_eval f) [z, y1, y2])"  | 
|
469 by (induct x) (simp_all add: rec_accum2_def)  | 
|
470  | 
|
471 lemma accum3_lemma [simp]:  | 
|
472 shows "rec_eval (rec_accum3 f) [x, y1, y2, y3] = (\<Prod> z \<le> x. (rec_eval f) [z, y1, y2, y3])"  | 
|
473 by (induct x) (simp_all add: rec_accum3_def)  | 
|
474  | 
|
475 lemma ex1_lemma [simp]:  | 
|
476 "rec_eval (rec_ex1 f) [x, y] = (if (\<exists>z \<le> x. 0 < rec_eval f [z, y]) then 1 else 0)"  | 
|
477 by (simp add: rec_ex1_def)  | 
|
478  | 
|
479 lemma ex2_lemma [simp]:  | 
|
480 "rec_eval (rec_ex2 f) [x, y1, y2] = (if (\<exists>z \<le> x. 0 < rec_eval f [z, y1, y2]) then 1 else 0)"  | 
|
481 by (simp add: rec_ex2_def)  | 
|
482  | 
|
483 lemma all1_lemma [simp]:  | 
|
484 "rec_eval (rec_all1 f) [x, y] = (if (\<forall>z \<le> x. 0 < rec_eval f [z, y]) then 1 else 0)"  | 
|
485 by (simp add: rec_all1_def)  | 
|
486  | 
|
487 lemma all2_lemma [simp]:  | 
|
488 "rec_eval (rec_all2 f) [x, y1, y2] = (if (\<forall>z \<le> x. 0 < rec_eval f [z, y1, y2]) then 1 else 0)"  | 
|
489 by (simp add: rec_all2_def)  | 
|
490  | 
|
491 lemma all3_lemma [simp]:  | 
|
492 "rec_eval (rec_all3 f) [x, y1, y2, y3] = (if (\<forall>z \<le> x. 0 < rec_eval f [z, y1, y2, y3]) then 1 else 0)"  | 
|
493 by (simp add: rec_all3_def)  | 
|
494  | 
|
495 lemma all1_less_lemma [simp]:  | 
|
496 "rec_eval (rec_all1_less f) [x, y] = (if (\<forall>z < x. 0 < rec_eval f [z, y]) then 1 else 0)"  | 
|
497 apply(auto simp add: Let_def rec_all1_less_def)  | 
|
498 apply (metis nat_less_le)+  | 
|
499 done  | 
|
500  | 
|
501 lemma all2_less_lemma [simp]:  | 
|
502 "rec_eval (rec_all2_less f) [x, y1, y2] = (if (\<forall>z < x. 0 < rec_eval f [z, y1, y2]) then 1 else 0)"  | 
|
503 apply(auto simp add: Let_def rec_all2_less_def)  | 
|
504 apply(metis nat_less_le)+  | 
|
505 done  | 
|
506  | 
|
507  | 
|
508 lemma dvd_alt_def:  | 
|
509 fixes x y k:: nat  | 
|
510 shows "(x dvd y) = (\<exists> k \<le> y. y = x * k)"  | 
|
511 apply(auto simp add: dvd_def)  | 
|
512 apply(case_tac x)  | 
|
513 apply(auto)  | 
|
514 done  | 
|
515  | 
|
516 lemma dvd_lemma [simp]:  | 
|
517 "rec_eval rec_dvd [x, y] = (if x dvd y then 1 else 0)"  | 
|
518 unfolding dvd_alt_def  | 
|
519 by (auto simp add: rec_dvd_def)  | 
|
520  | 
|
521 fun Quo where  | 
493 fun Quo where  | 
522 "Quo x 0 = 0"  | 
494 "Quo x 0 = 0"  | 
523 | "Quo x (Suc y) = (if (Suc y = x * (Suc (Quo x y))) then Suc (Quo x y) else Quo x y)"  | 
495 | "Quo x (Suc y) = (if (Suc y = x * (Suc (Quo x y))) then Suc (Quo x y) else Quo x y)"  | 
524  | 
496  | 
525 lemma Quo0:  | 
497 lemma Quo0:  | 
526 shows "Quo 0 y = 0"  | 
498 shows "Quo 0 y = 0"  | 
527 apply(induct y)  | 
499 by (induct y) (auto)  | 
528 apply(auto)  | 
|
529 done  | 
|
530  | 
500  | 
531 lemma Quo1:  | 
501 lemma Quo1:  | 
532 "x * (Quo x y) \<le> y"  | 
502 "x * (Quo x y) \<le> y"  | 
533 by (induct y) (simp_all)  | 
503 by (induct y) (simp_all)  | 
534  | 
504  | 
564  | 
534  | 
565 lemma quo_lemma [simp]:  | 
535 lemma quo_lemma [simp]:  | 
566 shows "rec_eval rec_quo [y, x] = y div x"  | 
536 shows "rec_eval rec_quo [y, x] = y div x"  | 
567 by (simp add: Quo_div Quo_rec_quo)  | 
537 by (simp add: Quo_div Quo_rec_quo)  | 
568  | 
538  | 
569 lemma rem_lemma [simp]:  | 
539  | 
570 shows "rec_eval rec_mod [y, x] = y mod x"  | 
540 section {* Iteration *}  | 
571 by (simp add: rec_mod_def mod_div_equality' nat_mult_commute)  | 
541  | 
542 definition  | 
|
543 "rec_iter f = PR (Id 2 0) (CN f [Id 3 1])"  | 
|
544  | 
|
545 fun Iter where  | 
|
546 "Iter f 0 = id"  | 
|
547 | "Iter f (Suc n) = f \<circ> (Iter f n)"  | 
|
548  | 
|
549 lemma Iter_comm:  | 
|
550 "(Iter f n) (f x) = f ((Iter f n) x)"  | 
|
551 by (induct n) (simp_all)  | 
|
552  | 
|
553 lemma iter_lemma [simp]:  | 
|
554 "rec_eval (rec_iter f) [n, x] = Iter (\<lambda>x. rec_eval f [x]) n x"  | 
|
555 by (induct n) (simp_all add: rec_iter_def)  | 
|
572  | 
556  | 
573  | 
557  | 
574 section {* Bounded Maximisation *}  | 
558 section {* Bounded Maximisation *}  | 
575  | 
559  | 
576 fun BMax_rec where  | 
560 fun BMax_rec where  | 
577 "BMax_rec R 0 = 0"  | 
561 "BMax_rec R 0 = 0"  | 
578 | "BMax_rec R (Suc n) = (if R (Suc n) then (Suc n) else BMax_rec R n)"  | 
562 | "BMax_rec R (Suc n) = (if R (Suc n) then (Suc n) else BMax_rec R n)"  | 
579  | 
563  | 
580 definition BMax_set :: "(nat \<Rightarrow> bool) \<Rightarrow> nat \<Rightarrow> nat"  | 
564 definition  | 
581 where "BMax_set R x = Max ({z. z \<le> x \<and> R z} \<union> {0})"  | 
565 BMax_set :: "(nat \<Rightarrow> bool) \<Rightarrow> nat \<Rightarrow> nat"  | 
566 where  | 
|
567 "BMax_set R x = Max ({z. z \<le> x \<and> R z} \<union> {0})"  | 
|
582  | 
568  | 
583 lemma BMax_rec_eq1:  | 
569 lemma BMax_rec_eq1:  | 
584 "BMax_rec R x = (GREATEST z. (R z \<and> z \<le> x) \<or> z = 0)"  | 
570 "BMax_rec R x = (GREATEST z. (R z \<and> z \<le> x) \<or> z = 0)"  | 
585 apply(induct x)  | 
571 apply(induct x)  | 
586 apply(auto intro: Greatest_equality Greatest_equality[symmetric])  | 
572 apply(auto intro: Greatest_equality Greatest_equality[symmetric])  | 
609 "rec_max2 f = PR (constn 0) (CN rec_ifz [CN f [CN S [Id 4 0], Id 4 2, Id 4 3], CN S [Id 4 0], Id 4 1])"  | 
595 "rec_max2 f = PR (constn 0) (CN rec_ifz [CN f [CN S [Id 4 0], Id 4 2, Id 4 3], CN S [Id 4 0], Id 4 1])"  | 
610  | 
596  | 
611 lemma max2_lemma [simp]:  | 
597 lemma max2_lemma [simp]:  | 
612 "rec_eval (rec_max2 f) [x, y1, y2] = BMax_rec (\<lambda>u. rec_eval f [u, y1, y2] = 0) x"  | 
598 "rec_eval (rec_max2 f) [x, y1, y2] = BMax_rec (\<lambda>u. rec_eval f [u, y1, y2] = 0) x"  | 
613 by (induct x) (simp_all add: rec_max2_def)  | 
599 by (induct x) (simp_all add: rec_max2_def)  | 
600  | 
|
614  | 
601  | 
615 section {* Encodings using Cantor's pairing function *}  | 
602 section {* Encodings using Cantor's pairing function *}  | 
616  | 
603  | 
617 text {*  | 
604 text {*  | 
618 We use Cantor's pairing function from Nat_Bijection.  | 
605 We use Cantor's pairing function from Nat_Bijection.  | 
695 apply(simp only: w_aux)  | 
682 apply(simp only: w_aux)  | 
696 apply(rule y_aux)  | 
683 apply(rule y_aux)  | 
697 apply(simp)  | 
684 apply(simp)  | 
698 done  | 
685 done  | 
699  | 
686  | 
687  | 
|
700 definition  | 
688 definition  | 
701 "rec_triangle = CN rec_quo [CN rec_mult [Id 1 0, S], constn 2]"  | 
689 "rec_triangle = CN rec_quo [CN rec_mult [Id 1 0, S], constn 2]"  | 
690  | 
|
691 definition  | 
|
692 "rec_max_triangle =  | 
|
693 (let cond = CN rec_not [CN rec_le [CN rec_triangle [Id 2 0], Id 2 1]] in  | 
|
694 CN (rec_max1 cond) [Id 1 0, Id 1 0])"  | 
|
695  | 
|
702  | 
696  | 
703 lemma triangle_lemma [simp]:  | 
697 lemma triangle_lemma [simp]:  | 
704 "rec_eval rec_triangle [x] = triangle x"  | 
698 "rec_eval rec_triangle [x] = triangle x"  | 
705 by (simp add: rec_triangle_def triangle_def)  | 
699 by (simp add: rec_triangle_def triangle_def)  | 
706  | 
700  | 
707 definition  | 
|
708 "rec_max_triangle =  | 
|
709 (let cond = CN rec_not [CN rec_le [CN rec_triangle [Id 2 0], Id 2 1]] in  | 
|
710 CN (rec_max1 cond) [Id 1 0, Id 1 0])"  | 
|
711  | 
|
712 lemma max_triangle_lemma [simp]:  | 
701 lemma max_triangle_lemma [simp]:  | 
713 "rec_eval rec_max_triangle [x] = Max_triangle x"  | 
702 "rec_eval rec_max_triangle [x] = Max_triangle x"  | 
714 by (simp add: Max_triangle_greatest rec_max_triangle_def Let_def BMax_rec_eq1)  | 
703 by (simp add: Max_triangle_greatest rec_max_triangle_def Let_def BMax_rec_eq1)  | 
715  | 
704  | 
705  | 
|
706 text {* Encodings for Products *}  | 
|
707  | 
|
716 definition  | 
708 definition  | 
717 "rec_penc = CN rec_add [CN rec_triangle [CN rec_add [Id 2 0, Id 2 1]], Id 2 0]"  | 
709 "rec_penc = CN rec_add [CN rec_triangle [CN rec_add [Id 2 0, Id 2 1]], Id 2 0]"  | 
718  | 
710  | 
719 definition  | 
711 definition  | 
720 "rec_pdec1 = CN rec_minus [Id 1 0, CN rec_triangle [CN rec_max_triangle [Id 1 0]]]"  | 
712 "rec_pdec1 = CN rec_minus [Id 1 0, CN rec_triangle [CN rec_max_triangle [Id 1 0]]]"  | 
732  | 
724  | 
733 lemma penc_lemma [simp]:  | 
725 lemma penc_lemma [simp]:  | 
734 "rec_eval rec_penc [m, n] = penc m n"  | 
726 "rec_eval rec_penc [m, n] = penc m n"  | 
735 by (simp add: rec_penc_def prod_encode_def)  | 
727 by (simp add: rec_penc_def prod_encode_def)  | 
736  | 
728  | 
737 text {* encoding and decoding of lists of natural numbers *}  | 
729  | 
730 text {* Encodings of Lists *}  | 
|
738  | 
731  | 
739 fun  | 
732 fun  | 
740 lenc :: "nat list \<Rightarrow> nat"  | 
733 lenc :: "nat list \<Rightarrow> nat"  | 
741 where  | 
734 where  | 
742 "lenc [] = 0"  | 
735 "lenc [] = 0"  | 
760 lemma list_encode_inverse:  | 
753 lemma list_encode_inverse:  | 
761 "ldec (lenc xs) n = (if n < length xs then xs ! n else 0)"  | 
754 "ldec (lenc xs) n = (if n < length xs then xs ! n else 0)"  | 
762 by (induct xs arbitrary: n rule: lenc.induct)  | 
755 by (induct xs arbitrary: n rule: lenc.induct)  | 
763 (auto simp add: ldec_zero nth_Cons split: nat.splits)  | 
756 (auto simp add: ldec_zero nth_Cons split: nat.splits)  | 
764  | 
757  | 
765  | 
|
766 lemma lenc_length_le:  | 
758 lemma lenc_length_le:  | 
767 "length xs \<le> lenc xs"  | 
759 "length xs \<le> lenc xs"  | 
768 by (induct xs) (simp_all add: prod_encode_def)  | 
760 by (induct xs) (simp_all add: prod_encode_def)  | 
761  | 
|
762  | 
|
763 text {* Membership for the List Encoding *}  | 
|
769  | 
764  | 
770 fun within :: "nat \<Rightarrow> nat \<Rightarrow> bool" where  | 
765 fun within :: "nat \<Rightarrow> nat \<Rightarrow> bool" where  | 
771 "within z 0 = (0 < z)"  | 
766 "within z 0 = (0 < z)"  | 
772 | "within z (Suc n) = within (pdec2 z) n"  | 
767 | "within z (Suc n) = within (pdec2 z) n"  | 
773  | 
768  | 
785 apply(simp_all add: prod_encode_def)  | 
780 apply(simp_all add: prod_encode_def)  | 
786 apply(case_tac xs)  | 
781 apply(case_tac xs)  | 
787 apply(simp_all)  | 
782 apply(simp_all)  | 
788 done  | 
783 done  | 
789  | 
784  | 
785 text {* Length of Encoded Lists *}  | 
|
786  | 
|
790 lemma enclen_length [simp]:  | 
787 lemma enclen_length [simp]:  | 
791 "enclen (lenc xs) = length xs"  | 
788 "enclen (lenc xs) = length xs"  | 
792 unfolding enclen_def  | 
789 unfolding enclen_def  | 
793 apply(simp add: BMax_rec_eq1)  | 
790 apply(simp add: BMax_rec_eq1)  | 
794 apply(rule Greatest_equality)  | 
791 apply(rule Greatest_equality)  | 
801  | 
798  | 
802 lemma enclen_zero [simp]:  | 
799 lemma enclen_zero [simp]:  | 
803 "enclen 0 = 0"  | 
800 "enclen 0 = 0"  | 
804 by (simp add: enclen_def)  | 
801 by (simp add: enclen_def)  | 
805  | 
802  | 
803  | 
|
804 text {* Recursive De3finitions for List Encodings *}  | 
|
805  | 
|
806 fun  | 
806 fun  | 
807 rec_lenc :: "recf list \<Rightarrow> recf"  | 
807 rec_lenc :: "recf list \<Rightarrow> recf"  | 
808 where  | 
808 where  | 
809 "rec_lenc [] = Z"  | 
809 "rec_lenc [] = Z"  | 
810 | "rec_lenc (f # fs) = CN rec_penc [CN S [f], rec_lenc fs]"  | 
810 | "rec_lenc (f # fs) = CN rec_penc [CN S [f], rec_lenc fs]"  | 
817  | 
817  | 
818 definition  | 
818 definition  | 
819 "rec_enclen = CN (rec_max1 (CN rec_not [CN rec_within [Id 2 1, CN rec_pred [Id 2 0]]])) [Id 1 0, Id 1 0]"  | 
819 "rec_enclen = CN (rec_max1 (CN rec_not [CN rec_within [Id 2 1, CN rec_pred [Id 2 0]]])) [Id 1 0, Id 1 0]"  | 
820  | 
820  | 
821 lemma ldec_iter:  | 
821 lemma ldec_iter:  | 
822 "ldec z n = pdec1 ((Iter pdec2 n) z) - 1"  | 
822 "ldec z n = pdec1 (Iter pdec2 n z) - 1"  | 
823 by (induct n arbitrary: z) (simp | subst Iter_comm)+  | 
823 by (induct n arbitrary: z) (simp | subst Iter_comm)+  | 
824  | 
824  | 
825 lemma within_iter:  | 
825 lemma within_iter:  | 
826 "within z n = (0 < (Iter pdec2 n) z)"  | 
826 "within z n = (0 < Iter pdec2 n z)"  | 
827 by (induct n arbitrary: z) (simp | subst Iter_comm)+  | 
827 by (induct n arbitrary: z) (simp | subst Iter_comm)+  | 
828  | 
828  | 
829 lemma lenc_lemma [simp]:  | 
829 lemma lenc_lemma [simp]:  | 
830 "rec_eval (rec_lenc fs) xs = lenc (map (\<lambda>f. rec_eval f xs) fs)"  | 
830 "rec_eval (rec_lenc fs) xs = lenc (map (\<lambda>f. rec_eval f xs) fs)"  | 
831 by (induct fs) (simp_all)  | 
831 by (induct fs) (simp_all)  |