{-# LINE 1 "src/Data/Number/Flint/Fmpz/Poly/Q/FFI.hsc" #-}
{-|
module      :  Data.Number.Flint.Fmpz.Poly.Q.FFI
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.Q.FFI (
  -- * Rational functions over the rational numbers
    FmpzPolyQ (..)
  , CFmpzPolyQ (..)
  , newFmpzPolyQ
  , withFmpzPolyQ
  , withNewFmpzPolyQ
  , withFmpzPolyQNum
  , withFmpzPolyQDen
  -- * Memory management
  , fmpz_poly_q_init
  , fmpz_poly_q_clear
  -- , fmpz_poly_q_numref
  -- , fmpz_poly_q_denref
  , fmpz_poly_q_canonicalise
  , fmpz_poly_q_is_canonical
  -- * Randomisation
  , fmpz_poly_q_randtest
  , fmpz_poly_q_randtest_not_zero
  -- * Assignment
  , fmpz_poly_q_set
  , fmpz_poly_q_set_si
  , fmpz_poly_q_swap
  , fmpz_poly_q_zero
  , fmpz_poly_q_one
  , fmpz_poly_q_neg
  , fmpz_poly_q_inv
  -- * Comparison
  , fmpz_poly_q_is_zero
  , fmpz_poly_q_is_one
  , fmpz_poly_q_equal
  -- * Addition and subtraction
  , fmpz_poly_q_add
  , fmpz_poly_q_sub
  , fmpz_poly_q_addmul
  , fmpz_poly_q_submul
  -- * Scalar multiplication and division
  , fmpz_poly_q_scalar_mul_si
  , fmpz_poly_q_scalar_mul_fmpz
  , fmpz_poly_q_scalar_mul_fmpq
  , fmpz_poly_q_scalar_div_si
  , fmpz_poly_q_scalar_div_fmpz
  , fmpz_poly_q_scalar_div_fmpq
  -- * Multiplication and division
  , fmpz_poly_q_mul
  , fmpz_poly_q_div
  -- * Powering
  , fmpz_poly_q_pow
  -- * Derivative
  , fmpz_poly_q_derivative
  -- * Evaluation
  , fmpz_poly_q_evaluate_fmpq
  -- * Input and output
  , fmpz_poly_q_set_str
  , fmpz_poly_q_get_str
  , fmpz_poly_q_get_str_pretty
  , fmpz_poly_q_print
  , fmpz_poly_q_print_pretty
) where 

-- Rational functions over the rational numbers --------------------------------

import Foreign.Ptr
import Foreign.ForeignPtr
import Foreign.C.Types
import Foreign.C.String
import Foreign.Storable
import Foreign.Marshal.Array ( advancePtr )

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



-- fmpz_poly_q_t ---------------------------------------------------------------

data FmpzPolyQ = FmpzPolyQ {-# UNPACK #-} !(ForeignPtr CFmpzPolyQ)
data CFmpzPolyQ = CFmpzPolyQ (Ptr CFmpzPoly) (Ptr CFmpzPoly)

instance Storable CFmpzPolyQ where
  sizeOf :: CFmpzPolyQ -> Int
sizeOf    CFmpzPolyQ
_ = (Int
16)
{-# LINE 91 "src/Data/Number/Flint/Fmpz/Poly/Q/FFI.hsc" #-}
  alignment _ = (16)
{-# LINE 92 "src/Data/Number/Flint/Fmpz/Poly/Q/FFI.hsc" #-}
  peek ptr = CFmpzPolyQ
    <$> (\hsc_ptr -> peekByteOff hsc_ptr 0) ptr
{-# LINE 94 "src/Data/Number/Flint/Fmpz/Poly/Q/FFI.hsc" #-}
    <*> (\hsc_ptr -> peekByteOff hsc_ptr 8) ptr
{-# LINE 95 "src/Data/Number/Flint/Fmpz/Poly/Q/FFI.hsc" #-}
  poke ptr (CFmpzPolyQ num den) = do
    (\hsc_ptr -> pokeByteOff hsc_ptr 0) ptr num
{-# LINE 97 "src/Data/Number/Flint/Fmpz/Poly/Q/FFI.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 8) ptr den
{-# LINE 98 "src/Data/Number/Flint/Fmpz/Poly/Q/FFI.hsc" #-}

newFmpzPolyQ :: IO FmpzPolyQ
newFmpzPolyQ = do
  ForeignPtr CFmpzPolyQ
x <- IO (ForeignPtr CFmpzPolyQ)
forall a. Storable a => IO (ForeignPtr a)
mallocForeignPtr
  ForeignPtr CFmpzPolyQ -> (Ptr CFmpzPolyQ -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr CFmpzPolyQ
x Ptr CFmpzPolyQ -> IO ()
fmpz_poly_q_init
  FinalizerPtr CFmpzPolyQ -> ForeignPtr CFmpzPolyQ -> IO ()
forall a. FinalizerPtr a -> ForeignPtr a -> IO ()
addForeignPtrFinalizer FinalizerPtr CFmpzPolyQ
p_fmpz_poly_q_clear ForeignPtr CFmpzPolyQ
x
  FmpzPolyQ -> IO FmpzPolyQ
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (FmpzPolyQ -> IO FmpzPolyQ) -> FmpzPolyQ -> IO FmpzPolyQ
forall a b. (a -> b) -> a -> b
$ ForeignPtr CFmpzPolyQ -> FmpzPolyQ
FmpzPolyQ ForeignPtr CFmpzPolyQ
x

withFmpzPolyQ :: FmpzPolyQ -> (Ptr CFmpzPolyQ -> IO a) -> IO (FmpzPolyQ, a)
withFmpzPolyQ (FmpzPolyQ ForeignPtr CFmpzPolyQ
x) Ptr CFmpzPolyQ -> IO a
f = do
  ForeignPtr CFmpzPolyQ
-> (Ptr CFmpzPolyQ -> IO (FmpzPolyQ, a)) -> IO (FmpzPolyQ, a)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr CFmpzPolyQ
x ((Ptr CFmpzPolyQ -> IO (FmpzPolyQ, a)) -> IO (FmpzPolyQ, a))
-> (Ptr CFmpzPolyQ -> IO (FmpzPolyQ, a)) -> IO (FmpzPolyQ, a)
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPolyQ
xp -> (ForeignPtr CFmpzPolyQ -> FmpzPolyQ
FmpzPolyQ ForeignPtr CFmpzPolyQ
x,) (a -> (FmpzPolyQ, a)) -> IO a -> IO (FmpzPolyQ, a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CFmpzPolyQ -> IO a
f Ptr CFmpzPolyQ
xp

withNewFmpzPolyQ :: (Ptr CFmpzPolyQ -> IO a) -> IO (FmpzPolyQ, a)
withNewFmpzPolyQ Ptr CFmpzPolyQ -> IO a
f = do
  FmpzPolyQ
x <- IO FmpzPolyQ
newFmpzPolyQ
  FmpzPolyQ -> (Ptr CFmpzPolyQ -> IO a) -> IO (FmpzPolyQ, a)
forall {a}.
FmpzPolyQ -> (Ptr CFmpzPolyQ -> IO a) -> IO (FmpzPolyQ, a)
withFmpzPolyQ FmpzPolyQ
x Ptr CFmpzPolyQ -> IO a
f

withFmpzPolyQNum :: FmpzPolyQ -> (Ptr CFmpzPoly -> IO t) -> IO (FmpzPolyQ, t)
withFmpzPolyQNum :: forall t. FmpzPolyQ -> (Ptr CFmpzPoly -> IO t) -> IO (FmpzPolyQ, t)
withFmpzPolyQNum FmpzPolyQ
x Ptr CFmpzPoly -> IO t
f = do
  (FmpzPolyQ
_, (FmpzPolyQ, t)
res) <- FmpzPolyQ
-> (Ptr CFmpzPolyQ -> IO (FmpzPolyQ, t))
-> IO (FmpzPolyQ, (FmpzPolyQ, t))
forall {a}.
FmpzPolyQ -> (Ptr CFmpzPolyQ -> IO a) -> IO (FmpzPolyQ, a)
withFmpzPolyQ FmpzPolyQ
x ((Ptr CFmpzPolyQ -> IO (FmpzPolyQ, t))
 -> IO (FmpzPolyQ, (FmpzPolyQ, t)))
-> (Ptr CFmpzPolyQ -> IO (FmpzPolyQ, t))
-> IO (FmpzPolyQ, (FmpzPolyQ, t))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPolyQ
xp -> do
    CFmpzPolyQ Ptr CFmpzPoly
n Ptr CFmpzPoly
d <- Ptr CFmpzPolyQ -> IO CFmpzPolyQ
forall a. Storable a => Ptr a -> IO a
peek Ptr CFmpzPolyQ
xp
    (FmpzPolyQ
x,) (t -> (FmpzPolyQ, t)) -> IO t -> IO (FmpzPolyQ, t)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CFmpzPoly -> IO t
f Ptr CFmpzPoly
n
  (FmpzPolyQ, t) -> IO (FmpzPolyQ, t)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (FmpzPolyQ, t)
res
    
withFmpzPolyQDen :: FmpzPolyQ -> (Ptr CFmpzPoly -> IO t) -> IO (FmpzPolyQ, t)
withFmpzPolyQDen :: forall t. FmpzPolyQ -> (Ptr CFmpzPoly -> IO t) -> IO (FmpzPolyQ, t)
withFmpzPolyQDen FmpzPolyQ
x Ptr CFmpzPoly -> IO t
f = do
  (FmpzPolyQ
_, (FmpzPolyQ, t)
res) <- FmpzPolyQ
-> (Ptr CFmpzPolyQ -> IO (FmpzPolyQ, t))
-> IO (FmpzPolyQ, (FmpzPolyQ, t))
forall {a}.
FmpzPolyQ -> (Ptr CFmpzPolyQ -> IO a) -> IO (FmpzPolyQ, a)
withFmpzPolyQ FmpzPolyQ
x ((Ptr CFmpzPolyQ -> IO (FmpzPolyQ, t))
 -> IO (FmpzPolyQ, (FmpzPolyQ, t)))
-> (Ptr CFmpzPolyQ -> IO (FmpzPolyQ, t))
-> IO (FmpzPolyQ, (FmpzPolyQ, t))
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpzPolyQ
xp -> do
    CFmpzPolyQ Ptr CFmpzPoly
n Ptr CFmpzPoly
d <- Ptr CFmpzPolyQ -> IO CFmpzPolyQ
forall a. Storable a => Ptr a -> IO a
peek Ptr CFmpzPolyQ
xp
    (FmpzPolyQ
x,) (t -> (FmpzPolyQ, t)) -> IO t -> IO (FmpzPolyQ, t)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CFmpzPoly -> IO t
f Ptr CFmpzPoly
d
  (FmpzPolyQ, t) -> IO (FmpzPolyQ, t)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (FmpzPolyQ, t)
res

-- Memory management -----------------------------------------------------------

-- We represent a rational function over \(\mathbf{Q}\) as the quotient of
-- two coprime integer polynomials of type @fmpz_poly_t@, enforcing that
-- the leading coefficient of the denominator is positive. The zero
-- function is represented as \(0/1\).
--
-- | /fmpz_poly_q_init/ /rop/ 
--
-- Initialises @rop@.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_init"
  fmpz_poly_q_init :: Ptr CFmpzPolyQ -> IO ()

-- | /fmpz_poly_q_clear/ /rop/ 
--
-- Clears the object @rop@.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_clear"
  fmpz_poly_q_clear :: Ptr CFmpzPolyQ -> IO ()

foreign import ccall "fmpz_poly_q.h &fmpz_poly_q_clear"
  p_fmpz_poly_q_clear :: FunPtr (Ptr CFmpzPolyQ -> IO ())

-- -- | /fmpz_poly_q_numref/ /op/ 
-- --
-- -- Returns a reference to the numerator of @op@.
-- foreign import ccall "fmpz_poly_q.h fmpz_poly_q_numref"
--   fmpz_poly_q_numref :: Ptr CFmpzPolyQ -> IO (Ptr CFmpzPoly)

-- -- | /fmpz_poly_q_denref/ /op/ 
-- --
-- -- Returns a reference to the denominator of @op@.
-- foreign import ccall "fmpz_poly_q.h fmpz_poly_q_denref"
--   fmpz_poly_q_denref :: Ptr CFmpzPolyQ -> IO (Ptr CFmpzPoly)

-- | /fmpz_poly_q_canonicalise/ /rop/ 
--
-- Brings @rop@ into canonical form, only assuming that the denominator is
-- non-zero.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_canonicalise"
  fmpz_poly_q_canonicalise :: Ptr CFmpzPolyQ -> IO ()

-- | /fmpz_poly_q_is_canonical/ /op/ 
--
-- Checks whether the rational function @op@ is in canonical form.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_is_canonical"
  fmpz_poly_q_is_canonical :: Ptr CFmpzPolyQ -> IO CInt

-- Randomisation ---------------------------------------------------------------

-- | /fmpz_poly_q_randtest/ /poly/ /state/ /len1/ /bits1/ /len2/ /bits2/ 
--
-- Sets @poly@ to a random rational function.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_randtest"
  fmpz_poly_q_randtest :: Ptr CFmpzPolyQ -> Ptr CFRandState -> CLong -> CFBitCnt -> CLong -> CFBitCnt -> IO ()

-- | /fmpz_poly_q_randtest_not_zero/ /poly/ /state/ /len1/ /bits1/ /len2/ /bits2/ 
--
-- Sets @poly@ to a random non-zero rational function.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_randtest_not_zero"
  fmpz_poly_q_randtest_not_zero :: Ptr CFmpzPolyQ -> Ptr CFRandState -> CLong -> CFBitCnt -> CLong -> CFBitCnt -> IO ()

-- Assignment ------------------------------------------------------------------

-- | /fmpz_poly_q_set/ /rop/ /op/ 
--
-- Sets the element @rop@ to the same value as the element @op@.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_set"
  fmpz_poly_q_set :: Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> IO ()

-- | /fmpz_poly_q_set_si/ /rop/ /op/ 
--
-- Sets the element @rop@ to the value given by the @slong@ @op@.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_set_si"
  fmpz_poly_q_set_si :: Ptr CFmpzPolyQ -> CLong -> IO ()

-- | /fmpz_poly_q_swap/ /op1/ /op2/ 
--
-- Swaps the elements @op1@ and @op2@.
-- 
-- This is done efficiently by swapping pointers.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_swap"
  fmpz_poly_q_swap :: Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> IO ()

-- | /fmpz_poly_q_zero/ /rop/ 
--
-- Sets @rop@ to zero.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_zero"
  fmpz_poly_q_zero :: Ptr CFmpzPolyQ -> IO ()

-- | /fmpz_poly_q_one/ /rop/ 
--
-- Sets @rop@ to one.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_one"
  fmpz_poly_q_one :: Ptr CFmpzPolyQ -> IO ()

-- | /fmpz_poly_q_neg/ /rop/ /op/ 
--
-- Sets the element @rop@ to the additive inverse of @op@.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_neg"
  fmpz_poly_q_neg :: Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> IO ()

-- | /fmpz_poly_q_inv/ /rop/ /op/ 
--
-- Sets the element @rop@ to the multiplicative inverse of @op@.
-- 
-- Assumes that the element @op@ is non-zero.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_inv"
  fmpz_poly_q_inv :: Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> IO ()

-- Comparison ------------------------------------------------------------------

-- | /fmpz_poly_q_is_zero/ /op/ 
--
-- Returns whether the element @op@ is zero.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_is_zero"
  fmpz_poly_q_is_zero :: Ptr CFmpzPolyQ -> IO CInt

-- | /fmpz_poly_q_is_one/ /op/ 
--
-- Returns whether the element @rop@ is equal to the constant polynomial
-- \(1\).
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_is_one"
  fmpz_poly_q_is_one :: Ptr CFmpzPolyQ -> IO CInt

-- | /fmpz_poly_q_equal/ /op1/ /op2/ 
--
-- Returns whether the two elements @op1@ and @op2@ are equal.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_equal"
  fmpz_poly_q_equal :: Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> IO CInt

-- Addition and subtraction ----------------------------------------------------

-- | /fmpz_poly_q_add/ /rop/ /op1/ /op2/ 
--
-- Sets @rop@ to the sum of @op1@ and @op2@.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_add"
  fmpz_poly_q_add :: Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> IO ()

-- | /fmpz_poly_q_sub/ /rop/ /op1/ /op2/ 
--
-- Sets @rop@ to the difference of @op1@ and @op2@.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_sub"
  fmpz_poly_q_sub :: Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> IO ()

-- | /fmpz_poly_q_addmul/ /rop/ /op1/ /op2/ 
--
-- Adds the product of @op1@ and @op2@ to @rop@.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_addmul"
  fmpz_poly_q_addmul :: Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> IO ()

-- | /fmpz_poly_q_submul/ /rop/ /op1/ /op2/ 
--
-- Subtracts the product of @op1@ and @op2@ from @rop@.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_submul"
  fmpz_poly_q_submul :: Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> IO ()

-- Scalar multiplication and division ------------------------------------------

-- | /fmpz_poly_q_scalar_mul_si/ /rop/ /op/ /x/ 
--
-- Sets @rop@ to the product of the rational function @op@ and the @slong@
-- integer \(x\).
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_scalar_mul_si"
  fmpz_poly_q_scalar_mul_si :: Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> CLong -> IO ()

-- | /fmpz_poly_q_scalar_mul_fmpz/ /rop/ /op/ /x/ 
--
-- Sets @rop@ to the product of the rational function @op@ and the @fmpz_t@
-- integer \(x\).
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_scalar_mul_fmpz"
  fmpz_poly_q_scalar_mul_fmpz :: Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> Ptr CFmpz -> IO ()

-- | /fmpz_poly_q_scalar_mul_fmpq/ /rop/ /op/ /x/ 
--
-- Sets @rop@ to the product of the rational function @op@ and the @fmpq_t@
-- rational \(x\).
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_scalar_mul_fmpq"
  fmpz_poly_q_scalar_mul_fmpq :: Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> Ptr CFmpq -> IO ()

-- | /fmpz_poly_q_scalar_div_si/ /rop/ /op/ /x/ 
--
-- Sets @rop@ to the quotient of the rational function @op@ and the @slong@
-- integer \(x\).
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_scalar_div_si"
  fmpz_poly_q_scalar_div_si :: Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> CLong -> IO ()

-- | /fmpz_poly_q_scalar_div_fmpz/ /rop/ /op/ /x/ 
--
-- Sets @rop@ to the quotient of the rational function @op@ and the
-- @fmpz_t@ integer \(x\).
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_scalar_div_fmpz"
  fmpz_poly_q_scalar_div_fmpz :: Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> Ptr CFmpz -> IO ()

-- | /fmpz_poly_q_scalar_div_fmpq/ /rop/ /op/ /x/ 
--
-- Sets @rop@ to the quotient of the rational function @op@ and the
-- @fmpq_t@ rational \(x\).
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_scalar_div_fmpq"
  fmpz_poly_q_scalar_div_fmpq :: Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> Ptr CFmpq -> IO ()

-- Multiplication and division -------------------------------------------------

-- | /fmpz_poly_q_mul/ /rop/ /op1/ /op2/ 
--
-- Sets @rop@ to the product of @op1@ and @op2@.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_mul"
  fmpz_poly_q_mul :: Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> IO ()

-- | /fmpz_poly_q_div/ /rop/ /op1/ /op2/ 
--
-- Sets @rop@ to the quotient of @op1@ and @op2@.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_div"
  fmpz_poly_q_div :: Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> IO ()

-- Powering --------------------------------------------------------------------

-- | /fmpz_poly_q_pow/ /rop/ /op/ /exp/ 
--
-- Sets @rop@ to the @exp@-th power of @op@.
-- 
-- The corner case of @exp == 0@ is handled by setting @rop@ to the
-- constant function \(1\). Note that this includes the case \(0^0 = 1\).
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_pow"
  fmpz_poly_q_pow :: Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> CULong -> IO ()

-- Derivative ------------------------------------------------------------------

-- | /fmpz_poly_q_derivative/ /rop/ /op/ 
--
-- Sets @rop@ to the derivative of @op@.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_derivative"
  fmpz_poly_q_derivative :: Ptr CFmpzPolyQ -> Ptr CFmpzPolyQ -> IO ()

-- Evaluation ------------------------------------------------------------------

-- | /fmpz_poly_q_evaluate_fmpq/ /rop/ /f/ /a/ 
--
-- Sets @rop@ to \(f\) evaluated at the rational \(a\).
-- 
-- If the denominator evaluates to zero at \(a\), returns non-zero and does
-- not modify any of the variables. Otherwise, returns \(0\) and sets @rop@
-- to the rational \(f(a)\).
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_evaluate_fmpq"
  fmpz_poly_q_evaluate_fmpq :: Ptr CFmpq -> Ptr CFmpzPolyQ -> Ptr CFmpq -> IO CInt

-- Input and output ------------------------------------------------------------

-- | /fmpz_poly_q_set_str/ /rop/ /s/
--
-- Sets @rop@ to the rational function given by the string @s@.
-- The following three methods enable users to construct elements of type
-- @fmpz_poly_q_t@ from strings or to obtain string representations of such
-- elements. The format used is based on the FLINT format for integer
-- polynomials of type @fmpz_poly_t@, which we recall first: A non-zero
-- polynomial \(a_0 + a_1 X + \dotsb + a_n X^n\) of length n + 1 is
-- represented by the string @\"n+1  a_0 a_1 ... a_n\"@, where there are
-- two space characters following the length and single space characters
-- separating the individual coefficients. There is no leading or trailing
-- white-space. The zero polynomial is simply represented by @\"0\"@. We
-- adapt this notation for rational functions as follows. We denote the
-- zero function by @\"0\"@. Given a non-zero function with numerator and
-- denominator string representations @num@ and @den@, respectively, we use
-- the string @num\/den@ to represent the rational function, unless the
-- denominator is equal to one, in which case we simply use @num@. There is
-- also a @_pretty@ variant available, which bases the string parts for the
-- numerator and denominator on the output of the function
-- @fmpz_poly_get_str_pretty@ and introduces parentheses where necessary.
-- Note that currently these functions are not optimised for performance
-- and are intended to be used only for debugging purposes or one-off input
-- and output, rather than as a low-level parser.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_set_str"
  fmpz_poly_q_set_str :: Ptr CFmpzPolyQ -> CString -> IO CInt

-- | /fmpz_poly_q_get_str/ /op/ 
--
-- Returns the string representation of the rational function @op@.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_get_str"
  fmpz_poly_q_get_str :: Ptr CFmpzPolyQ -> IO CString

-- | /fmpz_poly_q_get_str_pretty/ /op/ /x/ 
--
-- Returns the pretty string representation of the rational function @op@.
foreign import ccall "fmpz_poly_q.h fmpz_poly_q_get_str_pretty"
  fmpz_poly_q_get_str_pretty :: Ptr CFmpzPolyQ -> CString -> IO CString

-- | /fmpz_poly_q_print/ /op/ 
--
-- Prints the representation of the rational function @op@ to @stdout@.
fmpz_poly_q_print :: Ptr CFmpzPolyQ -> IO CInt
fmpz_poly_q_print :: Ptr CFmpzPolyQ -> IO CInt
fmpz_poly_q_print Ptr CFmpzPolyQ
op = (Ptr CFmpzPolyQ -> IO CString) -> Ptr CFmpzPolyQ -> IO CInt
forall a. (Ptr a -> IO CString) -> Ptr a -> IO CInt
printCStr Ptr CFmpzPolyQ -> IO CString
fmpz_poly_q_get_str Ptr CFmpzPolyQ
op
  

-- | /fmpz_poly_q_print_pretty/ /op/ /x/ 
--
-- Prints the pretty representation of the rational function @op@ to
-- @stdout@.
fmpz_poly_q_print_pretty :: Ptr CFmpzPolyQ -> CString -> IO CInt
fmpz_poly_q_print_pretty :: Ptr CFmpzPolyQ -> CString -> IO CInt
fmpz_poly_q_print_pretty Ptr CFmpzPolyQ
op CString
x = 
  (Ptr CFmpzPolyQ -> IO CString) -> Ptr CFmpzPolyQ -> IO CInt
forall a. (Ptr a -> IO CString) -> Ptr a -> IO CInt
printCStr (Ptr CFmpzPolyQ -> CString -> IO CString
`fmpz_poly_q_get_str_pretty` CString
x) Ptr CFmpzPolyQ
op