594 |
594 |
595 |
595 |
596 subsection {* Implementation of rational numbers as pairs of integers *} |
596 subsection {* Implementation of rational numbers as pairs of integers *} |
597 |
597 |
598 definition |
598 definition |
599 RatC :: "int \<times> int \<Rightarrow> rat" |
599 Rational :: "int \<times> int \<Rightarrow> rat" |
600 where |
600 where |
601 "RatC = INum" |
601 "Rational = INum" |
602 |
602 |
603 code_datatype RatC |
603 code_datatype Rational |
604 |
604 |
605 lemma RatC_simp: |
605 lemma Rational_simp: |
606 "RatC (k, l) = rat_of_int k / rat_of_int l" |
606 "Rational (k, l) = rat_of_int k / rat_of_int l" |
607 unfolding RatC_def INum_def by simp |
607 unfolding Rational_def INum_def by simp |
608 |
608 |
609 lemma RatC_zero [simp]: "RatC 0\<^sub>N = 0" |
609 lemma Rational_zero [simp]: "Rational 0\<^sub>N = 0" |
610 by (simp add: RatC_simp) |
610 by (simp add: Rational_simp) |
611 |
611 |
612 lemma RatC_lit [simp]: "RatC i\<^sub>N = rat_of_int i" |
612 lemma Rational_lit [simp]: "Rational i\<^sub>N = rat_of_int i" |
613 by (simp add: RatC_simp) |
613 by (simp add: Rational_simp) |
614 |
614 |
615 lemma zero_rat_code [code, code unfold]: |
615 lemma zero_rat_code [code, code unfold]: |
616 "0 = RatC 0\<^sub>N" by simp |
616 "0 = Rational 0\<^sub>N" by simp |
617 |
617 |
618 lemma zero_rat_code [code, code unfold]: |
618 lemma zero_rat_code [code, code unfold]: |
619 "1 = RatC 1\<^sub>N" by simp |
619 "1 = Rational 1\<^sub>N" by simp |
620 |
620 |
621 lemma [code, code unfold]: |
621 lemma [code, code unfold]: |
622 "number_of k = rat_of_int (number_of k)" |
622 "number_of k = rat_of_int (number_of k)" |
623 by (simp add: number_of_is_id rat_number_of_def) |
623 by (simp add: number_of_is_id rat_number_of_def) |
624 |
624 |
628 lemma [code]: |
628 lemma [code]: |
629 "Fract k l = Fract' (l \<noteq> 0) k l" |
629 "Fract k l = Fract' (l \<noteq> 0) k l" |
630 unfolding Fract'_def .. |
630 unfolding Fract'_def .. |
631 |
631 |
632 lemma [code]: |
632 lemma [code]: |
633 "Fract' True k l = (if l \<noteq> 0 then RatC (k, l) else Fract 1 0)" |
633 "Fract' True k l = (if l \<noteq> 0 then Rational (k, l) else Fract 1 0)" |
634 by (simp add: Fract'_def RatC_simp Fract_of_int_quotient [of k l]) |
634 by (simp add: Fract'_def Rational_simp Fract_of_int_quotient [of k l]) |
635 |
635 |
636 lemma [code]: |
636 lemma [code]: |
637 "of_rat (RatC (k, l)) = (if l \<noteq> 0 then of_int k / of_int l else 0)" |
637 "of_rat (Rational (k, l)) = (if l \<noteq> 0 then of_int k / of_int l else 0)" |
638 by (cases "l = 0") |
638 by (cases "l = 0") |
639 (auto simp add: RatC_simp of_rat_rat [simplified Fract_of_int_quotient [of k l], symmetric]) |
639 (auto simp add: Rational_simp of_rat_rat [simplified Fract_of_int_quotient [of k l], symmetric]) |
640 |
640 |
641 instance rat :: eq .. |
641 instance rat :: eq .. |
642 |
642 |
643 lemma rat_eq_code [code]: "RatC x = RatC y \<longleftrightarrow> normNum x = normNum y" |
643 lemma rat_eq_code [code]: "Rational x = Rational y \<longleftrightarrow> normNum x = normNum y" |
644 unfolding RatC_def INum_normNum_iff .. |
644 unfolding Rational_def INum_normNum_iff .. |
645 |
645 |
646 lemma rat_less_eq_code [code]: "RatC x \<le> RatC y \<longleftrightarrow> normNum x \<le>\<^sub>N normNum y" |
646 lemma rat_less_eq_code [code]: "Rational x \<le> Rational y \<longleftrightarrow> normNum x \<le>\<^sub>N normNum y" |
647 proof - |
647 proof - |
648 have "normNum x \<le>\<^sub>N normNum y \<longleftrightarrow> RatC (normNum x) \<le> RatC (normNum y)" |
648 have "normNum x \<le>\<^sub>N normNum y \<longleftrightarrow> Rational (normNum x) \<le> Rational (normNum y)" |
649 by (simp add: RatC_def del: normNum) |
649 by (simp add: Rational_def del: normNum) |
650 also have "\<dots> = (RatC x \<le> RatC y)" by (simp add: RatC_def) |
650 also have "\<dots> = (Rational x \<le> Rational y)" by (simp add: Rational_def) |
651 finally show ?thesis by simp |
651 finally show ?thesis by simp |
652 qed |
652 qed |
653 |
653 |
654 lemma rat_less_code [code]: "RatC x < RatC y \<longleftrightarrow> normNum x <\<^sub>N normNum y" |
654 lemma rat_less_code [code]: "Rational x < Rational y \<longleftrightarrow> normNum x <\<^sub>N normNum y" |
655 proof - |
655 proof - |
656 have "normNum x <\<^sub>N normNum y \<longleftrightarrow> RatC (normNum x) < RatC (normNum y)" |
656 have "normNum x <\<^sub>N normNum y \<longleftrightarrow> Rational (normNum x) < Rational (normNum y)" |
657 by (simp add: RatC_def del: normNum) |
657 by (simp add: Rational_def del: normNum) |
658 also have "\<dots> = (RatC x < RatC y)" by (simp add: RatC_def) |
658 also have "\<dots> = (Rational x < Rational y)" by (simp add: Rational_def) |
659 finally show ?thesis by simp |
659 finally show ?thesis by simp |
660 qed |
660 qed |
661 |
661 |
662 lemma rat_add_code [code]: "RatC x + RatC y = RatC (x +\<^sub>N y)" |
662 lemma rat_add_code [code]: "Rational x + Rational y = Rational (x +\<^sub>N y)" |
663 unfolding RatC_def by simp |
663 unfolding Rational_def by simp |
664 |
664 |
665 lemma rat_mul_code [code]: "RatC x * RatC y = RatC (x *\<^sub>N y)" |
665 lemma rat_mul_code [code]: "Rational x * Rational y = Rational (x *\<^sub>N y)" |
666 unfolding RatC_def by simp |
666 unfolding Rational_def by simp |
667 |
667 |
668 lemma rat_neg_code [code]: "- RatC x = RatC (~\<^sub>N x)" |
668 lemma rat_neg_code [code]: "- Rational x = Rational (~\<^sub>N x)" |
669 unfolding RatC_def by simp |
669 unfolding Rational_def by simp |
670 |
670 |
671 lemma rat_sub_code [code]: "RatC x - RatC y = RatC (x -\<^sub>N y)" |
671 lemma rat_sub_code [code]: "Rational x - Rational y = Rational (x -\<^sub>N y)" |
672 unfolding RatC_def by simp |
672 unfolding Rational_def by simp |
673 |
673 |
674 lemma rat_inv_code [code]: "inverse (RatC x) = RatC (Ninv x)" |
674 lemma rat_inv_code [code]: "inverse (Rational x) = Rational (Ninv x)" |
675 unfolding RatC_def Ninv divide_rat_def by simp |
675 unfolding Rational_def Ninv divide_rat_def by simp |
676 |
676 |
677 lemma rat_div_code [code]: "RatC x / RatC y = RatC (x \<div>\<^sub>N y)" |
677 lemma rat_div_code [code]: "Rational x / Rational y = Rational (x \<div>\<^sub>N y)" |
678 unfolding RatC_def by simp |
678 unfolding Rational_def by simp |
679 |
679 |
680 text {* Setup for old code generator *} |
680 text {* Setup for SML code generator *} |
681 |
681 |
682 types_code |
682 types_code |
683 rat ("(int */ int)") |
683 rat ("(int */ int)") |
684 attach (term_of) {* |
684 attach (term_of) {* |
685 fun term_of_rat (p, q) = |
685 fun term_of_rat (p, q) = |
686 let val rT = Type ("Rational.rat", []) |
686 let |
|
687 val rT = @{typ rat} |
687 in |
688 in |
688 if q = 1 orelse p = 0 then HOLogic.mk_number rT p |
689 if q = 1 orelse p = 0 then HOLogic.mk_number rT p |
689 else Const ("HOL.inverse_class.divide", [rT, rT] ---> rT) $ |
690 else @{term "op / \<Colon> rat \<Rightarrow> rat \<Rightarrow> rat"} $ |
690 HOLogic.mk_number rT p $ HOLogic.mk_number rT q |
691 HOLogic.mk_number rT p $ HOLogic.mk_number rT q |
691 end; |
692 end; |
692 *} |
693 *} |
693 attach (test) {* |
694 attach (test) {* |
694 fun gen_rat i = |
695 fun gen_rat i = |