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) |