-- LML original: Sandra Foubister, 1990
-- Haskell translation: Colin Runciman, May 1991

module Rational(
radd, rsub, rmul, rdiv, rmin, rabs, intval, show_rat, torat) where
--CR removed norm from export list, renamed rmin2 as rmin

norm :: (Int, Int) -> (Int, Int)
norm (x,y) = (u `div` d, v `div` d)
             where
             u = if y > 0 then x else -x
	     v = abs y
             d = gcd (abs u) v

	     gcd :: Int -> Int -> Int
	     gcd 0 n2  = n2
	     gcd n1 0  = n1
	     gcd n1 n2 = if n1 < n2 then gcd n1 (n2 `mod` n1) else gcd (n1 `mod` n2) n2

radd, rsub, rmul, rdiv :: (Int, Int) -> (Int, Int) -> (Int, Int)
radd (x,y) (u,v) = norm (x * v + u * y, y * v)
rsub (x,y) (u,v) = norm (x * v - u * y, y * v)
rmul (x,y) (u,v) = norm (x * u, y * v)
rdiv (x,y) (u,v) = norm (x * v, y * u)

--CR removed unnecessary normalisation, renamed as rmin
rmin (x,y) (u,v) = if a > 0 then (u,v) else (x,y)
                   where (a,b) = rsub (x,y) (u,v)

--CR removed unnecessary normalisation
rabs :: (Int, Int) -> (Int, Int)
rabs (x,y) = if x<0 then (-x,y) else (x,y)

-- if y is zero we have an error condition
intval :: (Int, Int) -> Int
intval (x,y) = x `div` y

--for debugging
show_rat :: (Int, Int) -> [Char]
show_rat (x,y) = show x ++ "/" ++ show y

torat :: Int -> (Int, Int)
torat n = (n,1)



