{-# LINE 1 "src/Data/Number/Flint/Qadic/FFI.hsc" #-}
{-|
module      :  Data.Number.Flint.Qadic.FFI
copyright   :  (c) 2022 Hartmut Monien
license     :  GNU GPL, version 2 or above (see LICENSE)
maintainer  :  hmonien@uni-bonn.de
-}
module Data.Number.Flint.Qadic.FFI (
  -- * Unramified extensions over p-adic numbers
  -- 
  -- ** q-adic numbers 
  -- | Data structures
  -- We represent an element of the
  -- extension \(\mathbb{Q}_q \cong \mathbb{Q}_p[X]\ /\ f(X)\)
  -- as a polynomial in \(\mathbb{Q}_p[X]\) of degree less than \(\deg(f)\).
  -- As such, @qadic_struct@ and @qadic_t@ are typedef\'ed as
  -- @padic_poly_struct@ and @padic_poly_t@.
    Qadic (..)
  , CQadic (..)
  , newQadic
  , withQadic
  , withNewQadic
  , newQadicWithPrec
  , withNewQadicWithPrec
  -- * q-adic context
  --
  -- | Context
  -- We represent an unramified extension of \(\mathbb{Q}_p\) 
  -- via \(\mathbb{Q}_q \cong \mathbb{Q}_p[X]\ /\ f(X)\), 
  -- where \(f \in \mathbb{Q}_p[X]\) is a monic, irreducible polynomial which we
  -- assume to actually be in \(\mathbb{Z}[X]\). The first field in the
  -- context structure is a \(p\)-adic context struct @pctx@, which contains
  -- data about the prime \(p\), precomputed powers, the printing mode etc.
  -- The polynomial \(f\) is represented as a sparse polynomial using two
  -- arrays \(j\) and \(a\) of length @len@,
  -- where \(f(X) = \sum_{i} a_{i} X^{j_{i}}\).
  -- We also assume that the array \(j\) is sorted in ascending
  -- order. We choose this data structure to improve reduction modulo \(f(X)\)
  -- in \(\mathbb{Q}_p[X]\), assuming a sparse polynomial \(f(X)\)
  -- is chosen. The field @var@ contains the name of a generator of the
  -- extension, which is used when printing the elements.
  , QadicCtx (..)
  , CQadicCtx (..)
  , newQadicCtx
  , newQadicCtxConway
  , withQadicCtx
  , withNewQadicCtx
  , withNewQadicCtxConway
  , qadic_ctx_init
  , qadic_ctx_init_conway
  , qadic_ctx_clear
  , qadic_ctx_degree
  , qadic_ctx_print
  -- * Memory management
  , qadic_init
  , qadic_init2
  , qadic_clear
  , _fmpz_poly_reduce
  , _fmpz_mod_poly_reduce
  , qadic_reduce
  -- * Properties
  , qadic_val
  , qadic_prec
  -- * Randomisation
  , qadic_randtest
  , qadic_randtest_not_zero
  , qadic_randtest_val
  , qadic_randtest_int
  -- * Assignments and conversions
  , qadic_set
  , qadic_zero
  , qadic_one
  , qadic_gen
  , qadic_set_ui
  , qadic_get_padic
  -- * Comparison
  , qadic_is_zero
  , qadic_is_one
  , qadic_equal
  -- * Basic arithmetic
  , qadic_add
  , qadic_sub
  , qadic_neg
  , qadic_mul
  , _qadic_inv
  , qadic_inv
  , _qadic_pow
  , qadic_pow
  -- * Square root
  , qadic_sqrt
  -- * Special functions
  , _qadic_exp_rectangular
  , qadic_exp_rectangular
  , _qadic_exp_balanced
  , qadic_exp_balanced
  , _qadic_exp
  , qadic_exp
  , _qadic_log_rectangular
  , qadic_log_rectangular
  , _qadic_log_balanced
  , qadic_log_balanced
  , _qadic_log
  , qadic_log
  , _qadic_frobenius_a
  , _qadic_frobenius
  , qadic_frobenius
  , _qadic_teichmuller
  , qadic_teichmuller
  , _qadic_trace
  , _qadic_norm
  , qadic_norm
  , qadic_norm_analytic
  , qadic_norm_resultant
  -- * Output
  , qadic_fprint_pretty
  , qadic_print_pretty
) where

-- unramified extensions over p-adic numbers -----------------------------------

import Control.Monad

import Foreign.C.String
import Foreign.C.Types
import Foreign.ForeignPtr
import Foreign.Ptr ( Ptr, FunPtr, plusPtr, castPtr )
import Foreign.Storable
import Foreign.Marshal ( free )
import Foreign.Marshal.Array

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




-- qadic_t --------------------------------------------------------------------

data Qadic = Qadic {-# UNPACK #-} !(ForeignPtr CQadic)
type CQadic = CPadicPoly

-- | Create new q-adic
newQadic :: IO Qadic
newQadic = do
  ForeignPtr CQadic
x <- IO (ForeignPtr CQadic)
forall a. Storable a => IO (ForeignPtr a)
mallocForeignPtr
  ForeignPtr CQadic -> (Ptr CQadic -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr CQadic
x Ptr CQadic -> IO ()
qadic_init
  FinalizerPtr CQadic -> ForeignPtr CQadic -> IO ()
forall a. FinalizerPtr a -> ForeignPtr a -> IO ()
addForeignPtrFinalizer FinalizerPtr CQadic
p_qadic_clear ForeignPtr CQadic
x
  Qadic -> IO Qadic
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Qadic -> IO Qadic) -> Qadic -> IO Qadic
forall a b. (a -> b) -> a -> b
$ ForeignPtr CQadic -> Qadic
Qadic ForeignPtr CQadic
x

-- | Use q-adic
{-# INLINE withQadic #-}
withQadic :: Qadic -> (Ptr CQadic -> IO a) -> IO (Qadic, a)
withQadic (Qadic ForeignPtr CQadic
x) Ptr CQadic -> IO a
f = do
  ForeignPtr CQadic -> (Ptr CQadic -> IO (Qadic, a)) -> IO (Qadic, a)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr CQadic
x ((Ptr CQadic -> IO (Qadic, a)) -> IO (Qadic, a))
-> (Ptr CQadic -> IO (Qadic, a)) -> IO (Qadic, a)
forall a b. (a -> b) -> a -> b
$ \Ptr CQadic
px -> Ptr CQadic -> IO a
f Ptr CQadic
px IO a -> (a -> IO (Qadic, a)) -> IO (Qadic, a)
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Qadic, a) -> IO (Qadic, a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Qadic, a) -> IO (Qadic, a))
-> (a -> (Qadic, a)) -> a -> IO (Qadic, a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ForeignPtr CQadic -> Qadic
Qadic ForeignPtr CQadic
x,)

-- | Apply `f` to new q-adic
{-# INLINE withNewQadic #-}
withNewQadic :: (Ptr CQadic -> IO a) -> IO (Qadic, a)
withNewQadic Ptr CQadic -> IO a
f = do
  Qadic
x <- IO Qadic
newQadic
  Qadic -> (Ptr CQadic -> IO a) -> IO (Qadic, a)
forall {a}. Qadic -> (Ptr CQadic -> IO a) -> IO (Qadic, a)
withQadic Qadic
x Ptr CQadic -> IO a
f

newQadicWithPrec :: CLong -> IO Qadic
newQadicWithPrec CLong
prec = do
  ForeignPtr CQadic
x <- IO (ForeignPtr CQadic)
forall a. Storable a => IO (ForeignPtr a)
mallocForeignPtr
  ForeignPtr CQadic -> (Ptr CQadic -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr CQadic
x ((Ptr CQadic -> IO ()) -> IO ()) -> (Ptr CQadic -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr CQadic
x -> Ptr CQadic -> CLong -> IO ()
qadic_init2 Ptr CQadic
x CLong
prec
  FinalizerPtr CQadic -> ForeignPtr CQadic -> IO ()
forall a. FinalizerPtr a -> ForeignPtr a -> IO ()
addForeignPtrFinalizer FinalizerPtr CQadic
p_qadic_clear ForeignPtr CQadic
x
  Qadic -> IO Qadic
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Qadic -> IO Qadic) -> Qadic -> IO Qadic
forall a b. (a -> b) -> a -> b
$ ForeignPtr CQadic -> Qadic
Qadic ForeignPtr CQadic
x

-- | Apply `f` to new q-adic
{-# INLINE withNewQadicWithPrec #-}
withNewQadicWithPrec :: CLong -> (Ptr CQadic -> IO a) -> IO (Qadic, a)
withNewQadicWithPrec CLong
prec Ptr CQadic -> IO a
f = do
  Qadic
x <- CLong -> IO Qadic
newQadicWithPrec CLong
prec 
  Qadic -> (Ptr CQadic -> IO a) -> IO (Qadic, a)
forall {a}. Qadic -> (Ptr CQadic -> IO a) -> IO (Qadic, a)
withQadic Qadic
x Ptr CQadic -> IO a
f
  
-- qadic_ctx_t ----------------------------------------------------------------

data QadicCtx = QadicCtx {-# UNPACK #-} !(ForeignPtr CQadicCtx)
data CQadicCtx = CQadicCtx (Ptr CPadicCtx) (Ptr CFmpz) (Ptr CLong) CLong CString

instance Storable CQadicCtx where
  {-# INLINE sizeOf #-}
  sizeOf :: CQadicCtx -> Int
sizeOf CQadicCtx
_ = (Int
80)
{-# LINE 183 "src/Data/Number/Flint/Qadic/FFI.hsc" #-}
  {-# INLINE alignment #-}
  alignment :: CQadicCtx -> Int
alignment CQadicCtx
_ = Int
8
{-# LINE 185 "src/Data/Number/Flint/Qadic/FFI.hsc" #-}
  peek ptr = return CQadicCtx
    `ap` (return $ castPtr ptr)
    `ap` (\hsc_ptr -> peekByteOff hsc_ptr 48) ptr
{-# LINE 188 "src/Data/Number/Flint/Qadic/FFI.hsc" #-}
    `ap` (\hsc_ptr -> peekByteOff hsc_ptr 56) ptr
{-# LINE 189 "src/Data/Number/Flint/Qadic/FFI.hsc" #-}
    `ap` (\hsc_ptr -> peekByteOff hsc_ptr 64) ptr
{-# LINE 190 "src/Data/Number/Flint/Qadic/FFI.hsc" #-}
    `ap` (\hsc_ptr -> peekByteOff hsc_ptr 72) ptr
{-# LINE 191 "src/Data/Number/Flint/Qadic/FFI.hsc" #-}
  poke = undefined

{-# INLINE _newQadicCtx #-}
_newQadicCtx :: (Ptr CQadicCtx -> Ptr CFmpz -> t -> t -> t -> CString -> t -> IO a)
-> Fmpz -> t -> t -> t -> String -> t -> IO QadicCtx
_newQadicCtx Ptr CQadicCtx -> Ptr CFmpz -> t -> t -> t -> CString -> t -> IO a
f Fmpz
p t
d t
min t
max String
var t
mode = do
  ForeignPtr CQadicCtx
x <- IO (ForeignPtr CQadicCtx)
forall a. Storable a => IO (ForeignPtr a)
mallocForeignPtr
  ForeignPtr CQadicCtx
-> (Ptr CQadicCtx -> IO (Fmpz, a)) -> IO (Fmpz, a)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr CQadicCtx
x ((Ptr CQadicCtx -> IO (Fmpz, a)) -> IO (Fmpz, a))
-> (Ptr CQadicCtx -> IO (Fmpz, a)) -> IO (Fmpz, a)
forall a b. (a -> b) -> a -> b
$ \Ptr CQadicCtx
x -> do
    Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
forall {a}. Fmpz -> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
withFmpz Fmpz
p ((Ptr CFmpz -> IO a) -> IO (Fmpz, a))
-> (Ptr CFmpz -> IO a) -> IO (Fmpz, a)
forall a b. (a -> b) -> a -> b
$ \Ptr CFmpz
p -> do
      String -> (CString -> IO a) -> IO a
forall a. String -> (CString -> IO a) -> IO a
withCString String
var ((CString -> IO a) -> IO a) -> (CString -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \CString
var -> do
        Ptr CQadicCtx -> Ptr CFmpz -> t -> t -> t -> CString -> t -> IO a
f Ptr CQadicCtx
x Ptr CFmpz
p t
d t
min t
max CString
var t
mode
  FinalizerPtr CQadicCtx -> ForeignPtr CQadicCtx -> IO ()
forall a. FinalizerPtr a -> ForeignPtr a -> IO ()
addForeignPtrFinalizer FinalizerPtr CQadicCtx
p_qadic_ctx_clear ForeignPtr CQadicCtx
x
  QadicCtx -> IO QadicCtx
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (QadicCtx -> IO QadicCtx) -> QadicCtx -> IO QadicCtx
forall a b. (a -> b) -> a -> b
$ ForeignPtr CQadicCtx -> QadicCtx
QadicCtx ForeignPtr CQadicCtx
x

-- | Create q-adic context with prime \(p\), extension \(d\),
-- precomputed powers \(p^{min}\) to \(p^{max}\) and `PadicPrintMode`
-- @mode@. Initialized with `qadic_ctx_init`.
newQadicCtx :: Fmpz
-> CLong
-> CLong
-> CLong
-> String
-> PadicPrintMode
-> IO QadicCtx
newQadicCtx = (Ptr CQadicCtx
 -> Ptr CFmpz
 -> CLong
 -> CLong
 -> CLong
 -> CString
 -> PadicPrintMode
 -> IO ())
-> Fmpz
-> CLong
-> CLong
-> CLong
-> String
-> PadicPrintMode
-> IO QadicCtx
forall {t} {t} {t} {t} {a}.
(Ptr CQadicCtx -> Ptr CFmpz -> t -> t -> t -> CString -> t -> IO a)
-> Fmpz -> t -> t -> t -> String -> t -> IO QadicCtx
_newQadicCtx Ptr CQadicCtx
-> Ptr CFmpz
-> CLong
-> CLong
-> CLong
-> CString
-> PadicPrintMode
-> IO ()
qadic_ctx_init
-- | Create q-adic context with prime \(p\), extension \(d\),
-- precomputed powers \(p^{min}\) to \(p^{max}\) and `PadicPrintMode`
-- @mode@. Initialized with `qadic_ctx_init_conway`.
newQadicCtxConway :: Fmpz
-> CLong
-> CLong
-> CLong
-> String
-> PadicPrintMode
-> IO QadicCtx
newQadicCtxConway = (Ptr CQadicCtx
 -> Ptr CFmpz
 -> CLong
 -> CLong
 -> CLong
 -> CString
 -> PadicPrintMode
 -> IO ())
-> Fmpz
-> CLong
-> CLong
-> CLong
-> String
-> PadicPrintMode
-> IO QadicCtx
forall {t} {t} {t} {t} {a}.
(Ptr CQadicCtx -> Ptr CFmpz -> t -> t -> t -> CString -> t -> IO a)
-> Fmpz -> t -> t -> t -> String -> t -> IO QadicCtx
_newQadicCtx Ptr CQadicCtx
-> Ptr CFmpz
-> CLong
-> CLong
-> CLong
-> CString
-> PadicPrintMode
-> IO ()
qadic_ctx_init_conway

-- | Use q-adic context
{-# INLINE withQadicCtx #-}
withQadicCtx :: QadicCtx -> (Ptr CQadicCtx -> IO a) -> IO (QadicCtx, a)
withQadicCtx (QadicCtx ForeignPtr CQadicCtx
x) Ptr CQadicCtx -> IO a
f = do
  ForeignPtr CQadicCtx
-> (Ptr CQadicCtx -> IO (QadicCtx, a)) -> IO (QadicCtx, a)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr CQadicCtx
x ((Ptr CQadicCtx -> IO (QadicCtx, a)) -> IO (QadicCtx, a))
-> (Ptr CQadicCtx -> IO (QadicCtx, a)) -> IO (QadicCtx, a)
forall a b. (a -> b) -> a -> b
$ \Ptr CQadicCtx
px -> Ptr CQadicCtx -> IO a
f Ptr CQadicCtx
px IO a -> (a -> IO (QadicCtx, a)) -> IO (QadicCtx, a)
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (QadicCtx, a) -> IO (QadicCtx, a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ((QadicCtx, a) -> IO (QadicCtx, a))
-> (a -> (QadicCtx, a)) -> a -> IO (QadicCtx, a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ForeignPtr CQadicCtx -> QadicCtx
QadicCtx ForeignPtr CQadicCtx
x,)

_withNewQadicCtx :: (t -> t -> t -> t -> t -> t -> IO QadicCtx)
-> t
-> t
-> t
-> t
-> t
-> t
-> (Ptr CQadicCtx -> IO a)
-> IO (QadicCtx, a)
_withNewQadicCtx t -> t -> t -> t -> t -> t -> IO QadicCtx
initialize t
p t
d t
min t
max t
var t
mode Ptr CQadicCtx -> IO a
f = do
  QadicCtx
x <- t -> t -> t -> t -> t -> t -> IO QadicCtx
initialize t
p t
d t
min t
max t
var t
mode
  QadicCtx -> (Ptr CQadicCtx -> IO a) -> IO (QadicCtx, a)
forall {a}. QadicCtx -> (Ptr CQadicCtx -> IO a) -> IO (QadicCtx, a)
withQadicCtx QadicCtx
x Ptr CQadicCtx -> IO a
f

withNewQadicCtx :: Fmpz
-> CLong
-> CLong
-> CLong
-> String
-> PadicPrintMode
-> (Ptr CQadicCtx -> IO a)
-> IO (QadicCtx, a)
withNewQadicCtx       = (Fmpz
 -> CLong
 -> CLong
 -> CLong
 -> String
 -> PadicPrintMode
 -> IO QadicCtx)
-> Fmpz
-> CLong
-> CLong
-> CLong
-> String
-> PadicPrintMode
-> (Ptr CQadicCtx -> IO a)
-> IO (QadicCtx, a)
forall {t} {t} {t} {t} {t} {t} {a}.
(t -> t -> t -> t -> t -> t -> IO QadicCtx)
-> t
-> t
-> t
-> t
-> t
-> t
-> (Ptr CQadicCtx -> IO a)
-> IO (QadicCtx, a)
_withNewQadicCtx Fmpz
-> CLong
-> CLong
-> CLong
-> String
-> PadicPrintMode
-> IO QadicCtx
newQadicCtx
withNewQadicCtxConway :: Fmpz
-> CLong
-> CLong
-> CLong
-> String
-> PadicPrintMode
-> (Ptr CQadicCtx -> IO a)
-> IO (QadicCtx, a)
withNewQadicCtxConway = (Fmpz
 -> CLong
 -> CLong
 -> CLong
 -> String
 -> PadicPrintMode
 -> IO QadicCtx)
-> Fmpz
-> CLong
-> CLong
-> CLong
-> String
-> PadicPrintMode
-> (Ptr CQadicCtx -> IO a)
-> IO (QadicCtx, a)
forall {t} {t} {t} {t} {t} {t} {a}.
(t -> t -> t -> t -> t -> t -> IO QadicCtx)
-> t
-> t
-> t
-> t
-> t
-> t
-> (Ptr CQadicCtx -> IO a)
-> IO (QadicCtx, a)
_withNewQadicCtx Fmpz
-> CLong
-> CLong
-> CLong
-> String
-> PadicPrintMode
-> IO QadicCtx
newQadicCtxConway

--------------------------------------------------------------------------------

-- | /qadic_ctx_init/ /ctx/ /p/ /d/ /min/ /max/ /var/ /mode/ 
-- 
-- Initialises the context @ctx@ with prime \(p\), extension degree \(d\),
-- variable name @var@ and printing mode @mode@. The defining polynomial is
-- chosen as a Conway polynomial if possible and otherwise as a random
-- sparse polynomial.
-- 
-- Stores powers of \(p\) with exponents between @min@ (inclusive) and
-- @max@ exclusive. Assumes that @min@ is at most @max@.
-- 
-- Assumes that \(p\) is a prime.
-- 
-- Assumes that the string @var@ is a null-terminated string of length at
-- least one.
-- 
-- Assumes that the printing mode is one of @PADIC_TERSE@, @PADIC_SERIES@,
-- or @PADIC_VAL_UNIT@.
-- 
-- This function also carries out some relevant precomputation for
-- arithmetic in \(\mathbb{Q}_p / (p^N)\) such as powers of \(p\) close to
-- \(p^N\).
foreign import ccall "qadic.h qadic_ctx_init"
  qadic_ctx_init :: Ptr CQadicCtx -> Ptr CFmpz -> CLong -> CLong -> CLong -> CString -> PadicPrintMode -> IO ()

-- | /qadic_ctx_init_conway/ /ctx/ /p/ /d/ /min/ /max/ /var/ /mode/ 
-- 
-- Initialises the context @ctx@ with prime \(p\), extension degree \(d\),
-- variable name @var@ and printing mode @mode@. The defining polynomial is
-- chosen as a Conway polynomial, hence has restrictions on the prime and
-- the degree.
-- 
-- Stores powers of \(p\) with exponents between @min@ (inclusive) and
-- @max@ exclusive. Assumes that @min@ is at most @max@.
-- 
-- Assumes that \(p\) is a prime.
-- 
-- Assumes that the string @var@ is a null-terminated string of length at
-- least one.
-- 
-- Assumes that the printing mode is one of @PADIC_TERSE@, @PADIC_SERIES@,
-- or @PADIC_VAL_UNIT@.
-- 
-- This function also carries out some relevant precomputation for
-- arithmetic in \(\mathbb{Q}_p / (p^N)\) such as powers of \(p\) close to
-- \(p^N\).
foreign import ccall "qadic.h qadic_ctx_init_conway"
  qadic_ctx_init_conway :: Ptr CQadicCtx -> Ptr CFmpz -> CLong -> CLong -> CLong -> CString -> PadicPrintMode -> IO ()

-- | /qadic_ctx_clear/ /ctx/ 
-- 
-- Clears all memory that has been allocated as part of the context.
foreign import ccall "qadic.h qadic_ctx_clear"
  qadic_ctx_clear :: Ptr CQadicCtx -> IO ()

foreign import ccall "qadic.h &qadic_ctx_clear"
  p_qadic_ctx_clear :: FunPtr (Ptr CQadicCtx -> IO ())

-- | /qadic_ctx_degree/ /ctx/ 
-- 
-- Returns the extension degree.
foreign import ccall "qadic.h qadic_ctx_degree"
  qadic_ctx_degree :: Ptr CQadicCtx -> IO CLong

-- | /qadic_ctx_print/ /ctx/ 
-- 
-- Prints the data from the given context.
qadic_ctx_print :: Ptr CQadicCtx -> IO ()
qadic_ctx_print Ptr CQadicCtx
ctx = do
  CQadicCtx Ptr CPadicCtx
pctx Ptr CFmpz
a Ptr CLong
j CLong
len CString
var <- Ptr CQadicCtx -> IO CQadicCtx
forall a. Storable a => Ptr a -> IO a
peek Ptr CQadicCtx
ctx
  CPadicCtx Ptr CFmpz
p CDouble
_ Ptr CFmpz
_ CLong
_ CLong
_ PadicPrintMode
mode <- Ptr CPadicCtx -> IO CPadicCtx
forall a. Storable a => Ptr a -> IO a
peek Ptr CPadicCtx
pctx
  String -> IO ()
putStr String
"p    = "
  Ptr CFmpz -> IO CInt
fmpz_print Ptr CFmpz
p
  String -> IO ()
putStr String
"\n"
  CLong
d <- Ptr CLong -> IO CLong
forall a. Storable a => Ptr a -> IO a
peek (Ptr CLong
j Ptr CLong -> Int -> Ptr CLong
forall a. Storable a => Ptr a -> Int -> Ptr a
`advancePtr` (CLong -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CLong
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1))
  String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"d    = " String -> String -> String
forall a. [a] -> [a] -> [a]
++ CLong -> String
forall a. Show a => a -> String
show CLong
d
  String -> IO ()
putStr String
"f(X) = "
  Ptr CFmpz -> IO CInt
fmpz_print Ptr CFmpz
a
  [Int] -> (Int -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
1 .. CLong -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CLong
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1] ((Int -> IO ()) -> IO ()) -> (Int -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Int
k -> do
    CLong
i <- Ptr CLong -> IO CLong
forall a. Storable a => Ptr a -> IO a
peek (Ptr CLong
j Ptr CLong -> Int -> Ptr CLong
forall a. Storable a => Ptr a -> Int -> Ptr a
`advancePtr` Int
k)
    CInt
flag1 <- Ptr CFmpz -> IO CInt
fmpz_is_zero (Ptr CFmpz
a Ptr CFmpz -> Int -> Ptr CFmpz
forall a. Storable a => Ptr a -> Int -> Ptr a
`advancePtr` Int
k)
    case CInt
flag1 of 
      CInt
1 -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
      CInt
_ -> do
        String -> IO ()
putStr String
" + " 
        CInt
flag <- Ptr CFmpz -> IO CInt
fmpz_is_one (Ptr CFmpz
a Ptr CFmpz -> Int -> Ptr CFmpz
forall a. Storable a => Ptr a -> Int -> Ptr a
`advancePtr` Int
k)
        case CInt
flag of 
          CInt
1 -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
          CInt
_ -> do
            Ptr CFmpz -> IO CInt
fmpz_print (Ptr CFmpz
a Ptr CFmpz -> Int -> Ptr CFmpz
forall a. Storable a => Ptr a -> Int -> Ptr a
`advancePtr` Int
k)
            String -> IO ()
putStr String
"*"
        String -> IO ()
putStr String
"X"
        Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ( CLong
i CLong -> CLong -> Bool
forall a. Eq a => a -> a -> Bool
/= CLong
1 ) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStr (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"^" String -> String -> String
forall a. [a] -> [a] -> [a]
++ CLong -> String
forall a. Show a => a -> String
show CLong
i

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

-- | /qadic_init/ /rop/ 
-- 
-- Initialises the element @rop@, setting its value to \(0\).
foreign import ccall "qadic.h qadic_init"
  qadic_init :: Ptr CQadic -> IO ()

-- | /qadic_init2/ /rop/ /prec/ 
-- 
-- Initialises the element @rop@ with the given output precision, setting
-- the value to \(0\).
foreign import ccall "qadic.h qadic_init2"
  qadic_init2 :: Ptr CQadic -> CLong -> IO ()

-- | /qadic_clear/ /rop/ 
-- 
-- Clears the element @rop@.
foreign import ccall "qadic.h qadic_clear"
  qadic_clear :: Ptr CQadic -> IO ()

foreign import ccall "qadic.h &qadic_clear"
  p_qadic_clear :: FunPtr (Ptr CQadic -> IO ())

-- | /_fmpz_poly_reduce/ /R/ /lenR/ /a/ /j/ /len/ 
-- 
-- Reduces a polynomial @(R, lenR)@ modulo a sparse monic
-- polynomial \(f(X) = \sum_{i} a_{i} X^{j_{i}}\) of degree at least \(2\).
-- 
-- Assumes that the array \(j\) of positive length @len@ is sorted in
-- ascending order.
-- 
-- Allows zero-padding in @(R, lenR)@.
foreign import ccall "qadic.h _fmpz_poly_reduce"
  _fmpz_poly_reduce :: Ptr CFmpz -> CLong -> Ptr CFmpz -> Ptr CLong -> CLong -> IO ()

-- | /_fmpz_mod_poly_reduce/ /R/ /lenR/ /a/ /j/ /len/ /p/ 
-- 
-- Reduces a polynomial @(R, lenR)@ modulo a sparse monic
-- polynomial \(f(X) = \sum_{i} a_{i} X^{j_{i}}\) of degree at least \(2\) in
-- \(\mathbb{Z}/(p)\), where \(p\) is typically a prime power.
-- 
-- Assumes that the array \(j\) of positive length @len@ is sorted in
-- ascending order.
-- 
-- Allows zero-padding in @(R, lenR)@.
foreign import ccall "qadic.h _fmpz_mod_poly_reduce"
  _fmpz_mod_poly_reduce :: Ptr CFmpz -> CLong -> Ptr CFmpz -> Ptr CLong -> CLong -> Ptr CFmpz -> IO ()

-- | /qadic_reduce/ /rop/ /ctx/ 
-- 
-- Reduces @rop@ modulo \(f(X)\) and \(p^N\).
foreign import ccall "qadic.h qadic_reduce"
  qadic_reduce :: Ptr CQadic -> Ptr CQadicCtx -> IO ()

-- Properties ------------------------------------------------------------------

-- | /qadic_val/ /op/ 
-- 
-- Returns the valuation of @op@.
foreign import ccall "qadic.h qadic_val"
  qadic_val :: Ptr CQadic -> IO CLong

-- | /qadic_prec/ /op/ 
-- 
-- Returns the precision of @op@.
foreign import ccall "qadic.h qadic_prec"
  qadic_prec :: Ptr CQadic -> IO CLong

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

-- | /qadic_randtest/ /rop/ /state/ /ctx/ 
-- 
-- Generates a random element of \(\mathbb{Q}_q\).
foreign import ccall "qadic.h qadic_randtest"
  qadic_randtest :: Ptr CQadic -> Ptr CFRandState -> Ptr CQadicCtx -> IO ()

-- | /qadic_randtest_not_zero/ /rop/ /state/ /ctx/ 
-- 
-- Generates a random non-zero element of \(\mathbb{Q}_q\).
foreign import ccall "qadic.h qadic_randtest_not_zero"
  qadic_randtest_not_zero :: Ptr CQadic -> Ptr CFRandState -> Ptr CQadicCtx -> IO ()

-- | /qadic_randtest_val/ /rop/ /state/ /v/ /ctx/ 
-- 
-- Generates a random element of \(\mathbb{Q}_q\) with prescribed valuation
-- @val@.
-- 
-- Note that if \(v \geq N\) then the element is necessarily zero.
foreign import ccall "qadic.h qadic_randtest_val"
  qadic_randtest_val :: Ptr CQadic -> Ptr CFRandState -> CLong -> Ptr CQadicCtx -> IO ()

-- | /qadic_randtest_int/ /rop/ /state/ /ctx/ 
-- 
-- Generates a random element of \(\mathbb{Q}_q\) with non-negative
-- valuation.
foreign import ccall "qadic.h qadic_randtest_int"
  qadic_randtest_int :: Ptr CQadic -> Ptr CFRandState -> Ptr CQadicCtx -> IO ()

-- Assignments and conversions -------------------------------------------------

-- | /qadic_set/ /rop/ /op/ 
-- 
-- Sets @rop@ to @op@.
foreign import ccall "qadic.h qadic_set"
  qadic_set :: Ptr CQadic -> Ptr CQadic -> IO ()

-- | /qadic_zero/ /rop/ 
-- 
-- Sets @rop@ to zero.
foreign import ccall "qadic.h qadic_zero"
  qadic_zero :: Ptr CQadic -> IO ()

-- | /qadic_one/ /rop/ /ctx/ 
-- 
-- Sets @rop@ to one, reduced in the given context.
-- 
-- Note that if the precision \(N\) is non-positive then @rop@ is actually
-- set to zero.
foreign import ccall "qadic.h qadic_one"
  qadic_one :: Ptr CQadic -> Ptr CQadicCtx -> IO ()

-- | /qadic_gen/ /rop/ /ctx/ 
-- 
-- Sets @rop@ to the generator \(X\) for the extension when \(N > 0\), and
-- zero otherwise. If the extension degree is one, raises an abort signal.
foreign import ccall "qadic.h qadic_gen"
  qadic_gen :: Ptr CQadic -> Ptr CQadicCtx -> IO ()

-- | /qadic_set_ui/ /rop/ /op/ /ctx/ 
-- 
-- Sets @rop@ to the integer @op@, reduced in the context.
foreign import ccall "qadic.h qadic_set_ui"
  qadic_set_ui :: Ptr CQadic -> CULong -> Ptr CQadicCtx -> IO ()

-- | /qadic_get_padic/ /rop/ /op/ /ctx/ 
-- 
-- If the element @op@ lies in \(\mathbb{Q}_p\), sets @rop@ to its value
-- and returns \(1\); otherwise, returns \(0\).
foreign import ccall "qadic.h qadic_get_padic"
  qadic_get_padic :: Ptr CPadic -> Ptr CQadic -> Ptr CQadicCtx -> IO CInt

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

-- | /qadic_is_zero/ /op/ 
-- 
-- Returns whether @op@ is equal to zero.
foreign import ccall "qadic.h qadic_is_zero"
  qadic_is_zero :: Ptr CQadic -> IO CInt

-- | /qadic_is_one/ /op/ /ctx/ 
-- 
-- Returns whether @op@ is equal to one in the given context.
foreign import ccall "qadic.h qadic_is_one"
  qadic_is_one :: Ptr CQadic -> Ptr CQadicCtx -> IO CInt

-- | /qadic_equal/ /op1/ /op2/ 
-- 
-- Returns whether @op1@ and @op2@ are equal.
foreign import ccall "qadic.h qadic_equal"
  qadic_equal :: Ptr CQadic -> Ptr CQadic -> IO CInt

-- Basic arithmetic ------------------------------------------------------------

-- | /qadic_add/ /rop/ /op1/ /op2/ /ctx/ 
-- 
-- Sets @rop@ to the sum of @op1@ and @op2@.
-- 
-- Assumes that both @op1@ and @op2@ are reduced in the given context and
-- ensures that @rop@ is, too.
foreign import ccall "qadic.h qadic_add"
  qadic_add :: Ptr CQadic -> Ptr CQadic -> Ptr CQadic -> Ptr CQadicCtx -> IO ()

-- | /qadic_sub/ /rop/ /op1/ /op2/ /ctx/ 
-- 
-- Sets @rop@ to the difference of @op1@ and @op2@.
-- 
-- Assumes that both @op1@ and @op2@ are reduced in the given context and
-- ensures that @rop@ is, too.
foreign import ccall "qadic.h qadic_sub"
  qadic_sub :: Ptr CQadic -> Ptr CQadic -> Ptr CQadic -> Ptr CQadicCtx -> IO ()

-- | /qadic_neg/ /rop/ /op/ /ctx/ 
-- 
-- Sets @rop@ to the negative of @op@.
-- 
-- Assumes that @op@ is reduced in the given context and ensures that @rop@
-- is, too.
foreign import ccall "qadic.h qadic_neg"
  qadic_neg :: Ptr CQadic -> Ptr CQadic -> Ptr CQadicCtx -> IO ()

-- | /qadic_mul/ /rop/ /op1/ /op2/ /ctx/ 
-- 
-- Sets @rop@ to the product of @op1@ and @op2@, reducing the output in the
-- given context.
foreign import ccall "qadic.h qadic_mul"
  qadic_mul :: Ptr CQadic -> Ptr CQadic -> Ptr CQadic -> Ptr CQadicCtx -> IO ()

-- | /_qadic_inv/ /rop/ /op/ /len/ /a/ /j/ /lena/ /p/ /N/ 
-- 
-- Sets @(rop, d)@ to the inverse of @(op, len)@ modulo \(f(X)\) given by
-- @(a,j,lena)@ and \(p^N\).
-- 
-- Assumes that @(op,len)@ has valuation \(0\), that is, that it represents
-- a \(p\)-adic unit.
-- 
-- Assumes that @len@ is at most \(d\).
-- 
-- Does not support aliasing.
foreign import ccall "qadic.h _qadic_inv"
  _qadic_inv :: Ptr CFmpz -> Ptr CFmpz -> CLong -> Ptr CFmpz -> Ptr CLong -> CLong -> Ptr CFmpz -> CLong -> IO ()

-- | /qadic_inv/ /rop/ /op/ /ctx/ 
-- 
-- Sets @rop@ to the inverse of @op@, reduced in the given context.
foreign import ccall "qadic.h qadic_inv"
  qadic_inv :: Ptr CQadic -> Ptr CQadic -> Ptr CQadicCtx -> IO ()

-- | /_qadic_pow/ /rop/ /op/ /len/ /e/ /a/ /j/ /lena/ /p/ 
-- 
-- Sets @(rop, 2*d-1)@ to @(op,len)@ raised to the power \(e\), reduced
-- modulo \(f(X)\) given by @(a, j, lena)@ and \(p\), which is expected to
-- be a prime power.
-- 
-- Assumes that \(e \geq 0\) and that @len@ is positive and at most \(d\).
-- 
-- Although we require that @rop@ provides space for \(2d - 1\)
-- coefficients, the output will be reduces modulo \(f(X)\), which is a
-- polynomial of degree \(d\).
-- 
-- Does not support aliasing.
foreign import ccall "qadic.h _qadic_pow"
  _qadic_pow :: Ptr CFmpz -> Ptr CFmpz -> CLong -> Ptr CFmpz -> Ptr CFmpz -> Ptr CLong -> CLong -> Ptr CFmpz -> IO ()

-- | /qadic_pow/ /rop/ /op/ /e/ /ctx/ 
-- 
-- Sets @rop@ the @op@ raised to the power \(e\).
-- 
-- Currently assumes that \(e \geq 0\).
-- 
-- Note that for any input @op@, @rop@ is set to one in the given context
-- whenever \(e = 0\).
foreign import ccall "qadic.h qadic_pow"
  qadic_pow :: Ptr CQadic -> Ptr CQadic -> Ptr CFmpz -> Ptr CQadicCtx -> IO ()

-- Square root -----------------------------------------------------------------

-- | /qadic_sqrt/ /rop/ /op/ /ctx/ 
-- 
-- Return @1@ if the input is a square (to input precision). If so, set
-- @rop@ to a square root (truncated to output precision).
foreign import ccall "qadic.h qadic_sqrt"
  qadic_sqrt :: Ptr CQadic -> Ptr CQadic -> Ptr CQadicCtx -> IO CInt

-- Special functions -----------------------------------------------------------

-- | /_qadic_exp_rectangular/ /rop/ /op/ /v/ /len/ /a/ /j/ /lena/ /p/ /N/ /pN/ 
-- 
-- Sets @(rop, 2*d - 1)@ to the exponential of @(op, v, len)@ reduced
-- modulo \(p^N\), assuming that the series converges.
-- 
-- Assumes that @(op, v, len)@ is non-zero.
-- 
-- Does not support aliasing.
foreign import ccall "qadic.h _qadic_exp_rectangular"
  _qadic_exp_rectangular :: Ptr CFmpz -> Ptr CFmpz -> CLong -> CLong -> Ptr CFmpz -> Ptr CLong -> CLong -> Ptr CFmpz -> CLong -> Ptr CFmpz -> IO ()

-- | /qadic_exp_rectangular/ /rop/ /op/ /ctx/ 
-- 
-- Returns whether the exponential series converges at @op@ and sets @rop@
-- to its value reduced modulo in the given context.
foreign import ccall "qadic.h qadic_exp_rectangular"
  qadic_exp_rectangular :: Ptr CQadic -> Ptr CQadic -> Ptr CQadicCtx -> IO CInt

-- | /_qadic_exp_balanced/ /rop/ /x/ /v/ /len/ /a/ /j/ /lena/ /p/ /N/ /pN/ 
-- 
-- Sets @(rop, d)@ to the exponential of @(op, v, len)@ reduced modulo
-- \(p^N\), assuming that the series converges.
-- 
-- Assumes that @len@ is in \([1,d)\) but supports zero padding, including
-- the special case when @(op, len)@ is zero.
-- 
-- Supports aliasing between @rop@ and @op@.
foreign import ccall "qadic.h _qadic_exp_balanced"
  _qadic_exp_balanced :: Ptr CFmpz -> Ptr CFmpz -> CLong -> CLong -> Ptr CFmpz -> Ptr CLong -> CLong -> Ptr CFmpz -> CLong -> Ptr CFmpz -> IO ()

-- | /qadic_exp_balanced/ /rop/ /op/ /ctx/ 
-- 
-- Returns whether the exponential series converges at @op@ and sets @rop@
-- to its value reduced modulo in the given context.
foreign import ccall "qadic.h qadic_exp_balanced"
  qadic_exp_balanced :: Ptr CQadic -> Ptr CQadic -> Ptr CQadicCtx -> IO CInt

-- | /_qadic_exp/ /rop/ /op/ /v/ /len/ /a/ /j/ /lena/ /p/ /N/ 
-- 
-- Sets @(rop, 2*d - 1)@ to the exponential of @(op, v, len)@ reduced
-- modulo \(p^N\), assuming that the series converges.
-- 
-- Assumes that @(op, v, len)@ is non-zero.
-- 
-- Does not support aliasing.
foreign import ccall "qadic.h _qadic_exp"
  _qadic_exp :: Ptr CFmpz -> Ptr CFmpz -> CLong -> CLong -> Ptr CFmpz -> Ptr CLong -> CLong -> Ptr CFmpz -> CLong -> IO ()

-- | /qadic_exp/ /rop/ /op/ /ctx/ 
-- 
-- Returns whether the exponential series converges at @op@ and sets @rop@
-- to its value reduced modulo in the given context.
-- 
-- The exponential series converges if the valuation of @op@ is at least
-- \(2\) or \(1\) when \(p\) is even or odd, respectively.
foreign import ccall "qadic.h qadic_exp"
  qadic_exp :: Ptr CQadic -> Ptr CQadic -> Ptr CQadicCtx -> IO CInt

-- | /_qadic_log_rectangular/ /z/ /y/ /v/ /len/ /a/ /j/ /lena/ /p/ /N/ /pN/ 
-- 
-- Computes
-- 
-- \[`\]
-- \[z = - \sum_{i = 1}^{\infty} \frac{y^i}{i} \pmod{p^N}.\]
-- 
-- Note that this can be used to compute the \(p\)-adic logarithm via the
-- equation
-- 
-- \[`\]
-- \[\begin{aligned}
-- \log(x) & = \sum_{i=1}^{\infty} (-1)^{i-1} \frac{(x-1)^i}{i} \\
--         & = - \sum_{i=1}^{\infty} \frac{(1-x)^i}{i}.
-- \end{aligned}\]
-- 
-- Assumes that \(y = 1 - x\) is non-zero and that
-- \(v = \operatorname{ord}_p(y)\) is at least \(1\) when \(p\) is odd and
-- at least \(2\) when \(p = 2\) so that the series converges.
-- 
-- Assumes that \(y\) is reduced modulo \(p^N\).
-- 
-- Assumes that \(v < N\), and in particular \(N \geq 2\).
-- 
-- Supports aliasing between \(y\) and \(z\).
foreign import ccall "qadic.h _qadic_log_rectangular"
  _qadic_log_rectangular :: Ptr CFmpz -> Ptr CFmpz -> CLong -> CLong -> Ptr CFmpz -> Ptr CLong -> CLong -> Ptr CFmpz -> CLong -> Ptr CFmpz -> IO ()

-- | /qadic_log_rectangular/ /rop/ /op/ /ctx/ 
-- 
-- Returns whether the \(p\)-adic logarithm function converges at @op@, and
-- if so sets @rop@ to its value.
foreign import ccall "qadic.h qadic_log_rectangular"
  qadic_log_rectangular :: Ptr CQadic -> Ptr CQadic -> Ptr CPadicCtx -> IO CInt

-- | /_qadic_log_balanced/ /z/ /y/ /len/ /a/ /j/ /lena/ /p/ /N/ /pN/ 
-- 
-- Computes \((z, d)\) as
-- 
-- \[`\]
-- \[z = - \sum_{i = 1}^{\infty} \frac{y^i}{i} \pmod{p^N}.\]
-- 
-- Assumes that \(v = \operatorname{ord}_p(y)\) is at least \(1\) when
-- \(p\) is odd and at least \(2\) when \(p = 2\) so that the series
-- converges.
-- 
-- Supports aliasing between \(z\) and \(y\).
foreign import ccall "qadic.h _qadic_log_balanced"
  _qadic_log_balanced :: Ptr CFmpz -> Ptr CFmpz -> CLong -> Ptr CFmpz -> Ptr CLong -> CLong -> Ptr CFmpz -> CLong -> Ptr CFmpz -> IO ()

-- | /qadic_log_balanced/ /rop/ /op/ /ctx/ 
-- 
-- Returns whether the \(p\)-adic logarithm function converges at @op@, and
-- if so sets @rop@ to its value.
foreign import ccall "qadic.h qadic_log_balanced"
  qadic_log_balanced :: Ptr CQadic -> Ptr CQadic -> Ptr CQadicCtx -> IO CInt

-- | /_qadic_log/ /z/ /y/ /v/ /len/ /a/ /j/ /lena/ /p/ /N/ /pN/ 
-- 
-- Computes \((z, d)\) as
-- 
-- \[`\]
-- \[z = - \sum_{i = 1}^{\infty} \frac{y^i}{i} \pmod{p^N}.\]
-- 
-- Note that this can be used to compute the \(p\)-adic logarithm via the
-- equation
-- 
-- \[`\]
-- \[\begin{aligned}
-- \log(x) & = \sum_{i=1}^{\infty} (-1)^{i-1} \frac{(x-1)^i}{i} \\
--         & = - \sum_{i=1}^{\infty} \frac{(1-x)^i}{i}.
-- \end{aligned}\]
-- 
-- Assumes that \(y = 1 - x\) is non-zero and that
-- \(v = \operatorname{ord}_p(y)\) is at least \(1\) when \(p\) is odd and
-- at least \(2\) when \(p = 2\) so that the series converges.
-- 
-- Assumes that \((y, d)\) is reduced modulo \(p^N\).
-- 
-- Assumes that \(v < N\), and hence in particular \(N \geq 2\).
-- 
-- Supports aliasing between \(z\) and \(y\).
foreign import ccall "qadic.h _qadic_log"
  _qadic_log :: Ptr CFmpz -> Ptr CFmpz -> CLong -> CLong -> Ptr CFmpz -> Ptr CLong -> CLong -> Ptr CFmpz -> CLong -> Ptr CFmpz -> IO ()

-- | /qadic_log/ /rop/ /op/ /ctx/ 
-- 
-- Returns whether the \(p\)-adic logarithm function converges at @op@, and
-- if so sets @rop@ to its value.
-- 
-- The \(p\)-adic logarithm function is defined by the usual series
-- 
-- \[`\]
-- \[\log_p(x) = \sum_{i=1}^{\infty} (-1)^{i-1} \frac{(x-1)^i}{i}\]
-- 
-- but this only converges when \(\operatorname{ord}_p(x)\) is at least
-- \(2\) or \(1\) when \(p = 2\) or \(p > 2\), respectively.
foreign import ccall "qadic.h qadic_log"
  qadic_log :: Ptr CQadic -> Ptr CQadic -> Ptr CQadicCtx -> IO CInt

-- | /_qadic_frobenius_a/ /rop/ /e/ /a/ /j/ /lena/ /p/ /N/ 
-- 
-- Computes \(\sigma^e(X) \bmod{p^N}\) where \(X\) is such that
-- \(\mathbb{Q}_q \cong \mathbb{Q}_p[X]/(f(X))\).
-- 
-- Assumes that the precision \(N\) is at least \(2\) and that the
-- extension is non-trivial, i.e.\(d \geq 2\).
-- 
-- Assumes that \(0 < e < d\).
-- 
-- Sets @(rop, 2*d-1)@, although the actual length of the output will be at
-- most \(d\).
foreign import ccall "qadic.h _qadic_frobenius_a"
  _qadic_frobenius_a :: Ptr CFmpz -> CLong -> Ptr CFmpz -> Ptr CLong -> CLong -> Ptr CFmpz -> CLong -> IO ()

-- | /_qadic_frobenius/ /rop/ /op/ /len/ /e/ /a/ /j/ /lena/ /p/ /N/ 
-- 
-- Sets @(rop, 2*d-1)@ to \(\Sigma\) evaluated at @(op, len)@.
-- 
-- Assumes that @len@ is positive but at most \(d\).
-- 
-- Assumes that \(0 < e < d\).
-- 
-- Does not support aliasing.
foreign import ccall "qadic.h _qadic_frobenius"
  _qadic_frobenius :: Ptr CFmpz -> Ptr CFmpz -> CLong -> CLong -> Ptr CFmpz -> Ptr CLong -> CLong -> Ptr CFmpz -> CLong -> IO ()

-- | /qadic_frobenius/ /rop/ /op/ /e/ /ctx/ 
-- 
-- Evaluates the homomorphism \(\Sigma^e\) at @op@.
-- 
-- Recall that \(\mathbb{Q}_q / \mathbb{Q}_p\) is Galois with Galois group
-- \(\langle \Sigma \rangle \cong \langle \sigma \rangle\), which is also
-- isomorphic to \(\mathbb{Z}/d\mathbb{Z}\), where
-- \(\sigma \in \operatorname{Gal}(\mathbb{F}_q/\mathbb{F}_p)\) is the
-- Frobenius element \(\sigma \colon x \mapsto x^p\) and \(\Sigma\) is its
-- lift to \(\operatorname{Gal}(\mathbb{Q}_q/\mathbb{Q}_p)\).
-- 
-- This functionality is implemented as @GaloisImage()@ in Magma.
foreign import ccall "qadic.h qadic_frobenius"
  qadic_frobenius :: Ptr CQadic -> Ptr CQadic -> CLong -> Ptr CQadicCtx -> IO ()

-- | /_qadic_teichmuller/ /rop/ /op/ /len/ /a/ /j/ /lena/ /p/ /N/ 
-- 
-- Sets @(rop, d)@ to the Teichm\"uller lift of @(op, len)@ modulo \(p^N\).
-- 
-- Does not support aliasing.
foreign import ccall "qadic.h _qadic_teichmuller"
  _qadic_teichmuller :: Ptr CFmpz -> Ptr CFmpz -> CLong -> Ptr CFmpz -> Ptr CLong -> CLong -> Ptr CFmpz -> CLong -> IO ()

-- | /qadic_teichmuller/ /rop/ /op/ /ctx/ 
-- 
-- Sets @rop@ to the Teichm\"uller lift of @op@ to the precision given in
-- the context.
-- 
-- For a unit @op@, this is the unique \((q-1)`th root of unity 
-- which is congruent to \)op modulo :math:\`p.
-- 
-- Sets @rop@ to zero if @op@ is zero in the given context.
-- 
-- Raises an exception if the valuation of @op@ is negative.
foreign import ccall "qadic.h qadic_teichmuller"
  qadic_teichmuller :: Ptr CQadic -> Ptr CQadic -> Ptr CQadicCtx -> IO ()

-- | /_qadic_trace/ /rop/ /op/ /len/ /a/ /j/ /lena/ /pN/ 
-- 
-- Sets @rop@ to the trace of @op@.
-- 
-- For an element \(a \in \mathbb{Q}_q\), multiplication by \(a\) defines a
-- \(\mathbb{Q}_p\)-linear map on \(\mathbb{Q}_q\). We define the trace of
-- \(a\) as the trace of this map. Equivalently, if \(\Sigma\) generates
-- \(\operatorname{Gal}(\mathbb{Q}_q / \mathbb{Q}_p)\) then the trace of
-- \(a\) is equal to \(\sum_{i=0}^{d-1} \Sigma^i (a)\).
foreign import ccall "qadic.h _qadic_trace"
  _qadic_trace :: Ptr CFmpz -> Ptr CFmpz -> CLong -> Ptr CFmpz -> Ptr CLong -> CLong -> Ptr CFmpz -> IO ()

-- | /_qadic_norm/ /rop/ /op/ /len/ /a/ /j/ /lena/ /p/ /N/ 
-- 
-- Sets @rop@ to the norm of the element @(op,len)@ in \(\mathbb{Z}_q\) to
-- precision \(N\), where @len@ is at least one.
-- 
-- The result will be reduced modulo \(p^N\).
-- 
-- Note that whenever @(op,len)@ is a unit, so is its norm. Thus, the
-- output @rop@ of this function will typically not have to be
-- canonicalised or reduced by the caller.
foreign import ccall "qadic.h _qadic_norm"
  _qadic_norm :: Ptr CFmpz -> Ptr CFmpz -> CLong -> Ptr CFmpz -> Ptr CLong -> CLong -> Ptr CFmpz -> CLong -> IO ()

-- | /qadic_norm/ /rop/ /op/ /ctx/ 
-- 
-- Computes the norm of @op@ to the given precision.
-- 
-- Algorithm selection is automatic depending on the input.
foreign import ccall "qadic.h qadic_norm"
  qadic_norm :: Ptr CPadic -> Ptr CQadic -> Ptr CQadicCtx -> IO ()

-- | /qadic_norm_analytic/ /rop/ /op/ /ctx/ 
-- 
-- Whenever @op@ has valuation greater than \((p-1)^{-1}\), this routine
-- computes its norm @rop@ via
-- 
-- \[`\]
-- \[\operatorname{Norm} (x) = \exp \Bigl( \bigl( \operatorname{Trace} \log (x) \bigr) \Bigr).\]
-- 
-- In the special case that @op@ lies in \(\mathbb{Q}_p\), returns its norm
-- as \(\operatorname{Norm}(x) = x^d\), where \(d\) is the extension
-- degree.
-- 
-- Otherwise, raises an @abort@ signal.
-- 
-- The complexity of this implementation is quasi-linear in \(d\) and
-- \(N\), and polynomial in \(\log p\).
foreign import ccall "qadic.h qadic_norm_analytic"
  qadic_norm_analytic :: Ptr CPadic -> Ptr CQadic -> Ptr CQadicCtx -> IO ()

-- | /qadic_norm_resultant/ /rop/ /op/ /ctx/ 
-- 
-- Sets @rop@ to the norm of @op@, using the formula
-- 
-- \[`\]
-- \[\operatorname{Norm}(x) = \ell(f)^{-\deg(a)} \operatorname{Res}(f(X), a(X)),\]
-- 
-- where \(\mathbb{Q}_q \cong \mathbb{Q}_p[X] / (f(X))\), \(\ell(f)\) is
-- the leading coefficient of \(f(X)\), and \(a(X) \in \mathbb{Q}_p[X]\)
-- denotes the same polynomial as \(x\).
-- 
-- The complexity of the current implementation is given
-- by \(\mathcal{O}(d^4 M(N \log p))\), where \(M(n)\) denotes the complexity
-- of multiplying to \(n\)-bit integers.
foreign import ccall "qadic.h qadic_norm_resultant"
  qadic_norm_resultant :: Ptr CPadic -> Ptr CQadic -> Ptr CQadicCtx -> IO ()

-- Output ----------------------------------------------------------------------

-- | /qadic_fprint_pretty/ /file/ /op/ /ctx/ 
-- 
-- Prints a pretty representation of @op@ to @file@.
-- 
-- In the current implementation, always returns \(1\). The return code is
-- part of the function\'s signature to allow for a later implementation to
-- return the number of characters printed or a non-positive error code.
foreign import ccall "qadic.h qadic_fprint_pretty"
  qadic_fprint_pretty :: Ptr CFile -> Ptr CQadic -> Ptr CQadicCtx -> IO CInt

-- | /qadic_print_pretty/ /op/ /ctx/ 
-- 
-- Prints a pretty representation of @op@ to @stdout@.
-- 
-- In the current implementation, always returns \(1\). The return code is
-- part of the function\'s signature to allow for a later implementation to
-- return the number of characters printed or a non-positive error code.
qadic_print_pretty :: Ptr CQadic -> Ptr CQadicCtx -> IO CInt
qadic_print_pretty Ptr CQadic
x Ptr CQadicCtx
ctx = (Ptr CQadic -> IO CString) -> Ptr CQadic -> IO CInt
forall a. (Ptr a -> IO CString) -> Ptr a -> IO CInt
printCStr ((Ptr CQadic -> Ptr CQadicCtx -> IO CString)
-> Ptr CQadicCtx -> Ptr CQadic -> IO CString
forall a b c. (a -> b -> c) -> b -> a -> c
flip Ptr CQadic -> Ptr CQadicCtx -> IO CString
qadic_get_str_pretty Ptr CQadicCtx
ctx) Ptr CQadic
x

-- | /qadic_get_str__pretty/ /op/ /ctx/
--
-- Returns a pretty representation of @op@ in a C string.
foreign import ccall "qadic_get_str_pretty"
  qadic_get_str_pretty :: Ptr CQadic -> Ptr CQadicCtx -> IO CString