module Data.Number.Flint.Fmpq.Instances (
  Fmpq (..)
) where

import System.IO.Unsafe
import Control.Monad

import qualified Data.Ratio as Ratio
import Data.Ratio ((%))

import Foreign.Storable
import Foreign.C.Types
import Foreign.C.String
import Foreign.Ptr
import Foreign.ForeignPtr
import Foreign.Marshal.Alloc

import Data.Char
import Text.Read
import Data.Number.Flint.Fmpz
import Data.Number.Flint.Fmpz.Instances
import Data.Number.Flint.Fmpq
import Data.Number.Flint.Quotient ((//))

instance Show Fmpq where
  show :: Fmpq -> String
show Fmpq
x = (Fmpq, String) -> String
forall a b. (a, b) -> b
snd ((Fmpq, String) -> String) -> (Fmpq, String) -> String
forall a b. (a -> b) -> a -> b
$ IO (Fmpq, String) -> (Fmpq, String)
forall a. IO a -> a
unsafePerformIO (IO (Fmpq, String) -> (Fmpq, String))
-> IO (Fmpq, String) -> (Fmpq, String)
forall a b. (a -> b) -> a -> b
$ do
    let base :: CInt
base = CInt
10 :: CInt
    Fmpq -> (Ptr CFmpq -> IO String) -> IO (Fmpq, String)
forall {a}. Fmpq -> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
withFmpq Fmpq
x ((Ptr CFmpq -> IO String) -> IO (Fmpq, String))
-> (Ptr CFmpq -> IO String) -> IO (Fmpq, String)
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpq
x -> do
      CString
cs <- CString -> CInt -> Ptr CFmpq -> IO CString
fmpq_get_str CString
forall a. Ptr a
nullPtr CInt
10 Ptr CFmpq
x
      String
s <- CString -> IO String
peekCString CString
cs
      CString -> IO ()
forall a. Ptr a -> IO ()
free CString
cs
      String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return String
s

instance Read Fmpq where
  readPrec :: ReadPrec Fmpq
readPrec = ReadPrec Fmpq -> ReadPrec Fmpq
forall a. ReadPrec a -> ReadPrec a
parens (ReadPrec Fmpq -> ReadPrec Fmpq) -> ReadPrec Fmpq -> ReadPrec Fmpq
forall a b. (a -> b) -> a -> b
$
               (Int -> ReadPrec Fmpq -> ReadPrec Fmpq
forall a. Int -> ReadPrec a -> ReadPrec a
prec Int
app_prec (ReadPrec Fmpq -> ReadPrec Fmpq) -> ReadPrec Fmpq -> ReadPrec Fmpq
forall a b. (a -> b) -> a -> b
$ do
                  Fmpz
x <- ReadPrec Fmpz -> ReadPrec Fmpz
forall a. ReadPrec a -> ReadPrec a
step ReadPrec Fmpz
forall a. Read a => ReadPrec a
readPrec
                  Symbol String
"/" <- ReadPrec Lexeme
lexP
                  Fmpz
y <- ReadPrec Fmpz -> ReadPrec Fmpz
forall a. ReadPrec a -> ReadPrec a
step ReadPrec Fmpz
forall a. Read a => ReadPrec a
readPrec
                  Fmpq -> ReadPrec Fmpq
forall a. a -> ReadPrec a
forall (m :: * -> *) a. Monad m => a -> m a
return (Fmpz
x Fmpz -> Fmpz -> Fmpq
forall a b. Quotient a b => b -> b -> a
// Fmpz
y))
           ReadPrec Fmpq -> ReadPrec Fmpq -> ReadPrec Fmpq
forall a. ReadPrec a -> ReadPrec a -> ReadPrec a
+++ (Int -> ReadPrec Fmpq -> ReadPrec Fmpq
forall a. Int -> ReadPrec a -> ReadPrec a
prec Int
up_prec (ReadPrec Fmpq -> ReadPrec Fmpq) -> ReadPrec Fmpq -> ReadPrec Fmpq
forall a b. (a -> b) -> a -> b
$ do
                  Fmpz
x <- ReadPrec Fmpz -> ReadPrec Fmpz
forall a. ReadPrec a -> ReadPrec a
step ReadPrec Fmpz
forall a. Read a => ReadPrec a
readPrec
                  Fmpq -> ReadPrec Fmpq
forall a. a -> ReadPrec a
forall (m :: * -> *) a. Monad m => a -> m a
return (Fmpz
x Fmpz -> Fmpz -> Fmpq
forall a b. Quotient a b => b -> b -> a
// Fmpz
1))
          where app_prec :: Int
app_prec = Int
10
                up_prec :: Int
up_prec = Int
5
       
instance Eq Fmpq where
  == :: Fmpq -> Fmpq -> Bool
(==) Fmpq
x Fmpq
y = (Fmpq, Bool) -> Bool
forall a b. (a, b) -> b
snd ((Fmpq, Bool) -> Bool) -> (Fmpq, Bool) -> Bool
forall a b. (a -> b) -> a -> b
$ (Fmpq, (Fmpq, Bool)) -> (Fmpq, Bool)
forall a b. (a, b) -> b
snd ((Fmpq, (Fmpq, Bool)) -> (Fmpq, Bool))
-> (Fmpq, (Fmpq, Bool)) -> (Fmpq, Bool)
forall a b. (a -> b) -> a -> b
$ IO (Fmpq, (Fmpq, Bool)) -> (Fmpq, (Fmpq, Bool))
forall a. IO a -> a
unsafePerformIO (IO (Fmpq, (Fmpq, Bool)) -> (Fmpq, (Fmpq, Bool)))
-> IO (Fmpq, (Fmpq, Bool)) -> (Fmpq, (Fmpq, Bool))
forall a b. (a -> b) -> a -> b
$ 
    Fmpq -> (Ptr CFmpq -> IO (Fmpq, Bool)) -> IO (Fmpq, (Fmpq, Bool))
forall {a}. Fmpq -> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
withFmpq Fmpq
x ((Ptr CFmpq -> IO (Fmpq, Bool)) -> IO (Fmpq, (Fmpq, Bool)))
-> (Ptr CFmpq -> IO (Fmpq, Bool)) -> IO (Fmpq, (Fmpq, Bool))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpq
x ->
      Fmpq -> (Ptr CFmpq -> IO Bool) -> IO (Fmpq, Bool)
forall {a}. Fmpq -> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
withFmpq Fmpq
y ((Ptr CFmpq -> IO Bool) -> IO (Fmpq, Bool))
-> (Ptr CFmpq -> IO Bool) -> IO (Fmpq, Bool)
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpq
y -> do
        CInt
result <- Ptr CFmpq -> Ptr CFmpq -> IO CInt
fmpq_equal Ptr CFmpq
x Ptr CFmpq
y
        Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> IO Bool) -> Bool -> IO Bool
forall a b. (a -> b) -> a -> b
$ CInt
result CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
== CInt
1

instance Ord Fmpq where
  compare :: Fmpq -> Fmpq -> Ordering
compare Fmpq
x Fmpq
y = (Fmpq, Ordering) -> Ordering
forall a b. (a, b) -> b
snd ((Fmpq, Ordering) -> Ordering) -> (Fmpq, Ordering) -> Ordering
forall a b. (a -> b) -> a -> b
$ (Fmpq, (Fmpq, Ordering)) -> (Fmpq, Ordering)
forall a b. (a, b) -> b
snd ((Fmpq, (Fmpq, Ordering)) -> (Fmpq, Ordering))
-> (Fmpq, (Fmpq, Ordering)) -> (Fmpq, Ordering)
forall a b. (a -> b) -> a -> b
$ IO (Fmpq, (Fmpq, Ordering)) -> (Fmpq, (Fmpq, Ordering))
forall a. IO a -> a
unsafePerformIO (IO (Fmpq, (Fmpq, Ordering)) -> (Fmpq, (Fmpq, Ordering)))
-> IO (Fmpq, (Fmpq, Ordering)) -> (Fmpq, (Fmpq, Ordering))
forall a b. (a -> b) -> a -> b
$ 
    Fmpq
-> (Ptr CFmpq -> IO (Fmpq, Ordering))
-> IO (Fmpq, (Fmpq, Ordering))
forall {a}. Fmpq -> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
withFmpq Fmpq
x ((Ptr CFmpq -> IO (Fmpq, Ordering)) -> IO (Fmpq, (Fmpq, Ordering)))
-> (Ptr CFmpq -> IO (Fmpq, Ordering))
-> IO (Fmpq, (Fmpq, Ordering))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpq
x ->
      Fmpq -> (Ptr CFmpq -> IO Ordering) -> IO (Fmpq, Ordering)
forall {a}. Fmpq -> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
withFmpq Fmpq
y ((Ptr CFmpq -> IO Ordering) -> IO (Fmpq, Ordering))
-> (Ptr CFmpq -> IO Ordering) -> IO (Fmpq, Ordering)
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpq
y -> do
        CInt
ord <- Ptr CFmpq -> Ptr CFmpq -> IO CInt
fmpq_cmp Ptr CFmpq
x Ptr CFmpq
y
        Ordering -> IO Ordering
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Ordering -> IO Ordering) -> Ordering -> IO Ordering
forall a b. (a -> b) -> a -> b
$ if CInt
ord CInt -> CInt -> Bool
forall a. Ord a => a -> a -> Bool
> CInt
0 then Ordering
GT else (if CInt
ord CInt -> CInt -> Bool
forall a. Ord a => a -> a -> Bool
< CInt
0 then Ordering
LT else Ordering
EQ)
    
instance Num Fmpq where
  {-# INLINE (+) #-}
  + :: Fmpq -> Fmpq -> Fmpq
(+) = (Ptr CFmpq -> Ptr CFmpq -> Ptr CFmpq -> IO ())
-> Fmpq -> Fmpq -> Fmpq
forall {a}.
(Ptr CFmpq -> Ptr CFmpq -> Ptr CFmpq -> IO a)
-> Fmpq -> Fmpq -> Fmpq
lift2 Ptr CFmpq -> Ptr CFmpq -> Ptr CFmpq -> IO ()
fmpq_add
  {-# INLINE (-) #-}
  (-) = (Ptr CFmpq -> Ptr CFmpq -> Ptr CFmpq -> IO ())
-> Fmpq -> Fmpq -> Fmpq
forall {a}.
(Ptr CFmpq -> Ptr CFmpq -> Ptr CFmpq -> IO a)
-> Fmpq -> Fmpq -> Fmpq
lift2 Ptr CFmpq -> Ptr CFmpq -> Ptr CFmpq -> IO ()
fmpq_sub
  {-# INLINE (*) #-}
  * :: Fmpq -> Fmpq -> Fmpq
(*) = (Ptr CFmpq -> Ptr CFmpq -> Ptr CFmpq -> IO ())
-> Fmpq -> Fmpq -> Fmpq
forall {a}.
(Ptr CFmpq -> Ptr CFmpq -> Ptr CFmpq -> IO a)
-> Fmpq -> Fmpq -> Fmpq
lift2 Ptr CFmpq -> Ptr CFmpq -> Ptr CFmpq -> IO ()
fmpq_mul
  negate :: Fmpq -> Fmpq
negate = (Ptr CFmpq -> Ptr CFmpq -> IO ()) -> Fmpq -> Fmpq
forall {a}. (Ptr CFmpq -> Ptr CFmpq -> IO a) -> Fmpq -> Fmpq
lift1 Ptr CFmpq -> Ptr CFmpq -> IO ()
fmpq_neg
  abs :: Fmpq -> Fmpq
abs    = (Ptr CFmpq -> Ptr CFmpq -> IO ()) -> Fmpq -> Fmpq
forall {a}. (Ptr CFmpq -> Ptr CFmpq -> IO a) -> Fmpq -> Fmpq
lift1 Ptr CFmpq -> Ptr CFmpq -> IO ()
fmpq_abs
  fromInteger :: Integer -> Fmpq
fromInteger Integer
x = IO Fmpq -> Fmpq
forall a. IO a -> a
unsafePerformIO (IO Fmpq -> Fmpq) -> IO Fmpq -> Fmpq
forall a b. (a -> b) -> a -> b
$ do
    let n :: Fmpz
n = Integer -> Fmpz
forall a. Num a => Integer -> a
fromInteger Integer
x 
        d :: Fmpz
d = Fmpz
1 :: Fmpz
    Fmpq
result <- IO Fmpq
newFmpq
    Fmpz
-> (Ptr CFmpz -> IO (Fmpz, (Fmpq, ())))
-> IO (Fmpz, (Fmpz, (Fmpq, ())))
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
n ((Ptr CFmpz -> IO (Fmpz, (Fmpq, ())))
 -> IO (Fmpz, (Fmpz, (Fmpq, ()))))
-> (Ptr CFmpz -> IO (Fmpz, (Fmpq, ())))
-> IO (Fmpz, (Fmpz, (Fmpq, ())))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
n ->
      Fmpz -> (Ptr CFmpz -> IO (Fmpq, ())) -> IO (Fmpz, (Fmpq, ()))
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
d ((Ptr CFmpz -> IO (Fmpq, ())) -> IO (Fmpz, (Fmpq, ())))
-> (Ptr CFmpz -> IO (Fmpq, ())) -> IO (Fmpz, (Fmpq, ()))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
d ->
        Fmpq -> (Ptr CFmpq -> IO ()) -> IO (Fmpq, ())
forall {a}. Fmpq -> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
withFmpq Fmpq
result ((Ptr CFmpq -> IO ()) -> IO (Fmpq, ()))
-> (Ptr CFmpq -> IO ()) -> IO (Fmpq, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpq
result -> do
          Ptr CFmpz -> IO ()
fmpz_one Ptr CFmpz
d
          Ptr CFmpq -> Ptr CFmpz -> Ptr CFmpz -> IO ()
fmpq_set_fmpz_frac Ptr CFmpq
result Ptr CFmpz
n Ptr CFmpz
d
          Ptr CFmpq -> IO ()
fmpq_canonicalise Ptr CFmpq
result
    Fmpq -> IO Fmpq
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Fmpq
result
  signum :: Fmpq -> Fmpq
signum = (Ptr CFmpq -> Ptr CFmpq -> IO ()) -> Fmpq -> Fmpq
forall {a}. (Ptr CFmpq -> Ptr CFmpq -> IO a) -> Fmpq -> Fmpq
lift1 Ptr CFmpq -> Ptr CFmpq -> IO ()
sgn where
    sgn :: Ptr CFmpq -> Ptr CFmpq -> IO ()
sgn Ptr CFmpq
result Ptr CFmpq
x = do
      CInt
s <- Ptr CFmpq -> IO CInt
fmpq_sgn Ptr CFmpq
x
      Ptr CFmpq -> CLong -> CULong -> IO ()
fmpq_set_si Ptr CFmpq
result (CInt -> CLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
s) CULong
1

instance Fractional Fmpq where
  / :: Fmpq -> Fmpq -> Fmpq
(/) = (Ptr CFmpq -> Ptr CFmpq -> Ptr CFmpq -> IO ())
-> Fmpq -> Fmpq -> Fmpq
forall {a}.
(Ptr CFmpq -> Ptr CFmpq -> Ptr CFmpq -> IO a)
-> Fmpq -> Fmpq -> Fmpq
lift2 Ptr CFmpq -> Ptr CFmpq -> Ptr CFmpq -> IO ()
fmpq_div
  recip :: Fmpq -> Fmpq
recip = (Ptr CFmpq -> Ptr CFmpq -> IO ()) -> Fmpq -> Fmpq
forall {a}. (Ptr CFmpq -> Ptr CFmpq -> IO a) -> Fmpq -> Fmpq
lift1 Ptr CFmpq -> Ptr CFmpq -> IO ()
fmpq_inv
  fromRational :: Rational -> Fmpq
fromRational Rational
x = IO Fmpq -> Fmpq
forall a. IO a -> a
unsafePerformIO (IO Fmpq -> Fmpq) -> IO Fmpq -> Fmpq
forall a b. (a -> b) -> a -> b
$ do
    Fmpq
result <- IO Fmpq
newFmpq
    let n :: Fmpz
n = Integer -> Fmpz
forall a. Num a => Integer -> a
fromInteger (Integer -> Fmpz) -> Integer -> Fmpz
forall a b. (a -> b) -> a -> b
$ Rational -> Integer
forall a. Ratio a -> a
Ratio.numerator Rational
x
        d :: Fmpz
d = Integer -> Fmpz
forall a. Num a => Integer -> a
fromInteger (Integer -> Fmpz) -> Integer -> Fmpz
forall a b. (a -> b) -> a -> b
$ Rational -> Integer
forall a. Ratio a -> a
Ratio.denominator Rational
x
    Fmpz
-> (Ptr CFmpz -> IO (Fmpz, (Fmpq, ())))
-> IO (Fmpz, (Fmpz, (Fmpq, ())))
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
n ((Ptr CFmpz -> IO (Fmpz, (Fmpq, ())))
 -> IO (Fmpz, (Fmpz, (Fmpq, ()))))
-> (Ptr CFmpz -> IO (Fmpz, (Fmpq, ())))
-> IO (Fmpz, (Fmpz, (Fmpq, ())))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
n ->
      Fmpz -> (Ptr CFmpz -> IO (Fmpq, ())) -> IO (Fmpz, (Fmpq, ()))
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
d ((Ptr CFmpz -> IO (Fmpq, ())) -> IO (Fmpz, (Fmpq, ())))
-> (Ptr CFmpz -> IO (Fmpq, ())) -> IO (Fmpz, (Fmpq, ()))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
d ->
        Fmpq -> (Ptr CFmpq -> IO ()) -> IO (Fmpq, ())
forall {a}. Fmpq -> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
withFmpq Fmpq
result ((Ptr CFmpq -> IO ()) -> IO (Fmpq, ()))
-> (Ptr CFmpq -> IO ()) -> IO (Fmpq, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpq
result -> do
          Ptr CFmpq -> Ptr CFmpz -> Ptr CFmpz -> IO ()
fmpq_set_fmpz_frac Ptr CFmpq
result Ptr CFmpz
n Ptr CFmpz
d
          Ptr CFmpq -> IO ()
fmpq_canonicalise Ptr CFmpq
result
    Fmpq -> IO Fmpq
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Fmpq
result

instance Real Fmpq where
  toRational :: Fmpq -> Rational
toRational Fmpq
x = IO Rational -> Rational
forall a. IO a -> a
unsafePerformIO (IO Rational -> Rational) -> IO Rational -> Rational
forall a b. (a -> b) -> a -> b
$ do
    Fmpz
p <- IO Fmpz
newFmpz
    Fmpz
q <- IO Fmpz
newFmpz
    Fmpq
-> (Ptr CFmpq -> IO (Fmpz, (Fmpz, ())))
-> IO (Fmpq, (Fmpz, (Fmpz, ())))
forall {a}. Fmpq -> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
withFmpq Fmpq
x ((Ptr CFmpq -> IO (Fmpz, (Fmpz, ())))
 -> IO (Fmpq, (Fmpz, (Fmpz, ()))))
-> (Ptr CFmpq -> IO (Fmpz, (Fmpz, ())))
-> IO (Fmpq, (Fmpz, (Fmpz, ())))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpq
x -> do
      Fmpz -> (Ptr CFmpz -> IO (Fmpz, ())) -> IO (Fmpz, (Fmpz, ()))
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
p ((Ptr CFmpz -> IO (Fmpz, ())) -> IO (Fmpz, (Fmpz, ())))
-> (Ptr CFmpz -> IO (Fmpz, ())) -> IO (Fmpz, (Fmpz, ()))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
p -> do
        Fmpz -> (Ptr CFmpz -> IO ()) -> IO (Fmpz, ())
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
q ((Ptr CFmpz -> IO ()) -> IO (Fmpz, ()))
-> (Ptr CFmpz -> IO ()) -> IO (Fmpz, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
q -> do
          Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpq -> IO ()
fmpq_get_fmpz_frac Ptr CFmpz
p Ptr CFmpz
q Ptr CFmpq
x
    Rational -> IO Rational
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Rational -> IO Rational) -> Rational -> IO Rational
forall a b. (a -> b) -> a -> b
$ (Fmpz -> Integer
forall a. Integral a => a -> Integer
toInteger Fmpz
p) Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% (Fmpz -> Integer
forall a. Integral a => a -> Integer
toInteger Fmpz
q)

instance RealFrac Fmpq where
  properFraction :: forall b. Integral b => Fmpq -> (b, Fmpq)
properFraction Fmpq
x =  IO (b, Fmpq) -> (b, Fmpq)
forall a. IO a -> a
unsafePerformIO (IO (b, Fmpq) -> (b, Fmpq)) -> IO (b, Fmpq) -> (b, Fmpq)
forall a b. (a -> b) -> a -> b
$ do
    Fmpz
p <- IO Fmpz
newFmpz
    Fmpz
q <- IO Fmpz
newFmpz
    Fmpq
r <- IO Fmpq
newFmpq
    Fmpq
-> (Ptr CFmpq -> IO (Fmpz, (Fmpz, (Fmpq, (Fmpz, ())))))
-> IO (Fmpq, (Fmpz, (Fmpz, (Fmpq, (Fmpz, ())))))
forall {a}. Fmpq -> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
withFmpq Fmpq
x ((Ptr CFmpq -> IO (Fmpz, (Fmpz, (Fmpq, (Fmpz, ())))))
 -> IO (Fmpq, (Fmpz, (Fmpz, (Fmpq, (Fmpz, ()))))))
-> (Ptr CFmpq -> IO (Fmpz, (Fmpz, (Fmpq, (Fmpz, ())))))
-> IO (Fmpq, (Fmpz, (Fmpz, (Fmpq, (Fmpz, ())))))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpq
x -> do
      Fmpz
-> (Ptr CFmpz -> IO (Fmpz, (Fmpq, (Fmpz, ()))))
-> IO (Fmpz, (Fmpz, (Fmpq, (Fmpz, ()))))
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
p ((Ptr CFmpz -> IO (Fmpz, (Fmpq, (Fmpz, ()))))
 -> IO (Fmpz, (Fmpz, (Fmpq, (Fmpz, ())))))
-> (Ptr CFmpz -> IO (Fmpz, (Fmpq, (Fmpz, ()))))
-> IO (Fmpz, (Fmpz, (Fmpq, (Fmpz, ()))))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
p -> do
        Fmpz
-> (Ptr CFmpz -> IO (Fmpq, (Fmpz, ())))
-> IO (Fmpz, (Fmpq, (Fmpz, ())))
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
q ((Ptr CFmpz -> IO (Fmpq, (Fmpz, ())))
 -> IO (Fmpz, (Fmpq, (Fmpz, ()))))
-> (Ptr CFmpz -> IO (Fmpq, (Fmpz, ())))
-> IO (Fmpz, (Fmpq, (Fmpz, ())))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
q -> do
          Fmpq -> (Ptr CFmpq -> IO (Fmpz, ())) -> IO (Fmpq, (Fmpz, ()))
forall {a}. Fmpq -> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
withFmpq Fmpq
r ((Ptr CFmpq -> IO (Fmpz, ())) -> IO (Fmpq, (Fmpz, ())))
-> (Ptr CFmpq -> IO (Fmpz, ())) -> IO (Fmpq, (Fmpz, ()))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpq
r -> do
            (Ptr CFmpz -> IO ()) -> IO (Fmpz, ())
forall {a}. (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withNewFmpz ((Ptr CFmpz -> IO ()) -> IO (Fmpz, ()))
-> (Ptr CFmpz -> IO ()) -> IO (Fmpz, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
tmp -> do
              Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpq -> IO ()
fmpq_get_fmpz_frac Ptr CFmpz
p Ptr CFmpz
q Ptr CFmpq
x
              Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> IO ()
fmpz_tdiv_qr Ptr CFmpz
p Ptr CFmpz
tmp Ptr CFmpz
p Ptr CFmpz
q
              Ptr CFmpq -> Ptr CFmpz -> Ptr CFmpz -> IO ()
fmpq_set_fmpz_frac Ptr CFmpq
r Ptr CFmpz
tmp Ptr CFmpz
q
    (b, Fmpq) -> IO (b, Fmpq)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Fmpz -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral Fmpz
p, Fmpq
r)
   
lift1 :: (Ptr CFmpq -> Ptr CFmpq -> IO a) -> Fmpq -> Fmpq
lift1 Ptr CFmpq -> Ptr CFmpq -> IO a
f Fmpq
x = (Fmpq, (Fmpq, a)) -> Fmpq
forall a b. (a, b) -> a
fst ((Fmpq, (Fmpq, a)) -> Fmpq) -> (Fmpq, (Fmpq, a)) -> Fmpq
forall a b. (a -> b) -> a -> b
$ IO (Fmpq, (Fmpq, a)) -> (Fmpq, (Fmpq, a))
forall a. IO a -> a
unsafePerformIO (IO (Fmpq, (Fmpq, a)) -> (Fmpq, (Fmpq, a)))
-> IO (Fmpq, (Fmpq, a)) -> (Fmpq, (Fmpq, a))
forall a b. (a -> b) -> a -> b
$ 
  (Ptr CFmpq -> IO (Fmpq, a)) -> IO (Fmpq, (Fmpq, a))
forall {a}. (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
withNewFmpq ((Ptr CFmpq -> IO (Fmpq, a)) -> IO (Fmpq, (Fmpq, a)))
-> (Ptr CFmpq -> IO (Fmpq, a)) -> IO (Fmpq, (Fmpq, a))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpq
result -> 
    Fmpq -> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
forall {a}. Fmpq -> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
withFmpq Fmpq
x ((Ptr CFmpq -> IO a) -> IO (Fmpq, a))
-> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpq
x ->
      Ptr CFmpq -> Ptr CFmpq -> IO a
f Ptr CFmpq
result Ptr CFmpq
x
  
lift2 :: (Ptr CFmpq -> Ptr CFmpq -> Ptr CFmpq -> IO a)
-> Fmpq -> Fmpq -> Fmpq
lift2 Ptr CFmpq -> Ptr CFmpq -> Ptr CFmpq -> IO a
f Fmpq
x Fmpq
y = (Fmpq, (Fmpq, (Fmpq, a))) -> Fmpq
forall a b. (a, b) -> a
fst ((Fmpq, (Fmpq, (Fmpq, a))) -> Fmpq)
-> (Fmpq, (Fmpq, (Fmpq, a))) -> Fmpq
forall a b. (a -> b) -> a -> b
$ IO (Fmpq, (Fmpq, (Fmpq, a))) -> (Fmpq, (Fmpq, (Fmpq, a)))
forall a. IO a -> a
unsafePerformIO (IO (Fmpq, (Fmpq, (Fmpq, a))) -> (Fmpq, (Fmpq, (Fmpq, a))))
-> IO (Fmpq, (Fmpq, (Fmpq, a))) -> (Fmpq, (Fmpq, (Fmpq, a)))
forall a b. (a -> b) -> a -> b
$ 
  (Ptr CFmpq -> IO (Fmpq, (Fmpq, a))) -> IO (Fmpq, (Fmpq, (Fmpq, a)))
forall {a}. (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
withNewFmpq ((Ptr CFmpq -> IO (Fmpq, (Fmpq, a)))
 -> IO (Fmpq, (Fmpq, (Fmpq, a))))
-> (Ptr CFmpq -> IO (Fmpq, (Fmpq, a)))
-> IO (Fmpq, (Fmpq, (Fmpq, a)))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpq
result ->
    Fmpq -> (Ptr CFmpq -> IO (Fmpq, a)) -> IO (Fmpq, (Fmpq, a))
forall {a}. Fmpq -> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
withFmpq Fmpq
x ((Ptr CFmpq -> IO (Fmpq, a)) -> IO (Fmpq, (Fmpq, a)))
-> (Ptr CFmpq -> IO (Fmpq, a)) -> IO (Fmpq, (Fmpq, a))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpq
x ->
      Fmpq -> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
forall {a}. Fmpq -> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
withFmpq Fmpq
y ((Ptr CFmpq -> IO a) -> IO (Fmpq, a))
-> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpq
y ->
        Ptr CFmpq -> Ptr CFmpq -> Ptr CFmpq -> IO a
f Ptr CFmpq
result Ptr CFmpq
x Ptr CFmpq
y