Theory Code_Rational
section‹Code Generation for rational numbers in Haskell›
theory Code_Rational
imports
"HOL-Library.Code_Real_Approx_By_Float"
Code_Generation_IArrays
"HOL-Library.Code_Target_Int"
begin
subsection‹Serializations›
text‹The following ‹code_printing code_module› module is the usual way to import libraries
in Haskell. In this case, we rebind some functions from Data.Ratio.
See @{url "https://lists.cam.ac.uk/pipermail/cl-isabelle-users/2013-June/msg00007.html"}›
code_printing code_module Rational ⇀ (Haskell)
‹module Rational(fract, numerator, denominator) where
import qualified Data.Ratio
import Data.Ratio(numerator, denominator)
fract (a, b) = a Data.Ratio.% b›
context
includes integer.lifting
begin
lift_definition Frct_integer :: "integer × integer => rat"
is "Frct :: int × int => rat" .
end
consts Foo::rat
code_datatype Foo
context
includes integer.lifting
begin
lemma [code]:
"Frct a = Frct_integer ((of_int (fst a)), (of_int (snd a)))"
by (transfer, simp)
lemma [code]:
"Rat.of_int a = Frct_integer (of_int a, 1)"
by transfer (auto simp: Fract_of_int_eq Rat.of_int_def)
definition numerator :: "rat => int"
where "numerator x = fst (quotient_of x)"
definition denominator :: "rat => int"
where "denominator x = snd (quotient_of x)"
lift_definition numerator_integer :: "rat => integer"
is "numerator" .
lift_definition denominator_integer :: "rat => integer"
is "denominator" .
lemma [code]:
"inverse x = Frct_integer (denominator_integer x, numerator_integer x)"
apply (cases x)
apply transfer
apply (auto simp: inverse_eq_divide numerator_def denominator_def quotient_of_Fract One_rat_def)
done
lemma quotient_of_num_den: "quotient_of x = ((numerator x), (denominator x))"
unfolding numerator_def denominator_def
by simp
lemma [code]: "quotient_of x = (int_of_integer (numerator_integer x), int_of_integer(denominator_integer x))"
by (transfer, simp add: quotient_of_num_den)
end
code_printing
type_constructor rat ⇀ (Haskell) "Prelude.Rational"
| class_instance rat :: "HOL.equal" => (Haskell) -
| constant "0 :: rat" ⇀ (Haskell) "(Prelude.toRational (0::Integer))"
| constant "1 :: rat" ⇀ (Haskell) "(Prelude.toRational (1::Integer))"
| constant "Frct_integer" ⇀ (Haskell) "Rational.fract (_)"
| constant "numerator_integer" ⇀ (Haskell) "Rational.numerator (_)"
| constant "denominator_integer" ⇀ (Haskell) "Rational.denominator (_)"
| constant "HOL.equal :: rat ⇒ rat ⇒ bool" ⇀
(Haskell) "(_) == (_)"
| constant "(<) :: rat => rat => bool" ⇀
(Haskell) "_ < _"
| constant "(≤) :: rat => rat => bool" ⇀
(Haskell) "_ <= _"
| constant "(+) :: rat ⇒ rat ⇒ rat" ⇀
(Haskell) "(_) + (_)"
| constant "(-) :: rat ⇒ rat ⇒ rat" ⇀
(Haskell) "(_) - (_)"
| constant "(*) :: rat ⇒ rat ⇒ rat" ⇀
(Haskell) "(_) * (_)"
| constant "(/) :: rat ⇒ rat ⇒ rat" ⇀
(Haskell) " (_) '/ (_)"
| constant "uminus :: rat => rat" ⇀
(Haskell) "Prelude.negate"
end