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 =  forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ do
    FmpqPoly
p <- IO FmpqPoly
newFmpqPoly
    forall {a}. FmpqPoly -> (Ptr CFmpqPoly -> IO a) -> IO (FmpqPoly, a)
withFmpqPoly FmpqPoly
p forall a b. (a -> b) -> a -> b
$ \Ptr CFmpqPoly
p -> do
      forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
0..forall (t :: * -> *) a. Foldable t => t a -> Int
length [Item FmpqPoly]
cforall a. Num a => a -> a -> a
-Int
1] forall a b. (a -> b) -> a -> b
$ \Int
j -> do
        forall {a}. Fmpq -> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
withFmpq ([Item FmpqPoly]
cforall a. [a] -> Int -> a
!!Int
j) forall a b. (a -> b) -> a -> b
$ \Ptr CFmpq
a -> 
          Ptr CFmpqPoly -> CLong -> Ptr CFmpq -> IO ()
fmpq_poly_set_coeff_fmpq Ptr CFmpqPoly
p (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
j) Ptr CFmpq
a
    forall (m :: * -> *) a. Monad m => a -> m a
return FmpqPoly
p
  toList :: FmpqPoly -> [Item FmpqPoly]
toList FmpqPoly
p = forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ do
    forall {a}. FmpqPoly -> (Ptr CFmpqPoly -> IO a) -> IO (FmpqPoly, a)
withFmpqPoly FmpqPoly
p forall a b. (a -> b) -> a -> b
$ \Ptr CFmpqPoly
p -> do
      CLong
d <- Ptr CFmpqPoly -> IO CLong
fmpq_poly_degree Ptr CFmpqPoly
p
      forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [CLong
0..CLong
d] forall a b. (a -> b) -> a -> b
$ \CLong
j -> do
        Fmpq
c <- IO Fmpq
newFmpq
        forall {a}. Fmpq -> (Ptr CFmpq -> IO a) -> IO (Fmpq, a)
withFmpq Fmpq
c 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
        forall (m :: * -> *) a. Monad m => a -> m a
return Fmpq
c
        
instance Show FmpqPoly where
  show :: FmpqPoly -> String
show FmpqPoly
p = forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ do
    forall {a}. FmpqPoly -> (Ptr CFmpqPoly -> IO a) -> IO (FmpqPoly, a)
withFmpqPoly FmpqPoly
p forall a b. (a -> b) -> a -> b
$ \Ptr CFmpqPoly
p -> do
      forall a. String -> (CString -> IO a) -> IO a
withCString String
"x" 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
        forall a. Ptr a -> IO ()
free CString
cs
        forall (m :: * -> *) a. Monad m => a -> m a
return String
s

instance Read FmpqPoly where
  readsPrec :: Int -> ReadS FmpqPoly
readsPrec Int
_ = forall a. ReadP a -> ReadS a
readP_to_S ReadP FmpqPoly
parseFmpqPoly

instance Num FmpqPoly where
  * :: 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
(+) = forall {a}.
(Ptr CFmpqPoly -> Ptr CFmpqPoly -> Ptr CFmpqPoly -> IO a)
-> FmpqPoly -> FmpqPoly -> FmpqPoly
lift2 Ptr CFmpqPoly -> Ptr CFmpqPoly -> Ptr CFmpqPoly -> IO ()
fmpq_poly_add
  (-) = 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 = forall a. HasCallStack => a
undefined
  signum :: FmpqPoly -> FmpqPoly
signum = forall a. HasCallStack => a
undefined
  fromInteger :: Integer -> FmpqPoly
fromInteger Integer
x = forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ do
    let t :: Fmpz
t = forall a. Num a => Integer -> a
fromInteger Integer
x :: Fmpz
    forall {a}. (Ptr CFmpqPoly -> IO a) -> IO (FmpqPoly, a)
withNewFmpqPoly forall a b. (a -> b) -> a -> b
$ \Ptr CFmpqPoly
poly -> do
      forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
t 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 = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ do
    FmpqPoly
result <- IO FmpqPoly
newFmpqPoly
    forall {a}. FmpqPoly -> (Ptr CFmpqPoly -> IO a) -> IO (FmpqPoly, a)
withFmpqPoly FmpqPoly
result forall a b. (a -> b) -> a -> b
$ \Ptr CFmpqPoly
result -> do
      forall {a}. FmpqPoly -> (Ptr CFmpqPoly -> IO a) -> IO (FmpqPoly, a)
withFmpqPoly FmpqPoly
x forall a b. (a -> b) -> a -> b
$ \Ptr CFmpqPoly
x -> do
        forall {a}. FmpqPoly -> (Ptr CFmpqPoly -> IO a) -> IO (FmpqPoly, a)
withFmpqPoly FmpqPoly
y 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
    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 <- forall a. Int -> ReadP a -> ReadP [a]
count Int
n ReadP Fmpq
parseItem
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall l. IsList l => [Item l] -> l
fromList [Fmpq]
v
  where
    parseItemNumber :: ReadP Int
parseItemNumber = forall a. Read a => String -> a
read forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char -> Bool) -> ReadP String
munch1 Char -> Bool
isNumber forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> ReadP Char
char Char
' '
    parseItem :: ReadP Fmpq
parseItem = forall a. Read a => String -> a
read forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char -> ReadP Char
char Char
' ' forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ReadP String
parseFrac)
    parseFrac :: ReadP String
parseFrac = ReadP String
parseFraction forall a. ReadP a -> ReadP a -> ReadP a
<++ ReadP String
parseNumber
    parseFraction :: ReadP String
parseFraction = forall a b. (a, b) -> a
fst forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. ReadP a -> ReadP (String, a)
gather (ReadP String
parseNumber forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Char -> ReadP Char
char Char
'/' forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ReadP String
parsePositive)
    parseNumber :: ReadP String
parseNumber = ReadP String
parseNegative forall a. ReadP a -> ReadP a -> ReadP a
<++ ReadP String
parsePositive
    parseNegative :: ReadP String
parseNegative = forall a b. (a, b) -> a
fst forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. ReadP a -> ReadP (String, a)
gather (Char -> ReadP Char
char Char
'-' 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