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

import GHC.Exts
import System.IO.Unsafe
import Control.Monad
import Foreign.C.String
import Foreign.Marshal.Alloc
import Text.ParserCombinators.ReadP

import Data.Ratio hiding (numerator, denominator)
import Data.Char

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

instance IsList FmpqPoly where
  type Item FmpqPoly = Fmpq
  fromList :: [Item FmpqPoly] -> FmpqPoly
fromList [Item FmpqPoly]
c =  IO FmpqPoly -> FmpqPoly
forall a. IO a -> a
unsafePerformIO (IO FmpqPoly -> FmpqPoly) -> IO FmpqPoly -> FmpqPoly
forall a b. (a -> b) -> a -> b
$ do
    FmpqPoly
p <- IO FmpqPoly
newFmpqPoly
    FmpqPoly -> (Ptr CFmpqPoly -> IO ()) -> IO (FmpqPoly, ())
forall {a}. FmpqPoly -> (Ptr CFmpqPoly -> IO a) -> IO (FmpqPoly, a)
withFmpqPoly FmpqPoly
p ((Ptr CFmpqPoly -> IO ()) -> IO (FmpqPoly, ()))
-> (Ptr CFmpqPoly -> IO ()) -> IO (FmpqPoly, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpqPoly
p -> do
      [Int] -> (Int -> IO (Fmpq, ())) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
0..[Fmpq] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Item FmpqPoly]
[Fmpq]
cInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1] ((Int -> IO (Fmpq, ())) -> IO ())
-> (Int -> IO (Fmpq, ())) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Int
j -> do
        Fmpq -> (Ptr CFmpq -> IO ()) -> IO (Fmpq, ())
forall {a}. Fmpq -> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
withFmpq ([Item FmpqPoly]
[Fmpq]
c[Fmpq] -> Int -> Fmpq
forall a. HasCallStack => [a] -> Int -> a
!!Int
j) ((Ptr CFmpq -> IO ()) -> IO (Fmpq, ()))
-> (Ptr CFmpq -> IO ()) -> IO (Fmpq, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpq
a -> 
          Ptr CFmpqPoly -> CLong -> Ptr CFmpq -> IO ()
fmpq_poly_set_coeff_fmpq Ptr CFmpqPoly
p (Int -> CLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
j) Ptr CFmpq
a
    FmpqPoly -> IO FmpqPoly
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return FmpqPoly
p
  toList :: FmpqPoly -> [Item FmpqPoly]
toList FmpqPoly
p = (FmpqPoly, [Item FmpqPoly]) -> [Item FmpqPoly]
forall a b. (a, b) -> b
snd ((FmpqPoly, [Item FmpqPoly]) -> [Item FmpqPoly])
-> (FmpqPoly, [Item FmpqPoly]) -> [Item FmpqPoly]
forall a b. (a -> b) -> a -> b
$ IO (FmpqPoly, [Item FmpqPoly]) -> (FmpqPoly, [Item FmpqPoly])
forall a. IO a -> a
unsafePerformIO (IO (FmpqPoly, [Item FmpqPoly]) -> (FmpqPoly, [Item FmpqPoly]))
-> IO (FmpqPoly, [Item FmpqPoly]) -> (FmpqPoly, [Item FmpqPoly])
forall a b. (a -> b) -> a -> b
$ do
    FmpqPoly
-> (Ptr CFmpqPoly -> IO [Item FmpqPoly])
-> IO (FmpqPoly, [Item FmpqPoly])
forall {a}. FmpqPoly -> (Ptr CFmpqPoly -> IO a) -> IO (FmpqPoly, a)
withFmpqPoly FmpqPoly
p ((Ptr CFmpqPoly -> IO [Item FmpqPoly])
 -> IO (FmpqPoly, [Item FmpqPoly]))
-> (Ptr CFmpqPoly -> IO [Item FmpqPoly])
-> IO (FmpqPoly, [Item FmpqPoly])
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpqPoly
p -> do
      CLong
d <- Ptr CFmpqPoly -> IO CLong
fmpq_poly_degree Ptr CFmpqPoly
p
      [CLong] -> (CLong -> IO Fmpq) -> IO [Fmpq]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [CLong
0..CLong
d] ((CLong -> IO Fmpq) -> IO [Fmpq])
-> (CLong -> IO Fmpq) -> IO [Fmpq]
forall a b. (a -> b) -> a -> b
$ \CLong
j -> do
        Fmpq
c <- IO Fmpq
newFmpq
        Fmpq -> (Ptr CFmpq -> IO ()) -> IO (Fmpq, ())
forall {a}. Fmpq -> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
withFmpq Fmpq
c ((Ptr CFmpq -> IO ()) -> IO (Fmpq, ()))
-> (Ptr CFmpq -> IO ()) -> IO (Fmpq, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpq
c -> Ptr CFmpq -> Ptr CFmpqPoly -> CLong -> IO ()
fmpq_poly_get_coeff_fmpq Ptr CFmpq
c Ptr CFmpqPoly
p CLong
j
        Fmpq -> IO Fmpq
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Fmpq
c
        
instance Show FmpqPoly where
  show :: FmpqPoly -> String
show FmpqPoly
p = (FmpqPoly, String) -> String
forall a b. (a, b) -> b
snd ((FmpqPoly, String) -> String) -> (FmpqPoly, String) -> String
forall a b. (a -> b) -> a -> b
$ IO (FmpqPoly, String) -> (FmpqPoly, String)
forall a. IO a -> a
unsafePerformIO (IO (FmpqPoly, String) -> (FmpqPoly, String))
-> IO (FmpqPoly, String) -> (FmpqPoly, String)
forall a b. (a -> b) -> a -> b
$ do
    FmpqPoly -> (Ptr CFmpqPoly -> IO String) -> IO (FmpqPoly, String)
forall {a}. FmpqPoly -> (Ptr CFmpqPoly -> IO a) -> IO (FmpqPoly, a)
withFmpqPoly FmpqPoly
p ((Ptr CFmpqPoly -> IO String) -> IO (FmpqPoly, String))
-> (Ptr CFmpqPoly -> IO String) -> IO (FmpqPoly, String)
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpqPoly
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 CFmpqPoly -> CString -> IO CString
fmpq_poly_get_str_pretty Ptr CFmpqPoly
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 FmpqPoly where
  readsPrec :: Int -> ReadS FmpqPoly
readsPrec Int
_ = ReadP FmpqPoly -> ReadS FmpqPoly
forall a. ReadP a -> ReadS a
readP_to_S ReadP FmpqPoly
parseFmpqPoly

instance Num FmpqPoly where
  * :: FmpqPoly -> FmpqPoly -> FmpqPoly
(*) = (Ptr CFmpqPoly -> Ptr CFmpqPoly -> Ptr CFmpqPoly -> IO ())
-> FmpqPoly -> FmpqPoly -> FmpqPoly
forall {a}.
(Ptr CFmpqPoly -> Ptr CFmpqPoly -> Ptr CFmpqPoly -> IO a)
-> FmpqPoly -> FmpqPoly -> FmpqPoly
lift2 Ptr CFmpqPoly -> Ptr CFmpqPoly -> Ptr CFmpqPoly -> IO ()
fmpq_poly_mul
  + :: FmpqPoly -> FmpqPoly -> FmpqPoly
(+) = (Ptr CFmpqPoly -> Ptr CFmpqPoly -> Ptr CFmpqPoly -> IO ())
-> FmpqPoly -> FmpqPoly -> FmpqPoly
forall {a}.
(Ptr CFmpqPoly -> Ptr CFmpqPoly -> Ptr CFmpqPoly -> IO a)
-> FmpqPoly -> FmpqPoly -> FmpqPoly
lift2 Ptr CFmpqPoly -> Ptr CFmpqPoly -> Ptr CFmpqPoly -> IO ()
fmpq_poly_add
  (-) = (Ptr CFmpqPoly -> Ptr CFmpqPoly -> Ptr CFmpqPoly -> IO ())
-> FmpqPoly -> FmpqPoly -> FmpqPoly
forall {a}.
(Ptr CFmpqPoly -> Ptr CFmpqPoly -> Ptr CFmpqPoly -> IO a)
-> FmpqPoly -> FmpqPoly -> FmpqPoly
lift2 Ptr CFmpqPoly -> Ptr CFmpqPoly -> Ptr CFmpqPoly -> IO ()
fmpq_poly_sub
  abs :: FmpqPoly -> FmpqPoly
abs = FmpqPoly -> FmpqPoly
forall a. HasCallStack => a
undefined
  signum :: FmpqPoly -> FmpqPoly
signum = FmpqPoly -> FmpqPoly
forall a. HasCallStack => a
undefined
  fromInteger :: Integer -> FmpqPoly
fromInteger Integer
x = (FmpqPoly, (Fmpz, ())) -> FmpqPoly
forall a b. (a, b) -> a
fst ((FmpqPoly, (Fmpz, ())) -> FmpqPoly)
-> (FmpqPoly, (Fmpz, ())) -> FmpqPoly
forall a b. (a -> b) -> a -> b
$ IO (FmpqPoly, (Fmpz, ())) -> (FmpqPoly, (Fmpz, ()))
forall a. IO a -> a
unsafePerformIO (IO (FmpqPoly, (Fmpz, ())) -> (FmpqPoly, (Fmpz, ())))
-> IO (FmpqPoly, (Fmpz, ())) -> (FmpqPoly, (Fmpz, ()))
forall a b. (a -> b) -> a -> b
$ do
    let t :: Fmpz
t = Integer -> Fmpz
forall a. Num a => Integer -> a
fromInteger Integer
x :: Fmpz
    (Ptr CFmpqPoly -> IO (Fmpz, ())) -> IO (FmpqPoly, (Fmpz, ()))
forall {a}. (Ptr CFmpqPoly -> IO a) -> IO (FmpqPoly, a)
withNewFmpqPoly ((Ptr CFmpqPoly -> IO (Fmpz, ())) -> IO (FmpqPoly, (Fmpz, ())))
-> (Ptr CFmpqPoly -> IO (Fmpz, ())) -> IO (FmpqPoly, (Fmpz, ()))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpqPoly
poly -> do
      Fmpz -> (Ptr CFmpz -> IO ()) -> IO (Fmpz, ())
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
t ((Ptr CFmpz -> IO ()) -> IO (Fmpz, ()))
-> (Ptr CFmpz -> IO ()) -> IO (Fmpz, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
x -> do
        Ptr CFmpqPoly -> Ptr CFmpz -> IO ()
fmpq_poly_set_fmpz Ptr CFmpqPoly
poly Ptr CFmpz
x
      
lift2 :: (Ptr CFmpqPoly -> Ptr CFmpqPoly -> Ptr CFmpqPoly -> IO a)
-> FmpqPoly -> FmpqPoly -> FmpqPoly
lift2 Ptr CFmpqPoly -> Ptr CFmpqPoly -> Ptr CFmpqPoly -> IO a
f FmpqPoly
x FmpqPoly
y = IO FmpqPoly -> FmpqPoly
forall a. IO a -> a
unsafePerformIO (IO FmpqPoly -> FmpqPoly) -> IO FmpqPoly -> FmpqPoly
forall a b. (a -> b) -> a -> b
$ do
    FmpqPoly
result <- IO FmpqPoly
newFmpqPoly
    FmpqPoly
-> (Ptr CFmpqPoly -> IO (FmpqPoly, (FmpqPoly, a)))
-> IO (FmpqPoly, (FmpqPoly, (FmpqPoly, a)))
forall {a}. FmpqPoly -> (Ptr CFmpqPoly -> IO a) -> IO (FmpqPoly, a)
withFmpqPoly FmpqPoly
result ((Ptr CFmpqPoly -> IO (FmpqPoly, (FmpqPoly, a)))
 -> IO (FmpqPoly, (FmpqPoly, (FmpqPoly, a))))
-> (Ptr CFmpqPoly -> IO (FmpqPoly, (FmpqPoly, a)))
-> IO (FmpqPoly, (FmpqPoly, (FmpqPoly, a)))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpqPoly
result -> do
      FmpqPoly
-> (Ptr CFmpqPoly -> IO (FmpqPoly, a))
-> IO (FmpqPoly, (FmpqPoly, a))
forall {a}. FmpqPoly -> (Ptr CFmpqPoly -> IO a) -> IO (FmpqPoly, a)
withFmpqPoly FmpqPoly
x ((Ptr CFmpqPoly -> IO (FmpqPoly, a))
 -> IO (FmpqPoly, (FmpqPoly, a)))
-> (Ptr CFmpqPoly -> IO (FmpqPoly, a))
-> IO (FmpqPoly, (FmpqPoly, a))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpqPoly
x -> do
        FmpqPoly -> (Ptr CFmpqPoly -> IO a) -> IO (FmpqPoly, a)
forall {a}. FmpqPoly -> (Ptr CFmpqPoly -> IO a) -> IO (FmpqPoly, a)
withFmpqPoly FmpqPoly
y ((Ptr CFmpqPoly -> IO a) -> IO (FmpqPoly, a))
-> (Ptr CFmpqPoly -> IO a) -> IO (FmpqPoly, a)
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpqPoly
y -> do
          Ptr CFmpqPoly -> Ptr CFmpqPoly -> Ptr CFmpqPoly -> IO a
f Ptr CFmpqPoly
result Ptr CFmpqPoly
x Ptr CFmpqPoly
y
    FmpqPoly -> IO FmpqPoly
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return FmpqPoly
result

parseFmpqPoly :: ReadP FmpqPoly
parseFmpqPoly :: ReadP FmpqPoly
parseFmpqPoly = do
  Int
n <- ReadP Int
parseItemNumber
  [Fmpq]
v <- Int -> ReadP Fmpq -> ReadP [Fmpq]
forall a. Int -> ReadP a -> ReadP [a]
count Int
n ReadP Fmpq
parseItem
  FmpqPoly -> ReadP FmpqPoly
forall a. a -> ReadP a
forall (m :: * -> *) a. Monad m => a -> m a
return (FmpqPoly -> ReadP FmpqPoly) -> FmpqPoly -> ReadP FmpqPoly
forall a b. (a -> b) -> a -> b
$ [Item FmpqPoly] -> FmpqPoly
forall l. IsList l => [Item l] -> l
fromList [Item FmpqPoly]
[Fmpq]
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 Fmpq
parseItem = String -> Fmpq
forall a. Read a => String -> a
read (String -> Fmpq) -> ReadP String -> ReadP Fmpq
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
parseFrac)
    parseFrac :: ReadP String
parseFrac = ReadP String
parseFraction ReadP String -> ReadP String -> ReadP String
forall a. ReadP a -> ReadP a -> ReadP a
<++ ReadP String
parseNumber
    parseFraction :: ReadP String
parseFraction = (String, String) -> String
forall a b. (a, b) -> a
fst ((String, String) -> String)
-> ReadP (String, String) -> ReadP String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadP String -> ReadP (String, String)
forall a. ReadP a -> ReadP (String, a)
gather (ReadP String
parseNumber ReadP String -> ReadP Char -> ReadP Char
forall a b. ReadP a -> ReadP b -> ReadP b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> 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
parsePositive)
    parseNumber :: ReadP String
parseNumber = ReadP String
parseNegative ReadP String -> ReadP String -> ReadP String
forall a. ReadP a -> ReadP a -> ReadP a
<++ ReadP String
parsePositive
    parseNegative :: ReadP String
parseNegative = (String, String) -> String
forall a b. (a, b) -> a
fst ((String, String) -> String)
-> ReadP (String, String) -> ReadP String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadP String -> ReadP (String, String)
forall a. ReadP a -> ReadP (String, a)
gather (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
*> (Char -> Bool) -> ReadP String
munch1 Char -> Bool
isNumber)
    parsePositive :: ReadP String
parsePositive = (Char -> Bool) -> ReadP String
munch1 Char -> Bool
isNumber