{-|
module      :  Data.Number.Flint.Fmpz.Poly.Instances
copyright   :  (c) 2022 Hartmut Monien
license     :  GNU GPL, version 2 or above (see LICENSE)
maintainer  :  hmonien@uni-bonn.de
-}
module Data.Number.Flint.Fmpz.Poly.Instances (
    FmpzPoly (..)
  , module GHC.Exts
) where

import Test.QuickCheck

import GHC.Exts

import System.IO.Unsafe
import Control.Monad

import Foreign.Ptr
import Foreign.C.String
import Foreign.Storable
import Foreign.Marshal.Alloc (free)
import Foreign.Marshal.Array (advancePtr)
import Text.ParserCombinators.ReadP

import Data.Bits
import Data.Char

import Data.Number.Flint.Fmpz
import Data.Number.Flint.Fmpz.Instances
import Data.Number.Flint.Fmpz.Poly
import Data.Number.Flint.Fmpz.Poly.Factor

import Data.Number.Flint.UFD

instance Show FmpzPoly where
  show :: FmpzPoly -> String
show FmpzPoly
p = (FmpzPoly, String) -> String
forall a b. (a, b) -> b
snd ((FmpzPoly, String) -> String) -> (FmpzPoly, String) -> String
forall a b. (a -> b) -> a -> b
$ IO (FmpzPoly, String) -> (FmpzPoly, String)
forall a. IO a -> a
unsafePerformIO (IO (FmpzPoly, String) -> (FmpzPoly, String))
-> IO (FmpzPoly, String) -> (FmpzPoly, String)
forall a b. (a -> b) -> a -> b
$ do
    FmpzPoly -> (Ptr CFmpzPoly -> IO String) -> IO (FmpzPoly, String)
forall {a}. FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
withFmpzPoly FmpzPoly
p ((Ptr CFmpzPoly -> IO String) -> IO (FmpzPoly, String))
-> (Ptr CFmpzPoly -> IO String) -> IO (FmpzPoly, String)
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPoly
p -> do
      String -> (CString -> IO String) -> IO String
forall a. String -> (CString -> IO a) -> IO a
withCString String
"x" ((CString -> IO String) -> IO String)
-> (CString -> IO String) -> IO String
forall a b. (a -> b) -> a -> b
$ \CString
x -> do
        CString
cs <- Ptr CFmpzPoly -> CString -> IO CString
fmpz_poly_get_str_pretty Ptr CFmpzPoly
p CString
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 FmpzPoly where
  readsPrec :: Int -> ReadS FmpzPoly
readsPrec Int
_ = ReadP FmpzPoly -> ReadS FmpzPoly
forall a. ReadP a -> ReadS a
readP_to_S ReadP FmpzPoly
parseFmpzPoly

instance Num FmpzPoly where
  * :: FmpzPoly -> FmpzPoly -> FmpzPoly
(*) = (Ptr CFmpzPoly -> Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO ())
-> FmpzPoly -> FmpzPoly -> FmpzPoly
forall {a}.
(Ptr CFmpzPoly -> Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO a)
-> FmpzPoly -> FmpzPoly -> FmpzPoly
lift2 Ptr CFmpzPoly -> Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO ()
fmpz_poly_mul
  + :: FmpzPoly -> FmpzPoly -> FmpzPoly
(+) = (Ptr CFmpzPoly -> Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO ())
-> FmpzPoly -> FmpzPoly -> FmpzPoly
forall {a}.
(Ptr CFmpzPoly -> Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO a)
-> FmpzPoly -> FmpzPoly -> FmpzPoly
lift2 Ptr CFmpzPoly -> Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO ()
fmpz_poly_add
  (-) = (Ptr CFmpzPoly -> Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO ())
-> FmpzPoly -> FmpzPoly -> FmpzPoly
forall {a}.
(Ptr CFmpzPoly -> Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO a)
-> FmpzPoly -> FmpzPoly -> FmpzPoly
lift2 Ptr CFmpzPoly -> Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO ()
fmpz_poly_sub
  abs :: FmpzPoly -> FmpzPoly
abs = FmpzPoly -> FmpzPoly
forall a. HasCallStack => a
undefined
  signum :: FmpzPoly -> FmpzPoly
signum = FmpzPoly -> FmpzPoly
forall a. HasCallStack => a
undefined
  fromInteger :: Integer -> FmpzPoly
fromInteger Integer
x = IO FmpzPoly -> FmpzPoly
forall a. IO a -> a
unsafePerformIO (IO FmpzPoly -> FmpzPoly) -> IO FmpzPoly -> FmpzPoly
forall a b. (a -> b) -> a -> b
$ do
    let tmp :: Fmpz
tmp = Integer -> Fmpz
forall a. Num a => Integer -> a
fromInteger Integer
x :: Fmpz
    FmpzPoly
result <- IO FmpzPoly
newFmpzPoly
    FmpzPoly
-> (Ptr CFmpzPoly -> IO (Fmpz, Ptr CFmpzPoly))
-> IO (FmpzPoly, (Fmpz, Ptr CFmpzPoly))
forall {a}. FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
withFmpzPoly FmpzPoly
result ((Ptr CFmpzPoly -> IO (Fmpz, Ptr CFmpzPoly))
 -> IO (FmpzPoly, (Fmpz, Ptr CFmpzPoly)))
-> (Ptr CFmpzPoly -> IO (Fmpz, Ptr CFmpzPoly))
-> IO (FmpzPoly, (Fmpz, Ptr CFmpzPoly))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPoly
result -> 
      Fmpz
-> (Ptr CFmpz -> IO (Ptr CFmpzPoly)) -> IO (Fmpz, Ptr CFmpzPoly)
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
tmp ((Ptr CFmpz -> IO (Ptr CFmpzPoly)) -> IO (Fmpz, Ptr CFmpzPoly))
-> (Ptr CFmpz -> IO (Ptr CFmpzPoly)) -> IO (Fmpz, Ptr CFmpzPoly)
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
tmp -> do
      Ptr CFmpzPoly -> Ptr CFmpz -> IO ()
fmpz_poly_set_fmpz Ptr CFmpzPoly
result Ptr CFmpz
tmp
      Ptr CFmpzPoly -> IO (Ptr CFmpzPoly)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Ptr CFmpzPoly
result
    FmpzPoly -> IO FmpzPoly
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return FmpzPoly
result

instance Semigroup FmpzPoly where
  <> :: FmpzPoly -> FmpzPoly -> FmpzPoly
(<>) = (Ptr CFmpzPoly -> Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO ())
-> FmpzPoly -> FmpzPoly -> FmpzPoly
forall {a}.
(Ptr CFmpzPoly -> Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO a)
-> FmpzPoly -> FmpzPoly -> FmpzPoly
lift2 Ptr CFmpzPoly -> Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO ()
fmpz_poly_compose

instance Eq FmpzPoly where
  == :: FmpzPoly -> FmpzPoly -> Bool
(==) FmpzPoly
x FmpzPoly
y = (FmpzPoly, Bool) -> Bool
forall a b. (a, b) -> b
snd ((FmpzPoly, Bool) -> Bool) -> (FmpzPoly, Bool) -> Bool
forall a b. (a -> b) -> a -> b
$ (FmpzPoly, (FmpzPoly, Bool)) -> (FmpzPoly, Bool)
forall a b. (a, b) -> b
snd ((FmpzPoly, (FmpzPoly, Bool)) -> (FmpzPoly, Bool))
-> (FmpzPoly, (FmpzPoly, Bool)) -> (FmpzPoly, Bool)
forall a b. (a -> b) -> a -> b
$ IO (FmpzPoly, (FmpzPoly, Bool)) -> (FmpzPoly, (FmpzPoly, Bool))
forall a. IO a -> a
unsafePerformIO (IO (FmpzPoly, (FmpzPoly, Bool)) -> (FmpzPoly, (FmpzPoly, Bool)))
-> IO (FmpzPoly, (FmpzPoly, Bool)) -> (FmpzPoly, (FmpzPoly, Bool))
forall a b. (a -> b) -> a -> b
$ do
    FmpzPoly
-> (Ptr CFmpzPoly -> IO (FmpzPoly, Bool))
-> IO (FmpzPoly, (FmpzPoly, Bool))
forall {a}. FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
withFmpzPoly FmpzPoly
x ((Ptr CFmpzPoly -> IO (FmpzPoly, Bool))
 -> IO (FmpzPoly, (FmpzPoly, Bool)))
-> (Ptr CFmpzPoly -> IO (FmpzPoly, Bool))
-> IO (FmpzPoly, (FmpzPoly, Bool))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPoly
x ->
      FmpzPoly -> (Ptr CFmpzPoly -> IO Bool) -> IO (FmpzPoly, Bool)
forall {a}. FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
withFmpzPoly FmpzPoly
y ((Ptr CFmpzPoly -> IO Bool) -> IO (FmpzPoly, Bool))
-> (Ptr CFmpzPoly -> IO Bool) -> IO (FmpzPoly, Bool)
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPoly
y -> do
        CInt
f <- Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO CInt
fmpz_poly_equal Ptr CFmpzPoly
x Ptr CFmpzPoly
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
f CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
== CInt
1

instance Ord FmpzPoly where
  compare :: FmpzPoly -> FmpzPoly -> Ordering
compare = FmpzPoly -> FmpzPoly -> Ordering
forall a. HasCallStack => a
undefined
  
instance Real FmpzPoly where
  toRational :: FmpzPoly -> Rational
toRational = FmpzPoly -> Rational
forall a. HasCallStack => a
undefined

instance Enum FmpzPoly where
  toEnum :: Int -> FmpzPoly
toEnum = Int -> FmpzPoly
forall a. HasCallStack => a
undefined
  fromEnum :: FmpzPoly -> Int
fromEnum = FmpzPoly -> Int
forall a. HasCallStack => a
undefined
  
instance Integral FmpzPoly where
  toInteger :: FmpzPoly -> Integer
toInteger = FmpzPoly -> Integer
forall a. HasCallStack => a
undefined
  div :: FmpzPoly -> FmpzPoly -> FmpzPoly
div FmpzPoly
x FmpzPoly
y = IO FmpzPoly -> FmpzPoly
forall a. IO a -> a
unsafePerformIO (IO FmpzPoly -> FmpzPoly) -> IO FmpzPoly -> FmpzPoly
forall a b. (a -> b) -> a -> b
$ do
    FmpzPoly
p <- IO FmpzPoly
newFmpzPoly
    FmpzPoly
q <- IO FmpzPoly
newFmpzPoly
    FmpzPoly
-> (Ptr CFmpzPoly -> IO (FmpzPoly, (FmpzPoly, ())))
-> IO (FmpzPoly, (FmpzPoly, (FmpzPoly, ())))
forall {a}. FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
withFmpzPoly FmpzPoly
x ((Ptr CFmpzPoly -> IO (FmpzPoly, (FmpzPoly, ())))
 -> IO (FmpzPoly, (FmpzPoly, (FmpzPoly, ()))))
-> (Ptr CFmpzPoly -> IO (FmpzPoly, (FmpzPoly, ())))
-> IO (FmpzPoly, (FmpzPoly, (FmpzPoly, ())))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPoly
x ->
      FmpzPoly
-> (Ptr CFmpzPoly -> IO (FmpzPoly, ()))
-> IO (FmpzPoly, (FmpzPoly, ()))
forall {a}. FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
withFmpzPoly FmpzPoly
y ((Ptr CFmpzPoly -> IO (FmpzPoly, ()))
 -> IO (FmpzPoly, (FmpzPoly, ())))
-> (Ptr CFmpzPoly -> IO (FmpzPoly, ()))
-> IO (FmpzPoly, (FmpzPoly, ()))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPoly
y ->
        FmpzPoly -> (Ptr CFmpzPoly -> IO ()) -> IO (FmpzPoly, ())
forall {a}. FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
withFmpzPoly FmpzPoly
q ((Ptr CFmpzPoly -> IO ()) -> IO (FmpzPoly, ()))
-> (Ptr CFmpzPoly -> IO ()) -> IO (FmpzPoly, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPoly
q ->
          Ptr CFmpzPoly -> Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO ()
fmpz_poly_div Ptr CFmpzPoly
q Ptr CFmpzPoly
x Ptr CFmpzPoly
y
    FmpzPoly -> IO FmpzPoly
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return FmpzPoly
q
  quotRem :: FmpzPoly -> FmpzPoly -> (FmpzPoly, FmpzPoly)
quotRem FmpzPoly
x FmpzPoly
y = IO (FmpzPoly, FmpzPoly) -> (FmpzPoly, FmpzPoly)
forall a. IO a -> a
unsafePerformIO (IO (FmpzPoly, FmpzPoly) -> (FmpzPoly, FmpzPoly))
-> IO (FmpzPoly, FmpzPoly) -> (FmpzPoly, FmpzPoly)
forall a b. (a -> b) -> a -> b
$ do
    FmpzPoly
p <- IO FmpzPoly
newFmpzPoly
    FmpzPoly
q <- IO FmpzPoly
newFmpzPoly
    FmpzPoly
-> (Ptr CFmpzPoly -> IO (FmpzPoly, (FmpzPoly, (FmpzPoly, ()))))
-> IO (FmpzPoly, (FmpzPoly, (FmpzPoly, (FmpzPoly, ()))))
forall {a}. FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
withFmpzPoly FmpzPoly
x ((Ptr CFmpzPoly -> IO (FmpzPoly, (FmpzPoly, (FmpzPoly, ()))))
 -> IO (FmpzPoly, (FmpzPoly, (FmpzPoly, (FmpzPoly, ())))))
-> (Ptr CFmpzPoly -> IO (FmpzPoly, (FmpzPoly, (FmpzPoly, ()))))
-> IO (FmpzPoly, (FmpzPoly, (FmpzPoly, (FmpzPoly, ()))))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPoly
x ->
      FmpzPoly
-> (Ptr CFmpzPoly -> IO (FmpzPoly, (FmpzPoly, ())))
-> IO (FmpzPoly, (FmpzPoly, (FmpzPoly, ())))
forall {a}. FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
withFmpzPoly FmpzPoly
y ((Ptr CFmpzPoly -> IO (FmpzPoly, (FmpzPoly, ())))
 -> IO (FmpzPoly, (FmpzPoly, (FmpzPoly, ()))))
-> (Ptr CFmpzPoly -> IO (FmpzPoly, (FmpzPoly, ())))
-> IO (FmpzPoly, (FmpzPoly, (FmpzPoly, ())))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPoly
y ->
        FmpzPoly
-> (Ptr CFmpzPoly -> IO (FmpzPoly, ()))
-> IO (FmpzPoly, (FmpzPoly, ()))
forall {a}. FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
withFmpzPoly FmpzPoly
p ((Ptr CFmpzPoly -> IO (FmpzPoly, ()))
 -> IO (FmpzPoly, (FmpzPoly, ())))
-> (Ptr CFmpzPoly -> IO (FmpzPoly, ()))
-> IO (FmpzPoly, (FmpzPoly, ()))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPoly
p ->
          FmpzPoly -> (Ptr CFmpzPoly -> IO ()) -> IO (FmpzPoly, ())
forall {a}. FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
withFmpzPoly FmpzPoly
q ((Ptr CFmpzPoly -> IO ()) -> IO (FmpzPoly, ()))
-> (Ptr CFmpzPoly -> IO ()) -> IO (FmpzPoly, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPoly
q ->
            Ptr CFmpzPoly
-> Ptr CFmpzPoly -> Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO ()
fmpz_poly_divrem Ptr CFmpzPoly
p Ptr CFmpzPoly
q Ptr CFmpzPoly
x Ptr CFmpzPoly
y
    (FmpzPoly, FmpzPoly) -> IO (FmpzPoly, FmpzPoly)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (FmpzPoly
p, FmpzPoly
q)

instance UFD FmpzPoly where
  factor :: FmpzPoly -> [(FmpzPoly, Int)]
factor FmpzPoly
x = (FmpzPolyFactor, [(FmpzPoly, Int)]) -> [(FmpzPoly, Int)]
forall a b. (a, b) -> b
snd ((FmpzPolyFactor, [(FmpzPoly, Int)]) -> [(FmpzPoly, Int)])
-> (FmpzPolyFactor, [(FmpzPoly, Int)]) -> [(FmpzPoly, Int)]
forall a b. (a -> b) -> a -> b
$ (FmpzPoly, (FmpzPolyFactor, [(FmpzPoly, Int)]))
-> (FmpzPolyFactor, [(FmpzPoly, Int)])
forall a b. (a, b) -> b
snd ((FmpzPoly, (FmpzPolyFactor, [(FmpzPoly, Int)]))
 -> (FmpzPolyFactor, [(FmpzPoly, Int)]))
-> (FmpzPoly, (FmpzPolyFactor, [(FmpzPoly, Int)]))
-> (FmpzPolyFactor, [(FmpzPoly, Int)])
forall a b. (a -> b) -> a -> b
$ IO (FmpzPoly, (FmpzPolyFactor, [(FmpzPoly, Int)]))
-> (FmpzPoly, (FmpzPolyFactor, [(FmpzPoly, Int)]))
forall a. IO a -> a
unsafePerformIO (IO (FmpzPoly, (FmpzPolyFactor, [(FmpzPoly, Int)]))
 -> (FmpzPoly, (FmpzPolyFactor, [(FmpzPoly, Int)])))
-> IO (FmpzPoly, (FmpzPolyFactor, [(FmpzPoly, Int)]))
-> (FmpzPoly, (FmpzPolyFactor, [(FmpzPoly, Int)]))
forall a b. (a -> b) -> a -> b
$ do
    FmpzPoly
-> (Ptr CFmpzPoly -> IO (FmpzPolyFactor, [(FmpzPoly, Int)]))
-> IO (FmpzPoly, (FmpzPolyFactor, [(FmpzPoly, Int)]))
forall {a}. FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
withFmpzPoly FmpzPoly
x ((Ptr CFmpzPoly -> IO (FmpzPolyFactor, [(FmpzPoly, Int)]))
 -> IO (FmpzPoly, (FmpzPolyFactor, [(FmpzPoly, Int)])))
-> (Ptr CFmpzPoly -> IO (FmpzPolyFactor, [(FmpzPoly, Int)]))
-> IO (FmpzPoly, (FmpzPolyFactor, [(FmpzPoly, Int)]))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPoly
x -> do
      FmpzPolyFactor
f <- IO FmpzPolyFactor
newFmpzPolyFactor
      FmpzPolyFactor
-> (Ptr CFmpzPolyFactor -> IO [(FmpzPoly, Int)])
-> IO (FmpzPolyFactor, [(FmpzPoly, Int)])
forall {a}.
FmpzPolyFactor
-> (Ptr CFmpzPolyFactor -> IO a) -> IO (FmpzPolyFactor, a)
withFmpzPolyFactor FmpzPolyFactor
f ((Ptr CFmpzPolyFactor -> IO [(FmpzPoly, Int)])
 -> IO (FmpzPolyFactor, [(FmpzPoly, Int)]))
-> (Ptr CFmpzPolyFactor -> IO [(FmpzPoly, Int)])
-> IO (FmpzPolyFactor, [(FmpzPoly, Int)])
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPolyFactor
f -> do
        Ptr CFmpzPolyFactor -> Ptr CFmpzPoly -> IO ()
fmpz_poly_factor Ptr CFmpzPolyFactor
f Ptr CFmpzPoly
x
        CFmpzPolyFactor Ptr CFmpz
c Ptr CFmpzPoly
d Ptr CLong
e CLong
n CLong
alloc <- Ptr CFmpzPolyFactor -> IO CFmpzPolyFactor
forall a. Storable a => Ptr a -> IO a
peek Ptr CFmpzPolyFactor
f
        Fmpz
prefactor <- IO Fmpz
newFmpz
        Fmpz -> (Ptr CFmpz -> IO ()) -> IO (Fmpz, ())
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
prefactor ((Ptr CFmpz -> IO ()) -> IO (Fmpz, ()))
-> (Ptr CFmpz -> IO ()) -> IO (Fmpz, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
prefactor -> Ptr CFmpz -> Ptr CFmpz -> IO ()
fmpz_set Ptr CFmpz
prefactor Ptr CFmpz
c 
        let pre :: (FmpzPoly, Int)
pre = ([Item FmpzPoly] -> FmpzPoly
forall l. IsList l => [Item l] -> l
fromList [Item FmpzPoly
Fmpz
prefactor] :: FmpzPoly, Int
1)
        [(FmpzPoly, Int)]
fac <- [Int] -> (Int -> IO (FmpzPoly, Int)) -> IO [(FmpzPoly, 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 (FmpzPoly, Int)) -> IO [(FmpzPoly, Int)])
-> (Int -> IO (FmpzPoly, Int)) -> IO [(FmpzPoly, Int)]
forall a b. (a -> b) -> a -> b
$ \Int
j -> do
          CLong
m <- Ptr CLong -> IO CLong
forall a. Storable a => Ptr a -> IO a
peek (Ptr CLong
e Ptr CLong -> Int -> Ptr CLong
forall a. Storable a => Ptr a -> Int -> Ptr a
`advancePtr` Int
j)
          FmpzPoly
r <- IO FmpzPoly
newFmpzPoly
          FmpzPoly -> (Ptr CFmpzPoly -> IO ()) -> IO (FmpzPoly, ())
forall {a}. FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
withFmpzPoly FmpzPoly
r ((Ptr CFmpzPoly -> IO ()) -> IO (FmpzPoly, ()))
-> (Ptr CFmpzPoly -> IO ()) -> IO (FmpzPoly, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPoly
r -> Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO ()
fmpz_poly_set Ptr CFmpzPoly
r (Ptr CFmpzPoly
d Ptr CFmpzPoly -> Int -> Ptr CFmpzPoly
forall a. Storable a => Ptr a -> Int -> Ptr a
`advancePtr` Int
j)
          (FmpzPoly, Int) -> IO (FmpzPoly, Int)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (FmpzPoly
r, CLong -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CLong
m)
        [(FmpzPoly, Int)] -> IO [(FmpzPoly, Int)]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([(FmpzPoly, Int)] -> IO [(FmpzPoly, Int)])
-> [(FmpzPoly, Int)] -> IO [(FmpzPoly, Int)]
forall a b. (a -> b) -> a -> b
$ if Fmpz
prefactor Fmpz -> Fmpz -> Bool
forall a. Eq a => a -> a -> Bool
== Fmpz
1 then [(FmpzPoly, Int)]
fac else (FmpzPoly, Int)
pre (FmpzPoly, Int) -> [(FmpzPoly, Int)] -> [(FmpzPoly, Int)]
forall a. a -> [a] -> [a]
: [(FmpzPoly, Int)]
fac
        
instance Arbitrary FmpzPoly where
  arbitrary :: Gen FmpzPoly
arbitrary = do
    [Fmpz]
c <- Gen Fmpz -> Gen [Fmpz]
forall a. Gen a -> Gen [a]
listOf Gen Fmpz
forall a. Arbitrary a => Gen a
arbitrary
    FmpzPoly -> Gen FmpzPoly
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return (FmpzPoly -> Gen FmpzPoly) -> FmpzPoly -> Gen FmpzPoly
forall a b. (a -> b) -> a -> b
$ [Item FmpzPoly] -> FmpzPoly
forall l. IsList l => [Item l] -> l
fromList ([Fmpz]
c [Fmpz] -> [Fmpz] -> [Fmpz]
forall a. [a] -> [a] -> [a]
++ [Fmpz
1])

instance IsList FmpzPoly where
  type Item FmpzPoly = Fmpz
  fromList :: [Item FmpzPoly] -> FmpzPoly
fromList [Item FmpzPoly]
c = IO FmpzPoly -> FmpzPoly
forall a. IO a -> a
unsafePerformIO (IO FmpzPoly -> FmpzPoly) -> IO FmpzPoly -> FmpzPoly
forall a b. (a -> b) -> a -> b
$ do
    FmpzPoly
p <- IO FmpzPoly
newFmpzPoly
    FmpzPoly -> (Ptr CFmpzPoly -> IO ()) -> IO (FmpzPoly, ())
forall {a}. FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
withFmpzPoly FmpzPoly
p ((Ptr CFmpzPoly -> IO ()) -> IO (FmpzPoly, ()))
-> (Ptr CFmpzPoly -> IO ()) -> IO (FmpzPoly, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPoly
p -> 
      [Int] -> (Int -> IO (Fmpz, ())) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
0..[Fmpz] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Item FmpzPoly]
[Fmpz]
cInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1] ((Int -> IO (Fmpz, ())) -> IO ())
-> (Int -> IO (Fmpz, ())) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Int
j ->
        Fmpz -> (Ptr CFmpz -> IO ()) -> IO (Fmpz, ())
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz ([Item FmpzPoly]
[Fmpz]
c[Fmpz] -> Int -> Fmpz
forall a. HasCallStack => [a] -> Int -> a
!!Int
j) ((Ptr CFmpz -> IO ()) -> IO (Fmpz, ()))
-> (Ptr CFmpz -> IO ()) -> IO (Fmpz, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
a -> 
          Ptr CFmpzPoly -> CLong -> Ptr CFmpz -> IO ()
fmpz_poly_set_coeff_fmpz Ptr CFmpzPoly
p (Int -> CLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
j) Ptr CFmpz
a
    FmpzPoly -> IO FmpzPoly
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return FmpzPoly
p
  toList :: FmpzPoly -> [Item FmpzPoly]
toList FmpzPoly
p = (FmpzPoly, [Item FmpzPoly]) -> [Item FmpzPoly]
forall a b. (a, b) -> b
snd ((FmpzPoly, [Item FmpzPoly]) -> [Item FmpzPoly])
-> (FmpzPoly, [Item FmpzPoly]) -> [Item FmpzPoly]
forall a b. (a -> b) -> a -> b
$ IO (FmpzPoly, [Item FmpzPoly]) -> (FmpzPoly, [Item FmpzPoly])
forall a. IO a -> a
unsafePerformIO (IO (FmpzPoly, [Item FmpzPoly]) -> (FmpzPoly, [Item FmpzPoly]))
-> IO (FmpzPoly, [Item FmpzPoly]) -> (FmpzPoly, [Item FmpzPoly])
forall a b. (a -> b) -> a -> b
$ 
    FmpzPoly
-> (Ptr CFmpzPoly -> IO [Item FmpzPoly])
-> IO (FmpzPoly, [Item FmpzPoly])
forall {a}. FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
withFmpzPoly FmpzPoly
p ((Ptr CFmpzPoly -> IO [Item FmpzPoly])
 -> IO (FmpzPoly, [Item FmpzPoly]))
-> (Ptr CFmpzPoly -> IO [Item FmpzPoly])
-> IO (FmpzPoly, [Item FmpzPoly])
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPoly
p -> do
      CLong
d <- Ptr CFmpzPoly -> IO CLong
fmpz_poly_degree Ptr CFmpzPoly
p
      [CLong] -> (CLong -> IO Fmpz) -> IO [Fmpz]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [CLong
0..CLong
d] ((CLong -> IO Fmpz) -> IO [Fmpz])
-> (CLong -> IO Fmpz) -> IO [Fmpz]
forall a b. (a -> b) -> a -> b
$ \CLong
j -> do
        Fmpz
c <- IO Fmpz
newFmpz
        Fmpz -> (Ptr CFmpz -> IO ()) -> IO (Fmpz, ())
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
c ((Ptr CFmpz -> IO ()) -> IO (Fmpz, ()))
-> (Ptr CFmpz -> IO ()) -> IO (Fmpz, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
c -> Ptr CFmpz -> Ptr CFmpzPoly -> CLong -> IO ()
fmpz_poly_get_coeff_fmpz Ptr CFmpz
c Ptr CFmpzPoly
p CLong
j
        Fmpz -> IO Fmpz
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Fmpz
c

lift2 :: (Ptr CFmpzPoly -> Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO a)
-> FmpzPoly -> FmpzPoly -> FmpzPoly
lift2 Ptr CFmpzPoly -> Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO a
f FmpzPoly
x FmpzPoly
y = IO FmpzPoly -> FmpzPoly
forall a. IO a -> a
unsafePerformIO (IO FmpzPoly -> FmpzPoly) -> IO FmpzPoly -> FmpzPoly
forall a b. (a -> b) -> a -> b
$ do
  FmpzPoly
result <- IO FmpzPoly
newFmpzPoly
  FmpzPoly
-> (Ptr CFmpzPoly -> IO (FmpzPoly, (FmpzPoly, a)))
-> IO (FmpzPoly, (FmpzPoly, (FmpzPoly, a)))
forall {a}. FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
withFmpzPoly FmpzPoly
result ((Ptr CFmpzPoly -> IO (FmpzPoly, (FmpzPoly, a)))
 -> IO (FmpzPoly, (FmpzPoly, (FmpzPoly, a))))
-> (Ptr CFmpzPoly -> IO (FmpzPoly, (FmpzPoly, a)))
-> IO (FmpzPoly, (FmpzPoly, (FmpzPoly, a)))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPoly
result -> do
    FmpzPoly
-> (Ptr CFmpzPoly -> IO (FmpzPoly, a))
-> IO (FmpzPoly, (FmpzPoly, a))
forall {a}. FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
withFmpzPoly FmpzPoly
x ((Ptr CFmpzPoly -> IO (FmpzPoly, a))
 -> IO (FmpzPoly, (FmpzPoly, a)))
-> (Ptr CFmpzPoly -> IO (FmpzPoly, a))
-> IO (FmpzPoly, (FmpzPoly, a))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPoly
x -> do
      FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
forall {a}. FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
withFmpzPoly FmpzPoly
y ((Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a))
-> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPoly
y -> do
        Ptr CFmpzPoly -> Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO a
f Ptr CFmpzPoly
result Ptr CFmpzPoly
x Ptr CFmpzPoly
y
  FmpzPoly -> IO FmpzPoly
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return FmpzPoly
result

lift1 :: (Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO a) -> FmpzPoly -> FmpzPoly
lift1 Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO a
f FmpzPoly
x = IO FmpzPoly -> FmpzPoly
forall a. IO a -> a
unsafePerformIO (IO FmpzPoly -> FmpzPoly) -> IO FmpzPoly -> FmpzPoly
forall a b. (a -> b) -> a -> b
$ do
  FmpzPoly
result <- IO FmpzPoly
newFmpzPoly
  FmpzPoly
-> (Ptr CFmpzPoly -> IO (FmpzPoly, a))
-> IO (FmpzPoly, (FmpzPoly, a))
forall {a}. FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
withFmpzPoly FmpzPoly
result ((Ptr CFmpzPoly -> IO (FmpzPoly, a))
 -> IO (FmpzPoly, (FmpzPoly, a)))
-> (Ptr CFmpzPoly -> IO (FmpzPoly, a))
-> IO (FmpzPoly, (FmpzPoly, a))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPoly
result ->
    FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
forall {a}. FmpzPoly -> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
withFmpzPoly FmpzPoly
x ((Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a))
-> (Ptr CFmpzPoly -> IO a) -> IO (FmpzPoly, a)
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPoly
x ->
    Ptr CFmpzPoly -> Ptr CFmpzPoly -> IO a
f Ptr CFmpzPoly
result Ptr CFmpzPoly
x
  FmpzPoly -> IO FmpzPoly
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return FmpzPoly
result

parseFmpzPoly :: ReadP FmpzPoly
parseFmpzPoly :: ReadP FmpzPoly
parseFmpzPoly = do
  Int
n <- ReadP Int
parseItemNumber
  [Fmpz]
v <- Int -> ReadP Fmpz -> ReadP [Fmpz]
forall a. Int -> ReadP a -> ReadP [a]
count Int
n ReadP Fmpz
parseItem 
  FmpzPoly -> ReadP FmpzPoly
forall a. a -> ReadP a
forall (m :: * -> *) a. Monad m => a -> m a
return (FmpzPoly -> ReadP FmpzPoly) -> FmpzPoly -> ReadP FmpzPoly
forall a b. (a -> b) -> a -> b
$ [Item FmpzPoly] -> FmpzPoly
forall l. IsList l => [Item l] -> l
fromList [Item FmpzPoly]
[Fmpz]
v
  where
    parseItemNumber :: ReadP Int
parseItemNumber = String -> Int
forall a. Read a => String -> a
read (String -> Int) -> ReadP String -> ReadP Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char -> Bool) -> ReadP String
munch1 Char -> Bool
isNumber ReadP Int -> ReadP Char -> ReadP Int
forall a b. ReadP a -> ReadP b -> ReadP a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> ReadP Char
char Char
' '
    parseItem :: ReadP Fmpz
parseItem = String -> Fmpz
forall a. Read a => String -> a
read (String -> Fmpz) -> ReadP String -> ReadP Fmpz
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char -> ReadP Char
char Char
' ' ReadP Char -> ReadP String -> ReadP String
forall a b. ReadP a -> ReadP b -> ReadP b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ReadP String
parseFmpz)
    parseFmpz :: ReadP String
parseFmpz = do
      String
s <- (Char -> Bool) -> ReadP String
munch (\Char
x -> Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'+' Bool -> Bool -> Bool
|| Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'-')
      ReadP ()
skipSpaces
      String
d <- (Char -> Bool) -> ReadP String
munch1 Char -> Bool
isNumber
      String -> ReadP String
forall a. a -> ReadP a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> ReadP String) -> String -> ReadP String
forall a b. (a -> b) -> a -> b
$ String
s String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
d