module Data.Number.Flint.Acb.Poly.Instances (
    AcbPoly (..)
  , 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 Data.Number.Flint.Acb
import Data.Number.Flint.Acb.Instances
import Data.Number.Flint.Acb.Poly

import Data.Number.Flint.UFD

instance Show AcbPoly where
  show :: AcbPoly -> String
show AcbPoly
p = (AcbPoly, String) -> String
forall a b. (a, b) -> b
snd ((AcbPoly, String) -> String) -> (AcbPoly, String) -> String
forall a b. (a -> b) -> a -> b
$ IO (AcbPoly, String) -> (AcbPoly, String)
forall a. IO a -> a
unsafePerformIO (IO (AcbPoly, String) -> (AcbPoly, String))
-> IO (AcbPoly, String) -> (AcbPoly, String)
forall a b. (a -> b) -> a -> b
$ do
    AcbPoly -> (Ptr CAcbPoly -> IO String) -> IO (AcbPoly, String)
forall {a}. AcbPoly -> (Ptr CAcbPoly -> IO a) -> IO (AcbPoly, a)
withAcbPoly AcbPoly
p ((Ptr CAcbPoly -> IO String) -> IO (AcbPoly, String))
-> (Ptr CAcbPoly -> IO String) -> IO (AcbPoly, String)
forall a b. (a -> b) -> a -> b
$ \Ptr CAcbPoly
p -> do
      CString
cs <- Ptr CAcbPoly -> CLong -> IO CString
acb_poly_get_strd Ptr CAcbPoly
p CLong
16
      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 IsList AcbPoly where
  type Item AcbPoly = Acb
  fromList :: [Item AcbPoly] -> AcbPoly
fromList [Item AcbPoly]
c = IO AcbPoly -> AcbPoly
forall a. IO a -> a
unsafePerformIO (IO AcbPoly -> AcbPoly) -> IO AcbPoly -> AcbPoly
forall a b. (a -> b) -> a -> b
$ do
    AcbPoly
p <- IO AcbPoly
newAcbPoly
    AcbPoly -> (Ptr CAcbPoly -> IO ()) -> IO (AcbPoly, ())
forall {a}. AcbPoly -> (Ptr CAcbPoly -> IO a) -> IO (AcbPoly, a)
withAcbPoly AcbPoly
p ((Ptr CAcbPoly -> IO ()) -> IO (AcbPoly, ()))
-> (Ptr CAcbPoly -> IO ()) -> IO (AcbPoly, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CAcbPoly
p -> 
      [Int] -> (Int -> IO (Acb, ())) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
0..[Acb] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Item AcbPoly]
[Acb]
cInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1] ((Int -> IO (Acb, ())) -> IO ()) -> (Int -> IO (Acb, ())) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Int
j ->
        Acb -> (Ptr CAcb -> IO ()) -> IO (Acb, ())
forall {a}. Acb -> (Ptr CAcb -> IO a) -> IO (Acb, a)
withAcb ([Item AcbPoly]
[Acb]
c[Acb] -> Int -> Acb
forall a. HasCallStack => [a] -> Int -> a
!!Int
j) ((Ptr CAcb -> IO ()) -> IO (Acb, ()))
-> (Ptr CAcb -> IO ()) -> IO (Acb, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CAcb
a -> 
          Ptr CAcbPoly -> CLong -> Ptr CAcb -> IO ()
acb_poly_set_coeff_acb Ptr CAcbPoly
p (Int -> CLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
j) Ptr CAcb
a
    AcbPoly -> IO AcbPoly
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return AcbPoly
p
  toList :: AcbPoly -> [Item AcbPoly]
toList AcbPoly
p = (AcbPoly, [Item AcbPoly]) -> [Item AcbPoly]
forall a b. (a, b) -> b
snd ((AcbPoly, [Item AcbPoly]) -> [Item AcbPoly])
-> (AcbPoly, [Item AcbPoly]) -> [Item AcbPoly]
forall a b. (a -> b) -> a -> b
$ IO (AcbPoly, [Item AcbPoly]) -> (AcbPoly, [Item AcbPoly])
forall a. IO a -> a
unsafePerformIO (IO (AcbPoly, [Item AcbPoly]) -> (AcbPoly, [Item AcbPoly]))
-> IO (AcbPoly, [Item AcbPoly]) -> (AcbPoly, [Item AcbPoly])
forall a b. (a -> b) -> a -> b
$ 
    AcbPoly
-> (Ptr CAcbPoly -> IO [Item AcbPoly])
-> IO (AcbPoly, [Item AcbPoly])
forall {a}. AcbPoly -> (Ptr CAcbPoly -> IO a) -> IO (AcbPoly, a)
withAcbPoly AcbPoly
p ((Ptr CAcbPoly -> IO [Item AcbPoly])
 -> IO (AcbPoly, [Item AcbPoly]))
-> (Ptr CAcbPoly -> IO [Item AcbPoly])
-> IO (AcbPoly, [Item AcbPoly])
forall a b. (a -> b) -> a -> b
$ \Ptr CAcbPoly
p -> do
      CLong
d <- Ptr CAcbPoly -> IO CLong
acb_poly_degree Ptr CAcbPoly
p
      [CLong] -> (CLong -> IO Acb) -> IO [Acb]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [CLong
0..CLong
d] ((CLong -> IO Acb) -> IO [Acb]) -> (CLong -> IO Acb) -> IO [Acb]
forall a b. (a -> b) -> a -> b
$ \CLong
j -> do
        Acb
c <- IO Acb
newAcb
        Acb -> (Ptr CAcb -> IO ()) -> IO (Acb, ())
forall {a}. Acb -> (Ptr CAcb -> IO a) -> IO (Acb, a)
withAcb Acb
c ((Ptr CAcb -> IO ()) -> IO (Acb, ()))
-> (Ptr CAcb -> IO ()) -> IO (Acb, ())
forall a b. (a -> b) -> a -> b
$ \Ptr CAcb
c -> Ptr CAcb -> Ptr CAcbPoly -> CLong -> IO ()
acb_poly_get_coeff_acb Ptr CAcb
c Ptr CAcbPoly
p CLong
j
        Acb -> IO Acb
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Acb
c

lift2 :: (Ptr CAcbPoly -> Ptr CAcbPoly -> Ptr CAcbPoly -> IO a)
-> AcbPoly -> AcbPoly -> AcbPoly
lift2 Ptr CAcbPoly -> Ptr CAcbPoly -> Ptr CAcbPoly -> IO a
f AcbPoly
x AcbPoly
y = IO AcbPoly -> AcbPoly
forall a. IO a -> a
unsafePerformIO (IO AcbPoly -> AcbPoly) -> IO AcbPoly -> AcbPoly
forall a b. (a -> b) -> a -> b
$ do
  AcbPoly
result <- IO AcbPoly
newAcbPoly
  AcbPoly
-> (Ptr CAcbPoly -> IO (AcbPoly, (AcbPoly, a)))
-> IO (AcbPoly, (AcbPoly, (AcbPoly, a)))
forall {a}. AcbPoly -> (Ptr CAcbPoly -> IO a) -> IO (AcbPoly, a)
withAcbPoly AcbPoly
result ((Ptr CAcbPoly -> IO (AcbPoly, (AcbPoly, a)))
 -> IO (AcbPoly, (AcbPoly, (AcbPoly, a))))
-> (Ptr CAcbPoly -> IO (AcbPoly, (AcbPoly, a)))
-> IO (AcbPoly, (AcbPoly, (AcbPoly, a)))
forall a b. (a -> b) -> a -> b
$ \Ptr CAcbPoly
result -> do
    AcbPoly
-> (Ptr CAcbPoly -> IO (AcbPoly, a)) -> IO (AcbPoly, (AcbPoly, a))
forall {a}. AcbPoly -> (Ptr CAcbPoly -> IO a) -> IO (AcbPoly, a)
withAcbPoly AcbPoly
x ((Ptr CAcbPoly -> IO (AcbPoly, a)) -> IO (AcbPoly, (AcbPoly, a)))
-> (Ptr CAcbPoly -> IO (AcbPoly, a)) -> IO (AcbPoly, (AcbPoly, a))
forall a b. (a -> b) -> a -> b
$ \Ptr CAcbPoly
x -> do
      AcbPoly -> (Ptr CAcbPoly -> IO a) -> IO (AcbPoly, a)
forall {a}. AcbPoly -> (Ptr CAcbPoly -> IO a) -> IO (AcbPoly, a)
withAcbPoly AcbPoly
y ((Ptr CAcbPoly -> IO a) -> IO (AcbPoly, a))
-> (Ptr CAcbPoly -> IO a) -> IO (AcbPoly, a)
forall a b. (a -> b) -> a -> b
$ \Ptr CAcbPoly
y -> do
        Ptr CAcbPoly -> Ptr CAcbPoly -> Ptr CAcbPoly -> IO a
f Ptr CAcbPoly
result Ptr CAcbPoly
x Ptr CAcbPoly
y
  AcbPoly -> IO AcbPoly
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return AcbPoly
result

lift1 :: (Ptr CAcbPoly -> Ptr CAcbPoly -> IO a) -> AcbPoly -> AcbPoly
lift1 Ptr CAcbPoly -> Ptr CAcbPoly -> IO a
f AcbPoly
x = IO AcbPoly -> AcbPoly
forall a. IO a -> a
unsafePerformIO (IO AcbPoly -> AcbPoly) -> IO AcbPoly -> AcbPoly
forall a b. (a -> b) -> a -> b
$ do
  AcbPoly
result <- IO AcbPoly
newAcbPoly
  AcbPoly
-> (Ptr CAcbPoly -> IO (AcbPoly, a)) -> IO (AcbPoly, (AcbPoly, a))
forall {a}. AcbPoly -> (Ptr CAcbPoly -> IO a) -> IO (AcbPoly, a)
withAcbPoly AcbPoly
result ((Ptr CAcbPoly -> IO (AcbPoly, a)) -> IO (AcbPoly, (AcbPoly, a)))
-> (Ptr CAcbPoly -> IO (AcbPoly, a)) -> IO (AcbPoly, (AcbPoly, a))
forall a b. (a -> b) -> a -> b
$ \Ptr CAcbPoly
result ->
    AcbPoly -> (Ptr CAcbPoly -> IO a) -> IO (AcbPoly, a)
forall {a}. AcbPoly -> (Ptr CAcbPoly -> IO a) -> IO (AcbPoly, a)
withAcbPoly AcbPoly
x ((Ptr CAcbPoly -> IO a) -> IO (AcbPoly, a))
-> (Ptr CAcbPoly -> IO a) -> IO (AcbPoly, a)
forall a b. (a -> b) -> a -> b
$ \Ptr CAcbPoly
x ->
    Ptr CAcbPoly -> Ptr CAcbPoly -> IO a
f Ptr CAcbPoly
result Ptr CAcbPoly
x
  AcbPoly -> IO AcbPoly
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return AcbPoly
result