src/HOL/Real/Rational.thy
changeset 24622 8116eb022282
parent 24533 fe1f93f6a15a
child 24630 351a308ab58d
equal deleted inserted replaced
24621:97d403d9ab54 24622:8116eb022282
   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 =
   703      if p' = 0 then 0 else q')
   704      if p' = 0 then 0 else q')
   704   end;
   705   end;
   705 *}
   706 *}
   706 
   707 
   707 consts_code
   708 consts_code
   708   RatC ("(_)")
   709   Rational ("(_)")
   709 
   710 
   710 consts_code
   711 consts_code
   711   "of_int :: int \<Rightarrow> rat" ("\<module>rat'_of'_int")
   712   "of_int :: int \<Rightarrow> rat" ("\<module>rat'_of'_int")
   712 attach {*
   713 attach {*
   713 fun rat_of_int 0 = (0, 0)
   714 fun rat_of_int 0 = (0, 0)