module Data.Number.Flint.Fmpz.Instances (
  Fmpz (..)
, UFD (..)
) where

import Test.QuickCheck
import System.IO.Unsafe
import Control.Monad

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 Foreign.Marshal.Array (advancePtr)

import Data.Number.Flint.Fmpz
import Data.Number.Flint.Fmpz.Factor
import Data.Number.Flint.UFD

instance Show Fmpz where
  show :: Fmpz -> String
show Fmpz
x = (Fmpz, String) -> String
forall a b. (a, b) -> b
snd ((Fmpz, String) -> String) -> (Fmpz, String) -> String
forall a b. (a -> b) -> a -> b
$ IO (Fmpz, String) -> (Fmpz, String)
forall a. IO a -> a
unsafePerformIO (IO (Fmpz, String) -> (Fmpz, String))
-> IO (Fmpz, String) -> (Fmpz, String)
forall a b. (a -> b) -> a -> b
$ do
    let base :: CInt
base = CInt
10 :: CInt
    Fmpz -> (Ptr CFmpz -> IO String) -> IO (Fmpz, String)
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
x ((Ptr CFmpz -> IO String) -> IO (Fmpz, String))
-> (Ptr CFmpz -> IO String) -> IO (Fmpz, String)
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
x -> do
      CString
cString <- CString -> CInt -> Ptr CFmpz -> IO CString
fmpz_get_str CString
forall a. Ptr a
nullPtr CInt
base Ptr CFmpz
x
      String
result <- CString -> IO String
peekCString CString
cString
      CString -> IO ()
forall a. Ptr a -> IO ()
free CString
cString
      String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return String
result

instance Read Fmpz where
  readsPrec :: Int -> ReadS Fmpz
readsPrec Int
d String
s = IO [(Fmpz, String)] -> [(Fmpz, String)]
forall a. IO a -> a
unsafePerformIO (IO [(Fmpz, String)] -> [(Fmpz, String)])
-> IO [(Fmpz, String)] -> [(Fmpz, String)]
forall a b. (a -> b) -> a -> b
$ do
    let n :: Integer
        [(Integer
n, String
r)] = Int -> ReadS Integer
forall a. Read a => Int -> ReadS a
readsPrec Int
d String
s
    Fmpz
result <- IO Fmpz
newFmpz
    (Fmpz
_, CInt
flag) <- Fmpz -> (Ptr CFmpz -> IO CInt) -> IO (Fmpz, CInt)
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
result ((Ptr CFmpz -> IO CInt) -> IO (Fmpz, CInt))
-> (Ptr CFmpz -> IO CInt) -> IO (Fmpz, CInt)
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
result -> 
      String -> (CString -> IO CInt) -> IO CInt
forall a. String -> (CString -> IO a) -> IO a
withCString (Integer -> String
forall a. Show a => a -> String
show Integer
n) ((CString -> IO CInt) -> IO CInt)
-> (CString -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \CString
s -> 
        Ptr CFmpz -> CString -> CInt -> IO CInt
fmpz_set_str Ptr CFmpz
result CString
s CInt
10
    if CInt
flag CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
== CInt
0 then 
      [(Fmpz, String)] -> IO [(Fmpz, String)]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return [(Fmpz
result, String
r)]
    else
      [(Fmpz, String)] -> IO [(Fmpz, String)]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return []

instance Eq Fmpz where
  == :: Fmpz -> Fmpz -> Bool
(==) Fmpz
x Fmpz
y = (Fmpz, Bool) -> Bool
forall a b. (a, b) -> b
snd ((Fmpz, Bool) -> Bool) -> (Fmpz, Bool) -> Bool
forall a b. (a -> b) -> a -> b
$ (Fmpz, (Fmpz, Bool)) -> (Fmpz, Bool)
forall a b. (a, b) -> b
snd ((Fmpz, (Fmpz, Bool)) -> (Fmpz, Bool))
-> (Fmpz, (Fmpz, Bool)) -> (Fmpz, Bool)
forall a b. (a -> b) -> a -> b
$ IO (Fmpz, (Fmpz, Bool)) -> (Fmpz, (Fmpz, Bool))
forall a. IO a -> a
unsafePerformIO (IO (Fmpz, (Fmpz, Bool)) -> (Fmpz, (Fmpz, Bool)))
-> IO (Fmpz, (Fmpz, Bool)) -> (Fmpz, (Fmpz, Bool))
forall a b. (a -> b) -> a -> b
$ 
    Fmpz -> (Ptr CFmpz -> IO (Fmpz, Bool)) -> IO (Fmpz, (Fmpz, Bool))
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
x ((Ptr CFmpz -> IO (Fmpz, Bool)) -> IO (Fmpz, (Fmpz, Bool)))
-> (Ptr CFmpz -> IO (Fmpz, Bool)) -> IO (Fmpz, (Fmpz, Bool))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
x ->
      Fmpz -> (Ptr CFmpz -> IO Bool) -> IO (Fmpz, Bool)
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
y ((Ptr CFmpz -> IO Bool) -> IO (Fmpz, Bool))
-> (Ptr CFmpz -> IO Bool) -> IO (Fmpz, Bool)
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
y -> do
        CInt
result <- Ptr CFmpz -> Ptr CFmpz -> IO CInt
fmpz_equal Ptr CFmpz
x Ptr CFmpz
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 Fmpz where
  compare :: Fmpz -> Fmpz -> Ordering
compare Fmpz
x Fmpz
y = (Fmpz, Ordering) -> Ordering
forall a b. (a, b) -> b
snd ((Fmpz, Ordering) -> Ordering) -> (Fmpz, Ordering) -> Ordering
forall a b. (a -> b) -> a -> b
$ (Fmpz, (Fmpz, Ordering)) -> (Fmpz, Ordering)
forall a b. (a, b) -> b
snd ((Fmpz, (Fmpz, Ordering)) -> (Fmpz, Ordering))
-> (Fmpz, (Fmpz, Ordering)) -> (Fmpz, Ordering)
forall a b. (a -> b) -> a -> b
$ IO (Fmpz, (Fmpz, Ordering)) -> (Fmpz, (Fmpz, Ordering))
forall a. IO a -> a
unsafePerformIO (IO (Fmpz, (Fmpz, Ordering)) -> (Fmpz, (Fmpz, Ordering)))
-> IO (Fmpz, (Fmpz, Ordering)) -> (Fmpz, (Fmpz, Ordering))
forall a b. (a -> b) -> a -> b
$
    Fmpz
-> (Ptr CFmpz -> IO (Fmpz, Ordering))
-> IO (Fmpz, (Fmpz, Ordering))
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
x ((Ptr CFmpz -> IO (Fmpz, Ordering)) -> IO (Fmpz, (Fmpz, Ordering)))
-> (Ptr CFmpz -> IO (Fmpz, Ordering))
-> IO (Fmpz, (Fmpz, Ordering))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
x ->
      Fmpz -> (Ptr CFmpz -> IO Ordering) -> IO (Fmpz, Ordering)
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
y ((Ptr CFmpz -> IO Ordering) -> IO (Fmpz, Ordering))
-> (Ptr CFmpz -> IO Ordering) -> IO (Fmpz, Ordering)
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
y -> do
        CInt
ord <- Ptr CFmpz -> Ptr CFmpz -> IO CInt
fmpz_cmp Ptr CFmpz
x Ptr CFmpz
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 Enum Fmpz where
  toEnum :: Int -> Fmpz
toEnum = Integer -> Fmpz
forall a. Num a => Integer -> a
fromInteger (Integer -> Fmpz) -> (Int -> Integer) -> Int -> Fmpz
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  fromEnum :: Fmpz -> Int
fromEnum = Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> Int) -> (Fmpz -> Integer) -> Fmpz -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fmpz -> Integer
forall a. Integral a => a -> Integer
toInteger
  succ :: Fmpz -> Fmpz
succ Fmpz
x = IO Fmpz -> Fmpz
forall a. IO a -> a
unsafePerformIO (IO Fmpz -> Fmpz) -> IO Fmpz -> Fmpz
forall a b. (a -> b) -> a -> b
$ do
    Fmpz
y <- IO Fmpz
newFmpz 
    Fmpz -> (Ptr CFmpz -> IO (Fmpz, ())) -> IO (Fmpz, (Fmpz, ()))
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
x ((Ptr CFmpz -> IO (Fmpz, ())) -> IO (Fmpz, (Fmpz, ())))
-> (Ptr CFmpz -> IO (Fmpz, ())) -> IO (Fmpz, (Fmpz, ()))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
x -> Fmpz -> (Ptr CFmpz -> IO ()) -> IO (Fmpz, ())
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
y ((Ptr CFmpz -> IO ()) -> IO (Fmpz, ()))
-> (Ptr CFmpz -> IO ()) -> IO (Fmpz, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
y -> Ptr CFmpz -> Ptr CFmpz -> CULong -> IO ()
fmpz_add_ui Ptr CFmpz
y Ptr CFmpz
x CULong
1
    Fmpz -> IO Fmpz
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Fmpz
y
    
instance Num Fmpz where
  {-# INLINE (+) #-}
  + :: Fmpz -> Fmpz -> Fmpz
(+) = (Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> IO ())
-> Fmpz -> Fmpz -> Fmpz
forall {a}.
(Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> IO a)
-> Fmpz -> Fmpz -> Fmpz
lift2 Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> IO ()
fmpz_add
  {-# INLINE (-) #-}
  (-) = (Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> IO ())
-> Fmpz -> Fmpz -> Fmpz
forall {a}.
(Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> IO a)
-> Fmpz -> Fmpz -> Fmpz
lift2 Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> IO ()
fmpz_sub
  {-# INLINE (*) #-}
  * :: Fmpz -> Fmpz -> Fmpz
(*) = (Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> IO ())
-> Fmpz -> Fmpz -> Fmpz
forall {a}.
(Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> IO a)
-> Fmpz -> Fmpz -> Fmpz
lift2 Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> IO ()
fmpz_mul
  negate :: Fmpz -> Fmpz
negate = (Ptr CFmpz -> Ptr CFmpz -> IO ()) -> Fmpz -> Fmpz
forall {a}. (Ptr CFmpz -> Ptr CFmpz -> IO a) -> Fmpz -> Fmpz
lift1 Ptr CFmpz -> Ptr CFmpz -> IO ()
fmpz_neg
  abs :: Fmpz -> Fmpz
abs    = (Ptr CFmpz -> Ptr CFmpz -> IO ()) -> Fmpz -> Fmpz
forall {a}. (Ptr CFmpz -> Ptr CFmpz -> IO a) -> Fmpz -> Fmpz
lift1 Ptr CFmpz -> Ptr CFmpz -> IO ()
fmpz_abs
  fromInteger :: Integer -> Fmpz
fromInteger Integer
x = String -> Fmpz
forall a. Read a => String -> a
read (Integer -> String
forall a. Show a => a -> String
show Integer
x) :: Fmpz
  signum :: Fmpz -> Fmpz
signum = (Ptr CFmpz -> Ptr CFmpz -> IO ()) -> Fmpz -> Fmpz
forall {a}. (Ptr CFmpz -> Ptr CFmpz -> IO a) -> Fmpz -> Fmpz
lift1 Ptr CFmpz -> Ptr CFmpz -> IO ()
sgn where
    sgn :: Ptr CFmpz -> Ptr CFmpz -> IO ()
sgn Ptr CFmpz
result Ptr CFmpz
x = do
      CInt
s <- Ptr CFmpz -> IO CInt
fmpz_sgn Ptr CFmpz
x
      Ptr CFmpz -> CLong -> IO ()
fmpz_set_si Ptr CFmpz
result (CInt -> CLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
s)

instance Real Fmpz where
  toRational :: Fmpz -> Rational
toRational Fmpz
x = (Fmpz -> Integer
forall a. Integral a => a -> Integer
toInteger Fmpz
x) Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% Integer
1

instance Integral Fmpz where
  mod :: Fmpz -> Fmpz -> Fmpz
mod Fmpz
x Fmpz
y = IO Fmpz -> Fmpz
forall a. IO a -> a
unsafePerformIO (IO Fmpz -> Fmpz) -> IO Fmpz -> Fmpz
forall a b. (a -> b) -> a -> b
$ do
    Fmpz
result <- IO Fmpz
newFmpz
    Fmpz
-> (Ptr CFmpz -> IO (Fmpz, (Fmpz, ())))
-> IO (Fmpz, (Fmpz, (Fmpz, ())))
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
result ((Ptr CFmpz -> IO (Fmpz, (Fmpz, ())))
 -> IO (Fmpz, (Fmpz, (Fmpz, ()))))
-> (Ptr CFmpz -> IO (Fmpz, (Fmpz, ())))
-> IO (Fmpz, (Fmpz, (Fmpz, ())))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
result ->
      Fmpz -> (Ptr CFmpz -> IO (Fmpz, ())) -> IO (Fmpz, (Fmpz, ()))
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
x ((Ptr CFmpz -> IO (Fmpz, ())) -> IO (Fmpz, (Fmpz, ())))
-> (Ptr CFmpz -> IO (Fmpz, ())) -> IO (Fmpz, (Fmpz, ()))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
x ->
        Fmpz -> (Ptr CFmpz -> IO ()) -> IO (Fmpz, ())
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
y ((Ptr CFmpz -> IO ()) -> IO (Fmpz, ()))
-> (Ptr CFmpz -> IO ()) -> IO (Fmpz, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
y -> Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> IO ()
fmpz_mod Ptr CFmpz
result Ptr CFmpz
x Ptr CFmpz
y
    Fmpz -> IO Fmpz
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Fmpz
result
  quotRem :: Fmpz -> Fmpz -> (Fmpz, Fmpz)
quotRem Fmpz
x Fmpz
y = IO (Fmpz, Fmpz) -> (Fmpz, Fmpz)
forall a. IO a -> a
unsafePerformIO (IO (Fmpz, Fmpz) -> (Fmpz, Fmpz))
-> IO (Fmpz, Fmpz) -> (Fmpz, Fmpz)
forall a b. (a -> b) -> a -> b
$ do
    Fmpz
quot <- IO Fmpz
newFmpz
    Fmpz
rem <- IO Fmpz
newFmpz
    Fmpz
-> (Ptr CFmpz -> IO (Fmpz, (Fmpz, (Fmpz, ()))))
-> IO (Fmpz, (Fmpz, (Fmpz, (Fmpz, ()))))
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
x ((Ptr CFmpz -> IO (Fmpz, (Fmpz, (Fmpz, ()))))
 -> IO (Fmpz, (Fmpz, (Fmpz, (Fmpz, ())))))
-> (Ptr CFmpz -> IO (Fmpz, (Fmpz, (Fmpz, ()))))
-> IO (Fmpz, (Fmpz, (Fmpz, (Fmpz, ()))))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
x -> 
      Fmpz
-> (Ptr CFmpz -> IO (Fmpz, (Fmpz, ())))
-> IO (Fmpz, (Fmpz, (Fmpz, ())))
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
y ((Ptr CFmpz -> IO (Fmpz, (Fmpz, ())))
 -> IO (Fmpz, (Fmpz, (Fmpz, ()))))
-> (Ptr CFmpz -> IO (Fmpz, (Fmpz, ())))
-> IO (Fmpz, (Fmpz, (Fmpz, ())))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
y -> 
        Fmpz -> (Ptr CFmpz -> IO (Fmpz, ())) -> IO (Fmpz, (Fmpz, ()))
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
quot ((Ptr CFmpz -> IO (Fmpz, ())) -> IO (Fmpz, (Fmpz, ())))
-> (Ptr CFmpz -> IO (Fmpz, ())) -> IO (Fmpz, (Fmpz, ()))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
quot -> 
          Fmpz -> (Ptr CFmpz -> IO ()) -> IO (Fmpz, ())
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
rem ((Ptr CFmpz -> IO ()) -> IO (Fmpz, ()))
-> (Ptr CFmpz -> IO ()) -> IO (Fmpz, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
rem -> 
            Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> IO ()
fmpz_tdiv_qr Ptr CFmpz
quot Ptr CFmpz
rem Ptr CFmpz
x Ptr CFmpz
y
    (Fmpz, Fmpz) -> IO (Fmpz, Fmpz)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Fmpz
quot, Fmpz
rem)
  toInteger :: Fmpz -> Integer
toInteger Fmpz
x = String -> Integer
forall a. Read a => String -> a
read (Fmpz -> String
forall a. Show a => a -> String
show Fmpz
x) :: Integer

instance UFD Fmpz where
  factor :: Fmpz -> [(Fmpz, Int)]
factor Fmpz
x = (FmpzFactor, [(Fmpz, Int)]) -> [(Fmpz, Int)]
forall a b. (a, b) -> b
snd ((FmpzFactor, [(Fmpz, Int)]) -> [(Fmpz, Int)])
-> (FmpzFactor, [(Fmpz, Int)]) -> [(Fmpz, Int)]
forall a b. (a -> b) -> a -> b
$ (Fmpz, (FmpzFactor, [(Fmpz, Int)])) -> (FmpzFactor, [(Fmpz, Int)])
forall a b. (a, b) -> b
snd ((Fmpz, (FmpzFactor, [(Fmpz, Int)]))
 -> (FmpzFactor, [(Fmpz, Int)]))
-> (Fmpz, (FmpzFactor, [(Fmpz, Int)]))
-> (FmpzFactor, [(Fmpz, Int)])
forall a b. (a -> b) -> a -> b
$ IO (Fmpz, (FmpzFactor, [(Fmpz, Int)]))
-> (Fmpz, (FmpzFactor, [(Fmpz, Int)]))
forall a. IO a -> a
unsafePerformIO (IO (Fmpz, (FmpzFactor, [(Fmpz, Int)]))
 -> (Fmpz, (FmpzFactor, [(Fmpz, Int)])))
-> IO (Fmpz, (FmpzFactor, [(Fmpz, Int)]))
-> (Fmpz, (FmpzFactor, [(Fmpz, Int)]))
forall a b. (a -> b) -> a -> b
$
    Fmpz
-> (Ptr CFmpz -> IO (FmpzFactor, [(Fmpz, Int)]))
-> IO (Fmpz, (FmpzFactor, [(Fmpz, Int)]))
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
x ((Ptr CFmpz -> IO (FmpzFactor, [(Fmpz, Int)]))
 -> IO (Fmpz, (FmpzFactor, [(Fmpz, Int)])))
-> (Ptr CFmpz -> IO (FmpzFactor, [(Fmpz, Int)]))
-> IO (Fmpz, (FmpzFactor, [(Fmpz, Int)]))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
y -> do
      CInt
is_one <- Ptr CFmpz -> IO CInt
fmpz_is_one Ptr CFmpz
y
      FmpzFactor
f <- IO FmpzFactor
newFmpzFactor
      FmpzFactor
-> (Ptr CFmpzFactor -> IO [(Fmpz, Int)])
-> IO (FmpzFactor, [(Fmpz, Int)])
forall {a}.
FmpzFactor -> (Ptr CFmpzFactor -> IO a) -> IO (FmpzFactor, a)
withFmpzFactor FmpzFactor
f ((Ptr CFmpzFactor -> IO [(Fmpz, Int)])
 -> IO (FmpzFactor, [(Fmpz, Int)]))
-> (Ptr CFmpzFactor -> IO [(Fmpz, Int)])
-> IO (FmpzFactor, [(Fmpz, Int)])
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzFactor
f -> do
        if Bool -> Bool
not (CInt
is_one CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
== CInt
1) then do
          Ptr CFmpzFactor -> Ptr CFmpz -> IO ()
fmpz_factor Ptr CFmpzFactor
f Ptr CFmpz
y
          CFmpzFactor CInt
s Ptr CFmpz
d Ptr CULong
e CLong
_ CLong
n <- Ptr CFmpzFactor -> IO CFmpzFactor
forall a. Storable a => Ptr a -> IO a
peek Ptr CFmpzFactor
f
          [(Fmpz, Int)]
result <- [Int] -> (Int -> IO (Fmpz, Int)) -> IO [(Fmpz, Int)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [Int
0 .. CLong -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CLong
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1] ((Int -> IO (Fmpz, Int)) -> IO [(Fmpz, Int)])
-> (Int -> IO (Fmpz, Int)) -> IO [(Fmpz, Int)]
forall a b. (a -> b) -> a -> b
$ \Int
j -> do
            Fmpz
f <- IO Fmpz
newFmpz
            CULong
m <- Ptr CULong -> IO CULong
forall a. Storable a => Ptr a -> IO a
peek (Ptr CULong
e Ptr CULong -> Int -> Ptr CULong
forall a. Storable a => Ptr a -> Int -> Ptr a
`advancePtr` Int
j)
            Fmpz -> (Ptr CFmpz -> IO ()) -> IO (Fmpz, ())
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
f ((Ptr CFmpz -> IO ()) -> IO (Fmpz, ()))
-> (Ptr CFmpz -> IO ()) -> IO (Fmpz, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
f -> Ptr CFmpz -> Ptr CFmpz -> IO ()
fmpz_set Ptr CFmpz
f (Ptr CFmpz
d Ptr CFmpz -> Int -> Ptr CFmpz
forall a. Storable a => Ptr a -> Int -> Ptr a
`advancePtr` Int
j)
            (Fmpz, Int) -> IO (Fmpz, Int)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Fmpz
f, CULong -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CULong
m)
          [(Fmpz, Int)] -> IO [(Fmpz, Int)]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([(Fmpz, Int)] -> IO [(Fmpz, Int)])
-> [(Fmpz, Int)] -> IO [(Fmpz, Int)]
forall a b. (a -> b) -> a -> b
$ if CInt
s CInt -> CInt -> Bool
forall a. Ord a => a -> a -> Bool
< CInt
1 then (-Fmpz
1, Int
1) (Fmpz, Int) -> [(Fmpz, Int)] -> [(Fmpz, Int)]
forall a. a -> [a] -> [a]
: [(Fmpz, Int)]
result else [(Fmpz, Int)]
result
        else do
          [(Fmpz, Int)] -> IO [(Fmpz, Int)]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return [(Fmpz
1, Int
1)]

instance Arbitrary Fmpz where
  arbitrary :: Gen Fmpz
arbitrary = do
    Integer
x <- Gen Integer
forall a. Arbitrary a => Gen a
arbitrary
    Fmpz -> Gen Fmpz
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return (Fmpz -> Gen Fmpz) -> Fmpz -> Gen Fmpz
forall a b. (a -> b) -> a -> b
$ Integer -> Fmpz
forall a. Num a => Integer -> a
fromInteger Integer
x
      
lift1 :: (Ptr CFmpz -> Ptr CFmpz -> IO a) -> Fmpz -> Fmpz
lift1 Ptr CFmpz -> Ptr CFmpz -> IO a
f Fmpz
x = IO Fmpz -> Fmpz
forall a. IO a -> a
unsafePerformIO (IO Fmpz -> Fmpz) -> IO Fmpz -> Fmpz
forall a b. (a -> b) -> a -> b
$ do
  Fmpz
z <- IO Fmpz
newFmpz
  Fmpz -> (Ptr CFmpz -> IO (Fmpz, a)) -> IO (Fmpz, (Fmpz, a))
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
x ((Ptr CFmpz -> IO (Fmpz, a)) -> IO (Fmpz, (Fmpz, a)))
-> (Ptr CFmpz -> IO (Fmpz, a)) -> IO (Fmpz, (Fmpz, a))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
x ->
    Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
z ((Ptr CFmpz -> IO a) -> IO (Fmpz, a))
-> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
z -> Ptr CFmpz -> Ptr CFmpz -> IO a
f Ptr CFmpz
z Ptr CFmpz
x
  Fmpz -> IO Fmpz
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Fmpz
z
  
lift2 :: (Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> IO a)
-> Fmpz -> Fmpz -> Fmpz
lift2 Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> IO a
f Fmpz
x Fmpz
y = IO Fmpz -> Fmpz
forall a. IO a -> a
unsafePerformIO (IO Fmpz -> Fmpz) -> IO Fmpz -> Fmpz
forall a b. (a -> b) -> a -> b
$ do
  Fmpz
z <- IO Fmpz
newFmpz
  Fmpz
-> (Ptr CFmpz -> IO (Fmpz, (Fmpz, a)))
-> IO (Fmpz, (Fmpz, (Fmpz, a)))
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
x ((Ptr CFmpz -> IO (Fmpz, (Fmpz, a)))
 -> IO (Fmpz, (Fmpz, (Fmpz, a))))
-> (Ptr CFmpz -> IO (Fmpz, (Fmpz, a)))
-> IO (Fmpz, (Fmpz, (Fmpz, a)))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
x ->
    Fmpz -> (Ptr CFmpz -> IO (Fmpz, a)) -> IO (Fmpz, (Fmpz, a))
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
y ((Ptr CFmpz -> IO (Fmpz, a)) -> IO (Fmpz, (Fmpz, a)))
-> (Ptr CFmpz -> IO (Fmpz, a)) -> IO (Fmpz, (Fmpz, a))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
y ->
      Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
z ((Ptr CFmpz -> IO a) -> IO (Fmpz, a))
-> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
z -> Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> IO a
f Ptr CFmpz
z Ptr CFmpz
x Ptr CFmpz
y
  Fmpz -> IO Fmpz
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Fmpz
z