| author | wenzelm | 
| Tue, 19 Sep 2006 23:01:52 +0200 | |
| changeset 20618 | 3f763be47c2f | 
| parent 20597 | 65fe827aa595 | 
| child 20701 | 17a625996bb0 | 
| permissions | -rw-r--r-- | 
| 19039 | 1  | 
(* Title: HOL/Library/ExecutableRat.thy  | 
2  | 
ID: $Id$  | 
|
3  | 
Author: Florian Haftmann, TU Muenchen  | 
|
4  | 
*)  | 
|
5  | 
||
6  | 
header {* Executable implementation of rational numbers in HOL *}
 | 
|
7  | 
||
8  | 
theory ExecutableRat  | 
|
9  | 
imports "~~/src/HOL/Real/Rational" "~~/src/HOL/NumberTheory/IntPrimes"  | 
|
10  | 
begin  | 
|
11  | 
||
12  | 
text {*
 | 
|
13  | 
Actually nothing is proved about the implementation.  | 
|
14  | 
*}  | 
|
15  | 
||
| 19791 | 16  | 
|
17  | 
section {* HOL definitions *}
 | 
|
18  | 
||
| 19039 | 19  | 
datatype erat = Rat bool int int  | 
20  | 
||
| 
19233
 
77ca20b0ed77
renamed HOL + - * etc. to HOL.plus HOL.minus HOL.times etc.
 
haftmann 
parents: 
19137 
diff
changeset
 | 
21  | 
instance erat :: zero ..  | 
| 
 
77ca20b0ed77
renamed HOL + - * etc. to HOL.plus HOL.minus HOL.times etc.
 
haftmann 
parents: 
19137 
diff
changeset
 | 
22  | 
instance erat :: one ..  | 
| 
 
77ca20b0ed77
renamed HOL + - * etc. to HOL.plus HOL.minus HOL.times etc.
 
haftmann 
parents: 
19137 
diff
changeset
 | 
23  | 
instance erat :: plus ..  | 
| 
 
77ca20b0ed77
renamed HOL + - * etc. to HOL.plus HOL.minus HOL.times etc.
 
haftmann 
parents: 
19137 
diff
changeset
 | 
24  | 
instance erat :: minus ..  | 
| 
 
77ca20b0ed77
renamed HOL + - * etc. to HOL.plus HOL.minus HOL.times etc.
 
haftmann 
parents: 
19137 
diff
changeset
 | 
25  | 
instance erat :: times ..  | 
| 
 
77ca20b0ed77
renamed HOL + - * etc. to HOL.plus HOL.minus HOL.times etc.
 
haftmann 
parents: 
19137 
diff
changeset
 | 
26  | 
instance erat :: inverse ..  | 
| 
 
77ca20b0ed77
renamed HOL + - * etc. to HOL.plus HOL.minus HOL.times etc.
 
haftmann 
parents: 
19137 
diff
changeset
 | 
27  | 
instance erat :: ord ..  | 
| 19039 | 28  | 
|
| 19609 | 29  | 
definition  | 
| 19039 | 30  | 
norm :: "erat \<Rightarrow> erat"  | 
| 19791 | 31  | 
norm_def: "norm r = (case r of (Rat a p q) \<Rightarrow>  | 
| 19039 | 32  | 
if p = 0 then Rat True 0 1  | 
33  | 
else  | 
|
34  | 
let  | 
|
35  | 
absp = abs p  | 
|
36  | 
in let  | 
|
37  | 
m = zgcd (absp, q)  | 
|
| 19609 | 38  | 
in Rat (a = (0 <= p)) (absp div m) (q div m))"  | 
39  | 
common :: "(int * int) * (int * int) \<Rightarrow> (int * int) * int"  | 
|
| 19791 | 40  | 
common_def: "common r = (case r of ((p1, q1), (p2, q2)) \<Rightarrow>  | 
| 19039 | 41  | 
let q' = q1 * q2 div int (gcd (nat q1, nat q2))  | 
| 19609 | 42  | 
in ((p1 * (q' div q1), p2 * (q' div q2)), q'))"  | 
43  | 
of_quotient :: "int * int \<Rightarrow> erat"  | 
|
| 19791 | 44  | 
of_quotient_def: "of_quotient r = (case r of (a, b) \<Rightarrow>  | 
| 19609 | 45  | 
norm (Rat True a b))"  | 
46  | 
of_rat :: "rat \<Rightarrow> erat"  | 
|
| 19791 | 47  | 
of_rat_def: "of_rat r = of_quotient (SOME s. s : Rep_Rat r)"  | 
| 19609 | 48  | 
to_rat :: "erat \<Rightarrow> rat"  | 
| 19791 | 49  | 
to_rat_def: "to_rat r = (case r of (Rat a p q) \<Rightarrow>  | 
| 19609 | 50  | 
if a then Fract p q else Fract (uminus p) q)"  | 
| 20597 | 51  | 
eq_erat :: "erat \<Rightarrow> erat \<Rightarrow> bool"  | 
52  | 
"eq_erat r s = (norm r = norm s)"  | 
|
| 19039 | 53  | 
|
54  | 
defs (overloaded)  | 
|
| 19791 | 55  | 
zero_rat_def: "0 == Rat True 0 1"  | 
56  | 
one_rat_def: "1 == Rat True 1 1"  | 
|
57  | 
add_rat_def: "r + s == case r of Rat a1 p1 q1 \<Rightarrow> case s of Rat a2 p2 q2 \<Rightarrow>  | 
|
| 19039 | 58  | 
let  | 
59  | 
((r1, r2), den) = common ((p1, q1), (p2, q2))  | 
|
60  | 
in let  | 
|
61  | 
num = (if a1 then r1 else -r1) + (if a2 then r2 else -r2)  | 
|
62  | 
in norm (Rat True num den)"  | 
|
| 19791 | 63  | 
uminus_rat_def: "- r == case r of Rat a p q \<Rightarrow>  | 
| 19039 | 64  | 
if p = 0 then Rat a p q  | 
65  | 
else Rat (\<not> a) p q"  | 
|
| 19791 | 66  | 
times_rat_def: "r * s == case r of Rat a1 p1 q1 \<Rightarrow> case s of Rat a2 p2 q2 \<Rightarrow>  | 
| 19039 | 67  | 
norm (Rat (a1 = a2) (p1 * p2) (q1 * q2))"  | 
| 19791 | 68  | 
inverse_rat_def: "inverse r == case r of Rat a p q \<Rightarrow>  | 
| 19039 | 69  | 
if p = 0 then arbitrary  | 
70  | 
else Rat a q p"  | 
|
| 19791 | 71  | 
le_rat_def: "r <= s == case r of Rat a1 p1 q1 \<Rightarrow> case s of Rat a2 p2 q2 \<Rightarrow>  | 
| 19039 | 72  | 
(\<not> a1 \<and> a2) \<or>  | 
73  | 
(\<not> (a1 \<and> \<not> a2) \<and>  | 
|
74  | 
(let  | 
|
75  | 
((r1, r2), dummy) = common ((p1, q1), (p2, q2))  | 
|
76  | 
in if a1 then r1 <= r2 else r2 <= r1))"  | 
|
77  | 
||
| 19791 | 78  | 
|
79  | 
section {* type serializations *}
 | 
|
80  | 
||
81  | 
types_code  | 
|
82  | 
  rat ("{*erat*}")
 | 
|
83  | 
||
| 
20453
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
84  | 
code_gen Rat  | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
85  | 
(SML) (Haskell)  | 
| 19889 | 86  | 
|
| 
20453
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
87  | 
code_type rat  | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
88  | 
  (SML "{*erat*}")
 | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
89  | 
  (Haskell "{*erat*}")
 | 
| 19039 | 90  | 
|
| 19791 | 91  | 
|
92  | 
section {* const serializations *}
 | 
|
93  | 
||
94  | 
consts_code  | 
|
95  | 
  arbitrary :: erat ("raise/ (Fail/ \"non-defined rational number\")")
 | 
|
96  | 
  Fract ("{*of_quotient*}")
 | 
|
97  | 
  0 :: rat ("{*0::erat*}")
 | 
|
98  | 
  1 :: rat ("{*1::erat*}")
 | 
|
99  | 
  HOL.plus :: "rat \<Rightarrow> rat \<Rightarrow> rat" ("{*op + :: erat \<Rightarrow> erat \<Rightarrow> erat*}")
 | 
|
100  | 
  uminus :: "rat \<Rightarrow> rat" ("{*uminus :: erat \<Rightarrow> erat*}")
 | 
|
101  | 
  HOL.times :: "rat \<Rightarrow> rat \<Rightarrow> rat" ("{*op * :: erat \<Rightarrow> erat \<Rightarrow> erat*}")
 | 
|
102  | 
  inverse :: "rat \<Rightarrow> rat" ("{*inverse :: erat \<Rightarrow> erat*}")
 | 
|
103  | 
  divide :: "rat \<Rightarrow> rat \<Rightarrow> rat" ("{*op * :: erat \<Rightarrow> erat \<Rightarrow> erat*}/ _/ ({*inverse :: erat \<Rightarrow> erat*}/ _)")
 | 
|
104  | 
  Orderings.less_eq :: "rat \<Rightarrow> rat \<Rightarrow> bool" ("{*op <= :: erat \<Rightarrow> erat \<Rightarrow> bool*}")
 | 
|
105  | 
  "op =" :: "rat \<Rightarrow> rat \<Rightarrow> bool" ("{*eq_rat*}")
 | 
|
106  | 
||
| 
20453
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
107  | 
code_const "arbitrary :: erat"  | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
108  | 
(SML "raise/ (Fail/ \"non-defined rational number\")")  | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
109  | 
(Haskell "error/ \"non-defined rational number\"")  | 
| 19889 | 110  | 
|
| 
20453
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
111  | 
code_gen  | 
| 19889 | 112  | 
of_quotient  | 
113  | 
"0::erat"  | 
|
114  | 
"1::erat"  | 
|
115  | 
"op + :: erat \<Rightarrow> erat \<Rightarrow> erat"  | 
|
116  | 
"uminus :: erat \<Rightarrow> erat"  | 
|
117  | 
"op * :: erat \<Rightarrow> erat \<Rightarrow> erat"  | 
|
118  | 
"inverse :: erat \<Rightarrow> erat"  | 
|
119  | 
"op <= :: erat \<Rightarrow> erat \<Rightarrow> bool"  | 
|
| 20597 | 120  | 
eq_erat  | 
| 
20453
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
121  | 
(SML) (Haskell)  | 
| 19889 | 122  | 
|
| 
20453
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
123  | 
code_const Fract  | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
124  | 
  (SML "{*of_quotient*}")
 | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
125  | 
  (Haskell "{*of_quotient*}")
 | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
126  | 
|
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
127  | 
code_const "0 :: rat"  | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
128  | 
  (SML "{*0::erat*}")
 | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
129  | 
  (Haskell "{*1::erat*}")
 | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
130  | 
|
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
131  | 
code_const "1 :: rat"  | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
132  | 
  (SML "{*1::erat*}")
 | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
133  | 
  (Haskell "{*1::erat*}")
 | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
134  | 
|
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
135  | 
code_const "op + :: rat \<Rightarrow> rat \<Rightarrow> rat"  | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
136  | 
  (SML "{*op + :: erat \<Rightarrow> erat \<Rightarrow> erat*}")
 | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
137  | 
  (Haskell "{*op + :: erat \<Rightarrow> erat \<Rightarrow> erat*}")
 | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
138  | 
|
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
139  | 
code_const "uminus :: rat \<Rightarrow> rat"  | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
140  | 
  (SML "{*uminus :: erat \<Rightarrow> erat*}")
 | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
141  | 
  (Haskell "{*uminus :: erat \<Rightarrow> erat*}")
 | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
142  | 
|
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
143  | 
code_const "op * :: rat \<Rightarrow> rat \<Rightarrow> rat"  | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
144  | 
  (SML "{*op * :: erat \<Rightarrow> erat \<Rightarrow> erat*}")
 | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
145  | 
  (Haskell "{*op * :: erat \<Rightarrow> erat \<Rightarrow> erat*}")
 | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
146  | 
|
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
147  | 
code_const "inverse :: rat \<Rightarrow> rat"  | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
148  | 
  (SML "{*inverse :: erat \<Rightarrow> erat*}")
 | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
149  | 
  (Haskell "{*inverse :: erat \<Rightarrow> erat*}")
 | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
150  | 
|
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
151  | 
code_const "divide :: rat \<Rightarrow> rat \<Rightarrow> rat"  | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
152  | 
  (SML "{*op * :: erat \<Rightarrow> erat \<Rightarrow> erat*}/ _/ ({*inverse :: erat \<Rightarrow> erat*}/ _)")
 | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
153  | 
  (Haskell "{*op * :: erat \<Rightarrow> erat \<Rightarrow> erat*}/ _/ ({*inverse :: erat \<Rightarrow> erat*}/ _)")
 | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
154  | 
|
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
155  | 
code_const "op <= :: rat \<Rightarrow> rat \<Rightarrow> bool"  | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
156  | 
  (SML "{*op <= :: erat \<Rightarrow> erat \<Rightarrow> bool*}")
 | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
157  | 
  (Haskell "{*op <= :: erat \<Rightarrow> erat \<Rightarrow> bool*}")
 | 
| 
 
855f07fabd76
final syntax for some Isar code generator keywords
 
haftmann 
parents: 
19889 
diff
changeset
 | 
158  | 
|
| 20597 | 159  | 
instance rat :: eq ..  | 
160  | 
||
161  | 
code_const "OperationalEquality.eq :: rat \<Rightarrow> rat \<Rightarrow> bool"  | 
|
162  | 
  (SML "{*eq_erat*}")
 | 
|
163  | 
  (Haskell "{*eq_erat*}")
 | 
|
164  | 
||
165  | 
code_gen (SML -)  | 
|
| 19039 | 166  | 
|
167  | 
end  |