changeset 20 | e04123f4bacc |
parent 15 | e3ecf558aef2 |
19:087d82632852 | 20:e04123f4bacc |
---|---|
220 |
220 |
221 |
221 |
222 section {* Arithmetic Functions *} |
222 section {* Arithmetic Functions *} |
223 |
223 |
224 text {* |
224 text {* |
225 @{text "constn n"} is the recursive function which computes |
225 @{text "constn n"} is the recursive function which generates |
226 natural number @{text "n"}. |
226 the natural number @{text "n"}. *} |
227 *} |
227 |
228 fun constn :: "nat \<Rightarrow> recf" |
228 fun constn :: "nat \<Rightarrow> recf" |
229 where |
229 where |
230 "constn 0 = Z" | |
230 "constn 0 = Z" | |
231 "constn (Suc n) = CN S [constn n]" |
231 "constn (Suc n) = CN S [constn n]" |
232 |
232 |
252 "rec_pred = CN (PR Z (Id 3 0)) [Id 1 0, Id 1 0]" |
252 "rec_pred = CN (PR Z (Id 3 0)) [Id 1 0, Id 1 0]" |
253 |
253 |
254 definition |
254 definition |
255 "rec_minus = rec_swap (PR (Id 1 0) (CN rec_pred [Id 3 1]))" |
255 "rec_minus = rec_swap (PR (Id 1 0) (CN rec_pred [Id 3 1]))" |
256 |
256 |
257 |
|
257 lemma constn_lemma [simp]: |
258 lemma constn_lemma [simp]: |
258 "rec_eval (constn n) xs = n" |
259 "rec_eval (constn n) xs = n" |
259 by (induct n) (simp_all) |
260 by (induct n) (simp_all) |
260 |
261 |
261 lemma swap_lemma [simp]: |
262 lemma swap_lemma [simp]: |
281 lemma fact_lemma [simp]: |
282 lemma fact_lemma [simp]: |
282 "rec_eval rec_fact [x] = fact x" |
283 "rec_eval rec_fact [x] = fact x" |
283 by (simp add: rec_fact_def) |
284 by (simp add: rec_fact_def) |
284 |
285 |
285 lemma pred_lemma [simp]: |
286 lemma pred_lemma [simp]: |
286 "rec_eval rec_pred [x] = x - 1" |
287 "rec_eval rec_pred [x] = x - 1" |
287 by (induct x) (simp_all add: rec_pred_def) |
288 by (induct x) (simp_all add: rec_pred_def) |
288 |
289 |
289 lemma minus_lemma [simp]: |
290 lemma minus_lemma [simp]: |
290 "rec_eval rec_minus [x, y] = x - y" |
291 "rec_eval rec_minus [x, y] = x - y" |
291 by (induct y) (simp_all add: rec_minus_def) |
292 by (induct y) (simp_all add: rec_minus_def) |
292 |
293 |
293 |
294 |
294 section {* Logical functions *} |
295 section {* Logical Functions *} |
295 |
296 |
296 text {* |
297 text {* |
297 The @{text "sign"} function returns 1 when the input argument |
298 The @{text "sign"} function returns 1 when the input argument |
298 is greater than @{text "0"}. *} |
299 is greater than @{text "0"}. *} |
299 |
300 |
319 "rec_disj = CN rec_sign [rec_add]" |
320 "rec_disj = CN rec_sign [rec_add]" |
320 |
321 |
321 definition |
322 definition |
322 "rec_imp = CN rec_disj [CN rec_not [Id 2 0], Id 2 1]" |
323 "rec_imp = CN rec_disj [CN rec_not [Id 2 0], Id 2 1]" |
323 |
324 |
324 text {* @{term "rec_ifz [z, x, y]"} returns x if z is zero, |
325 text {* @{term "rec_ifz [z, x, y]"} returns @{text x} if @{text z} is zero, and |
325 y otherwise; @{term "rec_if [z, x, y]"} returns x if z is *not* |
326 @{text y} otherwise; @{term "rec_if [z, x, y]"} returns @{text x} if @{text z} |
326 zero, y otherwise *} |
327 is *not* zero, and @{text y} otherwise. *} |
327 |
328 |
328 definition |
329 definition |
329 "rec_ifz = PR (Id 2 0) (Id 4 3)" |
330 "rec_ifz = PR (Id 2 0) (Id 4 3)" |
330 |
331 |
331 definition |
332 definition |
366 |
367 |
367 lemma if_lemma [simp]: |
368 lemma if_lemma [simp]: |
368 "rec_eval rec_if [z, x, y] = (if 0 < z then x else y)" |
369 "rec_eval rec_if [z, x, y] = (if 0 < z then x else y)" |
369 by (simp add: rec_if_def) |
370 by (simp add: rec_if_def) |
370 |
371 |
371 section {* Less and Le Relations *} |
372 |
373 section {* The Less and Less-Equal Relations *} |
|
372 |
374 |
373 text {* |
375 text {* |
374 @{text "rec_less"} compares two arguments and returns @{text "1"} if |
376 @{text "rec_less"} compares two arguments and returns @{text "1"} if |
375 the first is less than the second; otherwise returns @{text "0"}. *} |
377 the first is less than the second; otherwise it returns @{text "0"}. *} |
376 |
378 |
377 definition |
379 definition |
378 "rec_less = CN rec_sign [rec_swap rec_minus]" |
380 "rec_less = CN rec_sign [rec_swap rec_minus]" |
379 |
381 |
380 definition |
382 definition |
383 lemma less_lemma [simp]: |
385 lemma less_lemma [simp]: |
384 "rec_eval rec_less [x, y] = (if x < y then 1 else 0)" |
386 "rec_eval rec_less [x, y] = (if x < y then 1 else 0)" |
385 by (simp add: rec_less_def) |
387 by (simp add: rec_less_def) |
386 |
388 |
387 lemma le_lemma [simp]: |
389 lemma le_lemma [simp]: |
388 "rec_eval rec_le [x, y] = (if (x \<le> y) then 1 else 0)" |
390 "rec_eval rec_le [x, y] = (if x \<le> y then 1 else 0)" |
389 by(simp add: rec_le_def) |
391 by (simp add: rec_le_def) |
390 |
392 |
391 |
393 |
392 section {* Summation and Product Functions *} |
394 section {* Summation and Product Functions *} |
393 |
395 |
394 definition |
396 definition |
433 by (induct x) (simp_all add: rec_accum3_def) |
435 by (induct x) (simp_all add: rec_accum3_def) |
434 |
436 |
435 |
437 |
436 section {* Bounded Quantifiers *} |
438 section {* Bounded Quantifiers *} |
437 |
439 |
440 text {* Instead of defining quantifiers taking an aritrary |
|
441 list of arguments, we define the simpler quantifiers taking |
|
442 one, two and three extra arguments besides the argument |
|
443 that is quantified over. *} |
|
444 |
|
438 definition |
445 definition |
439 "rec_all1 f = CN rec_sign [rec_accum1 f]" |
446 "rec_all1 f = CN rec_sign [rec_accum1 f]" |
440 |
447 |
441 definition |
448 definition |
442 "rec_all2 f = CN rec_sign [rec_accum2 f]" |
449 "rec_all2 f = CN rec_sign [rec_accum2 f]" |
482 by (simp add: rec_all3_def) |
489 by (simp add: rec_all3_def) |
483 |
490 |
484 lemma all1_less_lemma [simp]: |
491 lemma all1_less_lemma [simp]: |
485 "rec_eval (rec_all1_less f) [x, y] = (if (\<forall>z < x. 0 < rec_eval f [z, y]) then 1 else 0)" |
492 "rec_eval (rec_all1_less f) [x, y] = (if (\<forall>z < x. 0 < rec_eval f [z, y]) then 1 else 0)" |
486 apply(auto simp add: Let_def rec_all1_less_def) |
493 apply(auto simp add: Let_def rec_all1_less_def) |
487 apply (metis nat_less_le)+ |
494 apply(metis nat_less_le)+ |
488 done |
495 done |
489 |
496 |
490 lemma all2_less_lemma [simp]: |
497 lemma all2_less_lemma [simp]: |
491 "rec_eval (rec_all2_less f) [x, y1, y2] = (if (\<forall>z < x. 0 < rec_eval f [z, y1, y2]) then 1 else 0)" |
498 "rec_eval (rec_all2_less f) [x, y1, y2] = (if (\<forall>z < x. 0 < rec_eval f [z, y1, y2]) then 1 else 0)" |
492 apply(auto simp add: Let_def rec_all2_less_def) |
499 apply(auto simp add: Let_def rec_all2_less_def) |
493 apply(metis nat_less_le)+ |
500 apply(metis nat_less_le)+ |
494 done |
501 done |
495 |
502 |
496 section {* Quotients *} |
503 |
497 |
504 section {* Natural Number Division *} |
498 definition |
505 |
499 "rec_quo = (let lhs = CN S [Id 3 0] in |
506 definition |
507 "rec_div = (let lhs = CN S [Id 3 0] in |
|
500 let rhs = CN rec_mult [Id 3 2, CN S [Id 3 1]] in |
508 let rhs = CN rec_mult [Id 3 2, CN S [Id 3 1]] in |
501 let cond = CN rec_eq [lhs, rhs] in |
509 let cond = CN rec_eq [lhs, rhs] in |
502 let if_stmt = CN rec_if [cond, CN S [Id 3 1], Id 3 1] |
510 let if_stmt = CN rec_if [cond, CN S [Id 3 1], Id 3 1] |
503 in PR Z if_stmt)" |
511 in PR Z if_stmt)" |
504 |
512 |
505 fun Quo where |
513 fun Div where |
506 "Quo x 0 = 0" |
514 "Div x 0 = 0" |
507 | "Quo x (Suc y) = (if (Suc y = x * (Suc (Quo x y))) then Suc (Quo x y) else Quo x y)" |
515 | "Div x (Suc y) = (if (Suc y = x * (Suc (Div x y))) then Suc (Div x y) else Div x y)" |
508 |
516 |
509 lemma Quo0: |
517 lemma Div0: |
510 shows "Quo 0 y = 0" |
518 shows "Div 0 y = 0" |
511 by (induct y) (auto) |
519 by (induct y) (auto) |
512 |
520 |
513 lemma Quo1: |
521 lemma Div1: |
514 "x * (Quo x y) \<le> y" |
522 "x * (Div x y) \<le> y" |
515 by (induct y) (simp_all) |
523 by (induct y) (simp_all) |
516 |
524 |
517 lemma Quo2: |
525 lemma Div2: |
518 "b * (Quo b a) + a mod b = a" |
526 "x * (Div x y) + y mod x = y" |
519 by (induct a) (auto simp add: mod_Suc) |
527 by (induct y) (auto simp add: mod_Suc) |
520 |
528 |
521 lemma Quo3: |
529 lemma Div3: |
522 "n * (Quo n m) = m - m mod n" |
530 "x * (Div x y) = y - y mod x" |
523 using Quo2[of n m] by (auto) |
531 using Div2[of x y] by (auto) |
524 |
532 |
525 lemma Quo4: |
533 lemma Div4: |
526 assumes h: "0 < x" |
534 assumes h: "0 < x" |
527 shows "y < x + x * Quo x y" |
535 shows "y < x + x * Div x y" |
528 proof - |
536 proof - |
529 have "x - (y mod x) > 0" using mod_less_divisor assms by auto |
537 have "x - (y mod x) > 0" using mod_less_divisor assms by auto |
530 then have "y < y + (x - (y mod x))" by simp |
538 then have "y < y + (x - (y mod x))" by simp |
531 then have "y < x + (y - (y mod x))" by simp |
539 then have "y < x + (y - (y mod x))" by simp |
532 then show "y < x + x * (Quo x y)" by (simp add: Quo3) |
540 then show "y < x + x * (Div x y)" by (simp add: Div3) |
533 qed |
541 qed |
534 |
542 |
535 lemma Quo_div: |
543 lemma Div_div: |
536 shows "Quo x y = y div x" |
544 shows "Div x y = y div x" |
537 apply(case_tac "x = 0") |
545 apply(case_tac "x = 0") |
538 apply(simp add: Quo0) |
546 apply(simp add: Div0) |
539 apply(subst split_div_lemma[symmetric]) |
547 apply(subst split_div_lemma[symmetric]) |
540 apply(auto intro: Quo1 Quo4) |
548 apply(auto intro: Div1 Div4) |
541 done |
549 done |
542 |
550 |
543 lemma Quo_rec_quo: |
551 lemma Div_rec_div: |
544 shows "rec_eval rec_quo [y, x] = Quo x y" |
552 shows "rec_eval rec_div [y, x] = Div x y" |
545 by (induct y) (simp_all add: rec_quo_def) |
553 by (induct y) (simp_all add: rec_div_def) |
546 |
554 |
547 lemma quo_lemma [simp]: |
555 lemma div_lemma [simp]: |
548 shows "rec_eval rec_quo [y, x] = y div x" |
556 shows "rec_eval rec_div [y, x] = y div x" |
549 by (simp add: Quo_div Quo_rec_quo) |
557 by (simp add: Div_div Div_rec_div) |
550 |
558 |
551 |
559 |
552 section {* Iteration *} |
560 section {* Iteration *} |
553 |
561 |
554 definition |
562 definition |
567 by (induct n) (simp_all add: rec_iter_def) |
575 by (induct n) (simp_all add: rec_iter_def) |
568 |
576 |
569 |
577 |
570 section {* Bounded Maximisation *} |
578 section {* Bounded Maximisation *} |
571 |
579 |
580 text {* Computes the greatest number below a bound @{text n} |
|
581 such that a predicate holds. If such a maximum does not exist, |
|
582 then @{text 0} is returned. *} |
|
572 |
583 |
573 fun BMax_rec where |
584 fun BMax_rec where |
574 "BMax_rec R 0 = 0" |
585 "BMax_rec R 0 = 0" |
575 | "BMax_rec R (Suc n) = (if R (Suc n) then (Suc n) else BMax_rec R n)" |
586 | "BMax_rec R (Suc n) = (if R (Suc n) then (Suc n) else BMax_rec R n)" |
576 |
587 |
592 apply(auto intro: Max_eqI Max_eqI[symmetric]) |
603 apply(auto intro: Max_eqI Max_eqI[symmetric]) |
593 apply(simp add: le_Suc_eq) |
604 apply(simp add: le_Suc_eq) |
594 by metis |
605 by metis |
595 |
606 |
596 lemma BMax_rec_eq3: |
607 lemma BMax_rec_eq3: |
597 "BMax_rec R x = Max (Set.filter (\<lambda>z. R z) {..x} \<union> {0})" |
608 "BMax_rec R x = Max (Set.filter R {..x} \<union> {0})" |
598 by (simp add: BMax_rec_eq2 Set.filter_def) |
609 by (simp add: BMax_rec_eq2 Set.filter_def) |
599 |
610 |
600 definition |
611 definition |
601 "rec_max1 f = PR Z (CN rec_ifz [CN f [CN S [Id 3 0], Id 3 2], CN S [Id 3 0], Id 3 1])" |
612 "rec_max1 f = PR Z (CN rec_ifz [CN f [CN S [Id 3 0], Id 3 2], CN S [Id 3 0], Id 3 1])" |
602 |
613 |
610 lemma max2_lemma [simp]: |
621 lemma max2_lemma [simp]: |
611 "rec_eval (rec_max2 f) [x, y1, y2] = BMax_rec (\<lambda>u. rec_eval f [u, y1, y2] = 0) x" |
622 "rec_eval (rec_max2 f) [x, y1, y2] = BMax_rec (\<lambda>u. rec_eval f [u, y1, y2] = 0) x" |
612 by (induct x) (simp_all add: rec_max2_def) |
623 by (induct x) (simp_all add: rec_max2_def) |
613 |
624 |
614 |
625 |
615 section {* Encodings using Cantor's pairing function *} |
626 section {* Encodings using Cantor's Pairing Function *} |
616 |
627 |
617 text {* |
628 text {* We use Cantor's pairing function from the theory |
618 We use Cantor's pairing function from Nat_Bijection. |
629 Nat_Bijection. However, we need to prove that the formulation |
619 However, we need to prove that the formulation of the |
630 of the decoding function there is recursive. For this we first |
620 decoding function there is recursive. For this we first |
|
621 prove that we can extract the maximal triangle number |
631 prove that we can extract the maximal triangle number |
622 using @{term prod_decode}. |
632 using @{term prod_decode}. |
623 *} |
633 *} |
624 |
634 |
625 abbreviation Max_triangle_aux where |
635 abbreviation Max_triangle_aux where |
697 apply(simp) |
707 apply(simp) |
698 done |
708 done |
699 |
709 |
700 |
710 |
701 definition |
711 definition |
702 "rec_triangle = CN rec_quo [CN rec_mult [Id 1 0, S], constn 2]" |
712 "rec_triangle = CN rec_div [CN rec_mult [Id 1 0, S], constn 2]" |
703 |
713 |
704 definition |
714 definition |
705 "rec_max_triangle = |
715 "rec_max_triangle = |
706 (let cond = CN rec_not [CN rec_le [CN rec_triangle [Id 2 0], Id 2 1]] in |
716 (let cond = CN rec_not [CN rec_le [CN rec_triangle [Id 2 0], Id 2 1]] in |
707 CN (rec_max1 cond) [Id 1 0, Id 1 0])" |
717 CN (rec_max1 cond) [Id 1 0, Id 1 0])" |
714 lemma max_triangle_lemma [simp]: |
724 lemma max_triangle_lemma [simp]: |
715 "rec_eval rec_max_triangle [x] = Max_triangle x" |
725 "rec_eval rec_max_triangle [x] = Max_triangle x" |
716 by (simp add: Max_triangle_greatest rec_max_triangle_def Let_def BMax_rec_eq1) |
726 by (simp add: Max_triangle_greatest rec_max_triangle_def Let_def BMax_rec_eq1) |
717 |
727 |
718 |
728 |
719 text {* Encodings for Products *} |
729 text {* Encodings for Pairs of Natural Numbers *} |
720 |
730 |
721 definition |
731 definition |
722 "rec_penc = CN rec_add [CN rec_triangle [CN rec_add [Id 2 0, Id 2 1]], Id 2 0]" |
732 "rec_penc = CN rec_add [CN rec_triangle [CN rec_add [Id 2 0, Id 2 1]], Id 2 0]" |
723 |
733 |
724 definition |
734 definition |
738 lemma penc_lemma [simp]: |
748 lemma penc_lemma [simp]: |
739 "rec_eval rec_penc [m, n] = penc m n" |
749 "rec_eval rec_penc [m, n] = penc m n" |
740 by (simp add: rec_penc_def prod_encode_def) |
750 by (simp add: rec_penc_def prod_encode_def) |
741 |
751 |
742 |
752 |
743 text {* Encodings of Lists *} |
753 text {* Encodings of Lists of Natural Numbers *} |
744 |
754 |
745 fun |
755 fun |
746 lenc :: "nat list \<Rightarrow> nat" |
756 lenc :: "nat list \<Rightarrow> nat" |
747 where |
757 where |
748 "lenc [] = 0" |
758 "lenc [] = 0" |
770 |
780 |
771 lemma lenc_length_le: |
781 lemma lenc_length_le: |
772 "length xs \<le> lenc xs" |
782 "length xs \<le> lenc xs" |
773 by (induct xs) (simp_all add: prod_encode_def) |
783 by (induct xs) (simp_all add: prod_encode_def) |
774 |
784 |
775 |
785 text {* The membership predicate for an encoded list. *} |
776 text {* Membership for the List Encoding *} |
|
777 |
786 |
778 fun within :: "nat \<Rightarrow> nat \<Rightarrow> bool" where |
787 fun within :: "nat \<Rightarrow> nat \<Rightarrow> bool" where |
779 "within z 0 = (0 < z)" |
788 "within z 0 = (0 < z)" |
780 | "within z (Suc n) = within (pdec2 z) n" |
789 | "within z (Suc n) = within (pdec2 z) n" |
781 |
790 |
793 apply(simp_all add: prod_encode_def) |
802 apply(simp_all add: prod_encode_def) |
794 apply(case_tac xs) |
803 apply(case_tac xs) |
795 apply(simp_all) |
804 apply(simp_all) |
796 done |
805 done |
797 |
806 |
798 text {* Length of Encoded Lists *} |
807 text {* The length of an encoded list. *} |
799 |
808 |
800 lemma enclen_length [simp]: |
809 lemma enclen_length [simp]: |
801 "enclen (lenc xs) = length xs" |
810 "enclen (lenc xs) = length xs" |
802 unfolding enclen_def |
811 unfolding enclen_def |
803 apply(simp add: BMax_rec_eq1) |
812 apply(simp add: BMax_rec_eq1) |