src/Tools/rat.ML
changeset 23261 85f27f79232f
parent 23251 471b576aad25
child 23297 06f108974fa1
--- a/src/Tools/rat.ML	Tue Jun 05 18:36:10 2007 +0200
+++ b/src/Tools/rat.ML	Tue Jun 05 19:19:30 2007 +0200
@@ -12,9 +12,9 @@
   val zero: rat
   val one: rat
   val two: rat
-  val rat_of_int: Intt.int -> rat
-  val rat_of_quotient: Intt.int * Intt.int -> rat
-  val quotient_of_rat: rat -> Intt.int * Intt.int
+  val rat_of_int: integer -> rat
+  val rat_of_quotient: integer * integer -> rat
+  val quotient_of_rat: rat -> integer * integer
   val string_of_rat: rat -> string
   val eq: rat * rat -> bool
   val cmp: rat * rat -> order
@@ -32,53 +32,59 @@
 structure Rat : RAT =
 struct
 
-datatype rat = Rat of bool * Intt.int * Intt.int;
+datatype rat = Rat of bool * integer * integer;
 
 exception DIVZERO;
 
-val zero = Rat (true, Intt.int 0, Intt.int 1);
-val one = Rat (true, Intt.int 1, Intt.int 1);
-val two = Rat (true, Intt.int 2, Intt.int 1);
+val zero = Rat (true, Integer.zero, Integer.one);
+val one = Rat (true, Integer.one, Integer.one);
+val two = Rat (true, Integer.two, Integer.one);
 
 fun rat_of_int i =
-  if i < Intt.int 0
-  then Rat (false, ~i, Intt.int 1)
-  else Rat (true, i, Intt.int 1);
+  let
+    val (a, p) = Integer.signabs i
+  in Rat (a, p, Integer.one) end;
 
 fun norm (a, p, q) =
-  if p = Intt.int 0 then Rat (true, Intt.int 0, Intt.int 1)
+  if Integer.cmp_zero p = EQUAL then Rat (true, Integer.zero, Integer.one)
   else
     let
-      val absp = abs p
-      val m = gcd (absp, q)
-    in Rat(a = (Intt.int 0 <= p), absp div m, q div m) end;
+      val (b, absp) = Integer.signabs p;
+      val m = Integer.gcd absp q;
+    in Rat (a = b, Integer.div absp m, Integer.div q m) end;
 
 fun common (p1, q1, p2, q2) =
-  let val q' = lcm (q1, q2)
-  in (p1 * (q' div q1), p2 * (q' div q2), q') end
+  let
+    val q' = Integer.lcm q1 q2;
+  in (p1 *% (Integer.div q' q1), p2 *% (Integer.div q' q2), q') end
 
 fun rat_of_quotient (p, q) =
-  if q = Intt.int 0 then raise DIVZERO
-  else norm (Intt.int 0 <= q, p, abs q);
+  let
+    val (a, absq) = Integer.signabs q;
+  in
+    if Integer.cmp_zero absq = EQUAL then raise DIVZERO
+    else norm (a, p, absq)
+  end;
 
-fun quotient_of_rat (Rat (a, p, q)) = (if a then p else ~p, q);
+fun quotient_of_rat (Rat (a, p, q)) = (if a then p else Integer.neg p, q);
 
 fun string_of_rat r =
-  let val (p, q) = quotient_of_rat r
-  in Intt.string_of_int p ^ "/" ^ Intt.string_of_int q end;
+  let
+    val (p, q) = quotient_of_rat r;
+  in Integer.string_of_int p ^ "/" ^ Integer.string_of_int q end;
 
 fun eq (Rat (false, _, _), Rat (true, _, _)) = false
   | eq (Rat (true, _, _), Rat (false, _, _)) = false
-  | eq (Rat (_, p1, q1), Rat (_, p2, q2)) = p1 = p2 andalso q1 = q2
+  | eq (Rat (_, p1, q1), Rat (_, p2, q2)) = p1 =% p2 andalso q1 =% q2;
 
 fun cmp (Rat (false, _, _), Rat (true, _, _)) = LESS
   | cmp (Rat (true, _, _), Rat (false, _, _)) = GREATER
   | cmp (Rat (a, p1, q1), Rat (_, p2, q2)) =
       let val (r1, r2, _) = common (p1, q1, p2, q2)
-      in if a then Intt.cmp (r1, r2) else Intt.cmp (r2, r1) end;
+      in if a then Integer.cmp (r1, r2) else Integer.cmp (r2, r1) end;
 
 fun le a b = let val order = cmp (a, b) in order = LESS orelse order = EQUAL end;
-fun lt a b = cmp (a, b) = LESS;
+fun lt a b = (cmp (a, b) = LESS);
 
 fun cmp_zero (Rat (false, _, _)) = LESS
   | cmp_zero (Rat (_, 0, _)) = EQUAL
@@ -86,53 +92,50 @@
 
 fun add (Rat (a1, p1, q1)) (Rat(a2, p2, q2)) =
   let
-    val (r1, r2, den) = common (p1, q1, p2, q2)
-    val num = (if a1 then r1 else ~r1) + (if a2 then r2 else ~r2)
+    val (r1, r2, den) = common (p1, q1, p2, q2);
+    val num = (if a1 then r1 else Integer.neg r1)
+      +% (if a2 then r2 else Integer.neg r2);
   in norm (true, num, den) end;
 
 fun mult (Rat (a1, p1, q1)) (Rat (a2, p2, q2)) =
-  norm (a1=a2, p1*p2, q1*q2);
+  norm (a1 = a2, p1 *% p2, q1 *% q2);
 
 fun neg (r as Rat (b, p, q)) =
-  if p = Intt.int 0 then r
+  if Integer.cmp_zero p = EQUAL then r
   else Rat (not b, p, q);
 
 fun inv (Rat (a, p, q)) =
-  if p = Intt.int 0 then raise DIVZERO
+  if Integer.cmp_zero q = EQUAL then raise DIVZERO
   else Rat (a, q, p);
 
 fun roundup (r as Rat (a, p, q)) =
-  if q = Intt.int 1 then r
+  if q = Integer.one then r
   else
     let
-      fun round true q = Rat (true, q + Intt.int 1, Intt.int 1)
+      fun round true q = Rat (true, Integer.inc q, Integer.one)
         | round false q =
-            if q = Intt.int 0
-            then Rat (true, Intt.int 0, Intt.int 1)
-            else Rat (false, q, Intt.int 1);
-    in round a (p div q) end;
+            Rat (Integer.cmp_zero q = EQUAL, Integer.int 0, Integer.int 1);
+    in round a (Integer.div p q) end;
 
 fun rounddown (r as Rat (a, p, q)) =
-  if q = Intt.int 1 then r
+  if q = Integer.one then r
   else
     let
-      fun round true q = Rat (true, q, Intt.int 1)
-        | round false q = Rat (false, q + Intt.int 1, Intt.int 1)
-    in round a (p div q) end;
+      fun round true q = Rat (true, q, Integer.one)
+        | round false q = Rat (false, Integer.inc q, Integer.one)
+    in round a (Integer.div p q) end;
 
 end;
 
-infix 5 +/; 
-infix 5 -/;
-infix 7 */;
-infix 7 //; 
+infix 7 */ //;
+infix 6 +/ -/; 
 infix 4 =/ </ <=/ >/ >=/ <>/;
 
 fun a +/ b = Rat.add a b;
 fun a -/ b = a +/ Rat.neg b;
 fun a */ b = Rat.mult a b;
 fun a // b = a */ Rat.inv b; 
-fun a =/ b = Rat.eq (a,b);
+fun a =/ b = Rat.eq (a, b);
 fun a </ b = Rat.lt a b;
 fun a <=/ b = Rat.le a b;
 fun a >/ b = b </ a;