586 |
586 |
587 text {* |
587 text {* |
588 Structures with subtraction @{term "op -"}. |
588 Structures with subtraction @{term "op -"}. |
589 *} |
589 *} |
590 |
590 |
591 text {* A decrement function *} |
591 text {* A double-and-decrement function *} |
592 |
592 |
593 primrec dec :: "num \<Rightarrow> num" where |
593 primrec DigM :: "num \<Rightarrow> num" where |
594 "dec 1 = 1" |
594 "DigM 1 = 1" |
595 | "dec (Dig0 n) = (case n of 1 \<Rightarrow> 1 | _ \<Rightarrow> Dig1 (dec n))" |
595 | "DigM (Dig0 n) = Dig1 (DigM n)" |
596 | "dec (Dig1 n) = Dig0 n" |
596 | "DigM (Dig1 n) = Dig1 (Dig0 n)" |
597 |
597 |
598 declare dec.simps [simp del, code del] |
598 lemma DigM_plus_one: "DigM n + 1 = Dig0 n" |
599 |
599 by (induct n) simp_all |
600 lemma Dig_dec [numeral, simp, code]: |
600 |
601 "dec 1 = 1" |
601 lemma one_plus_DigM: "1 + DigM n = Dig0 n" |
602 "dec (Dig0 1) = 1" |
602 unfolding add_commute [of 1] DigM_plus_one .. |
603 "dec (Dig0 (Dig0 n)) = Dig1 (dec (Dig0 n))" |
|
604 "dec (Dig0 (Dig1 n)) = Dig1 (Dig0 n)" |
|
605 "dec (Dig1 n) = Dig0 n" |
|
606 by (simp_all add: dec.simps) |
|
607 |
|
608 lemma Dig_dec_plus_one: |
|
609 "dec n + 1 = (if n = 1 then Dig0 1 else n)" |
|
610 by (induct n) |
|
611 (auto simp add: Dig_plus dec.simps, |
|
612 auto simp add: Dig_plus split: num.splits) |
|
613 |
|
614 lemma Dig_one_plus_dec: |
|
615 "1 + dec n = (if n = 1 then Dig0 1 else n)" |
|
616 unfolding add_commute [of 1] Dig_dec_plus_one .. |
|
617 |
603 |
618 class semiring_minus = semiring + minus + zero + |
604 class semiring_minus = semiring + minus + zero + |
619 assumes minus_inverts_plus1: "a + b = c \<Longrightarrow> c - b = a" |
605 assumes minus_inverts_plus1: "a + b = c \<Longrightarrow> c - b = a" |
620 assumes minus_minus_zero_inverts_plus1: "a + b = c \<Longrightarrow> b - c = 0 - a" |
606 assumes minus_minus_zero_inverts_plus1: "a + b = c \<Longrightarrow> b - c = 0 - a" |
621 begin |
607 begin |
682 lemma Dig_one_minus_one [numeral]: |
668 lemma Dig_one_minus_one [numeral]: |
683 "1 - 1 = 0" |
669 "1 - 1 = 0" |
684 by (simp add: minus_inverts_plus1) |
670 by (simp add: minus_inverts_plus1) |
685 |
671 |
686 lemma Dig_of_num_minus_one [numeral]: |
672 lemma Dig_of_num_minus_one [numeral]: |
687 "of_num (Dig0 n) - 1 = of_num (dec (Dig0 n))" |
673 "of_num (Dig0 n) - 1 = of_num (DigM n)" |
688 "of_num (Dig1 n) - 1 = of_num (Dig0 n)" |
674 "of_num (Dig1 n) - 1 = of_num (Dig0 n)" |
689 by (auto intro: minus_inverts_plus1 simp add: Dig_dec_plus_one of_num.simps of_num_plus_one) |
675 by (auto intro: minus_inverts_plus1 simp add: DigM_plus_one of_num.simps of_num_plus_one) |
690 |
676 |
691 lemma Dig_one_minus_of_num [numeral]: |
677 lemma Dig_one_minus_of_num [numeral]: |
692 "1 - of_num (Dig0 n) = 0 - of_num (dec (Dig0 n))" |
678 "1 - of_num (Dig0 n) = 0 - of_num (DigM n)" |
693 "1 - of_num (Dig1 n) = 0 - of_num (Dig0 n)" |
679 "1 - of_num (Dig1 n) = 0 - of_num (Dig0 n)" |
694 by (auto intro: minus_minus_zero_inverts_plus1 simp add: Dig_dec_plus_one of_num.simps of_num_plus_one) |
680 by (auto intro: minus_minus_zero_inverts_plus1 simp add: DigM_plus_one of_num.simps of_num_plus_one) |
695 |
681 |
696 end |
682 end |
697 |
683 |
698 context ring_1 |
684 context ring_1 |
699 begin |
685 begin |
746 unfolding of_num_plus_one [symmetric] by simp |
732 unfolding of_num_plus_one [symmetric] by simp |
747 |
733 |
748 lemma nat_number: |
734 lemma nat_number: |
749 "1 = Suc 0" |
735 "1 = Suc 0" |
750 "of_num 1 = Suc 0" |
736 "of_num 1 = Suc 0" |
751 "of_num (Dig0 n) = Suc (of_num (dec (Dig0 n)))" |
737 "of_num (Dig0 n) = Suc (of_num (DigM n))" |
752 "of_num (Dig1 n) = Suc (of_num (Dig0 n))" |
738 "of_num (Dig1 n) = Suc (of_num (Dig0 n))" |
753 by (simp_all add: of_num.simps Dig_dec_plus_one Suc_of_num) |
739 by (simp_all add: of_num.simps DigM_plus_one Suc_of_num) |
754 |
740 |
755 declare diff_0_eq_0 [numeral] |
741 declare diff_0_eq_0 [numeral] |
756 |
742 |
757 |
743 |
758 subsection {* Code generator setup for @{typ int} *} |
744 subsection {* Code generator setup for @{typ int} *} |
773 definition dup :: "int \<Rightarrow> int" where |
759 definition dup :: "int \<Rightarrow> int" where |
774 [code del]: "dup k = 2 * k" |
760 [code del]: "dup k = 2 * k" |
775 |
761 |
776 lemma Dig_sub [code]: |
762 lemma Dig_sub [code]: |
777 "sub 1 1 = 0" |
763 "sub 1 1 = 0" |
778 "sub (Dig0 m) 1 = of_num (dec (Dig0 m))" |
764 "sub (Dig0 m) 1 = of_num (DigM m)" |
779 "sub (Dig1 m) 1 = of_num (Dig0 m)" |
765 "sub (Dig1 m) 1 = of_num (Dig0 m)" |
780 "sub 1 (Dig0 n) = - of_num (dec (Dig0 n))" |
766 "sub 1 (Dig0 n) = - of_num (DigM n)" |
781 "sub 1 (Dig1 n) = - of_num (Dig0 n)" |
767 "sub 1 (Dig1 n) = - of_num (Dig0 n)" |
782 "sub (Dig0 m) (Dig0 n) = dup (sub m n)" |
768 "sub (Dig0 m) (Dig0 n) = dup (sub m n)" |
783 "sub (Dig1 m) (Dig1 n) = dup (sub m n)" |
769 "sub (Dig1 m) (Dig1 n) = dup (sub m n)" |
784 "sub (Dig1 m) (Dig0 n) = dup (sub m n) + 1" |
770 "sub (Dig1 m) (Dig0 n) = dup (sub m n) + 1" |
785 "sub (Dig0 m) (Dig1 n) = dup (sub m n) - 1" |
771 "sub (Dig0 m) (Dig1 n) = dup (sub m n) - 1" |
786 apply (simp_all add: dup_def algebra_simps) |
772 apply (simp_all add: dup_def algebra_simps) |
787 apply (simp_all add: of_num_plus Dig_one_plus_dec)[4] |
773 apply (simp_all add: of_num_plus one_plus_DigM)[4] |
788 apply (simp_all add: of_num.simps) |
774 apply (simp_all add: of_num.simps) |
789 done |
775 done |
790 |
776 |
791 lemma dup_code [code]: |
777 lemma dup_code [code]: |
792 "dup 0 = 0" |
778 "dup 0 = 0" |