singular-factory-0.1: src/Math/Singular/Factory/Internal/CanonicalForm.hs
-- | Low-level bindings to singular-factory
{-# LANGUAGE BangPatterns, EmptyDataDecls, ForeignFunctionInterface #-}
module Math.Singular.Factory.Internal.CanonicalForm where
--------------------------------------------------------------------------------
import Data.Word
import Data.Ratio
import Foreign.C
import Foreign.Ptr
import Foreign.ForeignPtr
import Foreign.Marshal.Array
import Numeric.GMP.Types
import qualified Numeric.GMP.Utils as GMP
--------------------------------------------------------------------------------
-- * types
data Variable
data CanonicalForm
data Factor -- CFFactor
data FactorList -- List<CFFactor>
type Var = ForeignPtr Variable
type CF = ForeignPtr CanonicalForm
type Fac = ForeignPtr Factor
type FacList = ForeignPtr FactorList
--------------------------------------------------------------------------------
-- * constants
foreign import ccall "level_trans" c_level_trans :: CInt
foreign import ccall "level_base" c_level_base :: CInt
foreign import ccall "level_quot" c_level_quot :: CInt
foreign import ccall "level_expr" c_level_expr :: CInt
--------------------------------------------------------------------------------
-- * versions
foreign import ccall "get_factory_version" c_get_factory_version :: Ptr CChar -> Int -> IO ()
foreign import ccall "get_package_version" c_get_package_version :: Ptr CChar -> Int -> IO ()
getFactoryVersion :: IO String
getFactoryVersion = do
let n = 16
allocaArray n $ \ptr -> do
c_get_factory_version ptr n
peekCString ptr
getPackageVersion :: IO String
getPackageVersion = do
let n = 16
allocaArray n $ \ptr -> do
c_get_package_version ptr n
peekCString ptr
foreign import ccall "have_FLINT" c_have_FLINT :: IO CInt
foreign import ccall "have_NTL" c_have_NTL :: IO CInt
foreign import ccall "have_GMP" c_have_GMP :: IO CInt
--------------------------------------------------------------------------------
-- * config
foreign import ccall "set_default_switches" c_set_default_switches :: IO ()
setDefaultSwitches :: IO ()
setDefaultSwitches = do
c_set_default_switches
--------------------------------------------------------------------------------
-- * memory management
foreign import ccall "&free_var"
varFinalizerPtr :: FunPtr (Ptr Variable -> IO ())
foreign import ccall "&free_cf"
cfFinalizerPtr :: FunPtr (Ptr CanonicalForm -> IO ())
foreign import ccall "&free_fac"
facFinalizerPtr :: FunPtr (Ptr Factor -> IO ())
foreign import ccall "&free_faclist"
faclistFinalizerPtr :: FunPtr (Ptr FactorList -> IO ())
makeVar :: Ptr Variable -> IO Var
makeVar = newForeignPtr varFinalizerPtr
makeCF :: Ptr CanonicalForm -> IO CF
makeCF = newForeignPtr cfFinalizerPtr
makeFac :: Ptr Factor -> IO Fac
makeFac = newForeignPtr facFinalizerPtr
makeFacList :: Ptr FactorList -> IO FacList
makeFacList = newForeignPtr faclistFinalizerPtr
--------------------------------------------------------------------------------
-- * variables
foreign import ccall "new_var_level" c_new_var_level :: CInt -> IO (Ptr Variable)
foreign import ccall "new_var_name" c_new_var_name :: CChar -> IO (Ptr Variable)
foreign import ccall "new_var_level_name" c_new_var_level_name :: CInt -> CChar -> IO (Ptr Variable)
newVarL :: Int -> IO Var
newVarL level = makeVar =<< c_new_var_level (fromIntegral level)
newVarN :: Char -> IO Var
newVarN name = makeVar =<< c_new_var_name (castCharToCChar name)
newVarLN :: Int -> Char -> IO Var
newVarLN level name = makeVar =<< c_new_var_level_name (fromIntegral level) (castCharToCChar name)
newTransVar :: IO Var
newTransVar = makeVar =<< c_new_var_level (c_level_trans)
foreign import ccall "root_of" c_root_of :: Ptr CanonicalForm -> IO (Ptr Variable)
newRootOf :: CF -> IO Var
newRootOf cf = withForeignPtr cf $ \ptr -> makeVar =<< c_root_of ptr
foreign import ccall "get_var_level" c_get_var_level :: Ptr Variable -> IO CInt
foreign import ccall "get_var_name" c_get_var_name :: Ptr Variable -> IO CChar
getVarLevel :: Var -> IO Int
getVarLevel var = withForeignPtr var $ \ptr -> fromIntegral <$> (c_get_var_level ptr)
getVarName :: Var -> IO Char
getVarName var = withForeignPtr var $ \ptr -> castCCharToChar <$> (c_get_var_name ptr)
foreign import ccall "has_mipo" c_has_mipo :: Ptr Variable -> IO CInt
foreign import ccall "get_mipo" c_get_mipo :: Ptr Variable -> Ptr Variable -> IO (Ptr CanonicalForm)
foreign import ccall "set_mipo" c_set_mipo :: Ptr Variable -> Ptr CanonicalForm -> IO ()
foreign import ccall "set_reduce" c_set_reduce :: Ptr Variable -> CInt -> IO ()
hasMinimalPoly :: Var -> IO Bool
hasMinimalPoly var = withForeignPtr var $ \ptr -> liftBool (c_has_mipo ptr)
getMinimalPoly :: Var -> Var -> IO CF
getMinimalPoly var1 var2 =
withForeignPtr var1 $ \ptr1 ->
withForeignPtr var2 $ \ptr2 ->
makeCF =<< c_get_mipo ptr1 ptr2
setReduceFlag :: Var -> Bool -> IO ()
setReduceFlag var flag = withForeignPtr var $ \ptr -> c_set_reduce ptr (if flag then 1 else 0)
--------------------------------------------------------------------------------
-- * factors
foreign import ccall "get_factor" c_get_factor :: Ptr Factor -> IO (Ptr CanonicalForm)
getFactorCF :: Fac -> IO CF
getFactorCF fac = withForeignPtr fac $ \ptr -> makeCF =<< c_get_factor ptr
foreign import ccall "get_fac_expo" c_get_fac_expo :: Ptr Factor -> IO CInt
getFactorExpo :: Fac -> IO Int
getFactorExpo fac = withForeignPtr fac $ \ptr -> fromIntegral <$> c_get_fac_expo ptr
unpackFactor :: Fac -> IO (CF,Int)
unpackFactor fac = do
cf <- getFactorCF fac
expo <- getFactorExpo fac
return (cf,expo)
--------------------------------------------------------------------------------
-- * lists
foreign import ccall "get_list_length" c_get_list_length :: Ptr FactorList -> IO CInt
getListLength :: FacList -> IO Int
getListLength faclist = withForeignPtr faclist $ \ptr -> fromIntegral <$> c_get_list_length ptr
--------------------------------------------------------------------------------
-- * factorization
foreign import ccall "flatten_faclist" c_flatten_faclist :: Ptr FactorList -> Ptr (Ptr Factor) -> IO ()
flattenFactorList :: FacList -> IO [Fac]
flattenFactorList faclist = withForeignPtr faclist $ \listptr -> do
n <- fromIntegral <$> c_get_list_length listptr
allocaArray n $ \arrptr -> do
c_flatten_faclist listptr arrptr
facptrs <- peekArray n arrptr
mapM makeFac facptrs
unpackFactorList :: FacList -> IO [(CF,Int)]
unpackFactorList faclist = mapM unpackFactor =<< flattenFactorList faclist
foreign import ccall "hs_factorize" c_hs_factorize :: Ptr CanonicalForm -> IO (Ptr FactorList)
factorizeIO' :: CF -> IO FacList
factorizeIO' cf = withForeignPtr cf $ \ptr -> makeFacList =<< (c_hs_factorize ptr)
factorizeIO :: CF -> IO [(CF,Int)]
factorizeIO cf = unpackFactorList =<< factorizeIO' cf
{-
foreign import ccall "rat_factorize" c_rat_factorize :: Ptr CanonicalForm -> Ptr Variable -> CInt -> IO (Ptr FactorList)
foreign import ccall "fq_factorize" c_fq_factorize :: Ptr CanonicalForm -> Ptr Variable -> CInt -> IO (Ptr FactorList)
foreign import ccall "fp_factorize" c_fp_factorize :: Ptr CanonicalForm -> CInt -> IO (Ptr FactorList)
foreign import ccall "gf_factorize" c_gf_factorize :: Ptr CanonicalForm -> CInt -> IO (Ptr FactorList)
fpFactorizeIO' :: CF -> Bool -> IO FacList
fpFactorizeIO' cf subst_check_flag =
withForeignPtr cf $ \ptr ->
makeFacList =<< (c_fp_factorize ptr (bool2cint subst_check_flag))
gfFactorizeIO' :: CF -> Bool -> IO FacList
gfFactorizeIO' cf subst_check_flag =
withForeignPtr cf $ \ptr ->
makeFacList =<< (c_gf_factorize ptr (bool2cint subst_check_flag))
ratFactorizeIO' :: CF -> Var -> Bool -> IO FacList
ratFactorizeIO' cf var subst_check_flag =
withForeignPtr cf $ \ptr -> withForeignPtr var $ \varptr ->
makeFacList =<< (c_rat_factorize ptr varptr (bool2cint subst_check_flag))
fqFactorizeIO' :: CF -> Var -> Bool -> IO FacList
fqFactorizeIO' cf var subst_check_flag =
withForeignPtr cf $ \ptr -> withForeignPtr var $ \varptr ->
makeFacList =<< (c_fq_factorize ptr varptr (bool2cint subst_check_flag))
fpFactorizeIO :: CF -> Bool -> IO [(CF,Int)]
fpFactorizeIO cf flag = unpackFactorList =<< fpFactorizeIO' cf flag
gfFactorizeIO :: CF -> Bool -> IO [(CF,Int)]
gfFactorizeIO cf flag = unpackFactorList =<< gfFactorizeIO' cf flag
ratFactorizeIO :: CF -> Var -> Bool -> IO [(CF,Int)]
ratFactorizeIO cf var flag = unpackFactorList =<< ratFactorizeIO' cf var flag
fqFactorizeIO :: CF -> Var -> Bool -> IO [(CF,Int)]
fqFactorizeIO cf var flag = unpackFactorList =<< fqFactorizeIO' cf var flag
-}
--------------------------------------------------------------------------------
-- * basic CFs
foreign import ccall "empty_cf" c_empty_cf :: IO (Ptr CanonicalForm)
newEmptyCF :: IO CF
newEmptyCF = makeCF =<< c_empty_cf
foreign import ccall "const_cf" c_const_cf :: CInt -> IO (Ptr CanonicalForm)
newSmallConstCF :: Int -> IO CF
newSmallConstCF k = makeCF =<< c_const_cf (fromIntegral k)
foreign import ccall "var_cf" c_var_cf :: Ptr Variable -> IO (Ptr CanonicalForm)
foreign import ccall "var_pow_cf" c_var_pow_cf :: Ptr Variable -> Int -> IO (Ptr CanonicalForm)
varIO :: Var -> IO CF
varIO var = withForeignPtr var $ \vptr -> makeCF =<< c_var_cf vptr
varPowIO :: Var -> Int -> IO CF
varPowIO var expo = withForeignPtr var $ \vptr -> makeCF =<< c_var_pow_cf vptr expo
--------------------------------------------------------------------------------
-- * basic CF predicates
bool2cint :: Bool -> CInt
bool2cint True = 1
bool2cint False = 0
cint2bool :: CInt -> Bool
cint2bool k = (k/=0)
liftBool :: IO CInt -> IO Bool
liftBool action = action >>= \k -> return (cint2bool k)
----------------------------------------
foreign import ccall "is_zero" c_is_zero :: Ptr CanonicalForm -> IO CInt
foreign import ccall "is_one" c_is_one :: Ptr CanonicalForm -> IO CInt
isZeroIO :: CF -> IO Bool
isZeroIO cf = withForeignPtr cf $ \ptr -> liftBool (c_is_zero ptr)
isOneIO :: CF -> IO Bool
isOneIO cf = withForeignPtr cf $ \ptr -> liftBool (c_is_one ptr)
foreign import ccall "is_imm" c_is_imm :: Ptr CanonicalForm -> IO CInt
foreign import ccall "is_univariate" c_is_univariate :: Ptr CanonicalForm -> IO CInt
isImmediateIO :: CF -> IO Bool
isImmediateIO cf = withForeignPtr cf $ \ptr -> liftBool (c_is_imm ptr)
isUnivariateIO :: CF -> IO Bool
isUnivariateIO cf = withForeignPtr cf $ \ptr -> liftBool (c_is_univariate ptr)
foreign import ccall "in_ZZ" c_in_ZZ :: Ptr CanonicalForm -> IO CInt
foreign import ccall "in_QQ" c_in_QQ :: Ptr CanonicalForm -> IO CInt
foreign import ccall "in_GF" c_in_GF :: Ptr CanonicalForm -> IO CInt
foreign import ccall "in_FF" c_in_FF :: Ptr CanonicalForm -> IO CInt
isInZZ_IO :: CF -> IO Bool
isInZZ_IO cf = withForeignPtr cf $ \ptr -> liftBool (c_in_ZZ ptr)
isInQQ_IO :: CF -> IO Bool
isInQQ_IO cf = withForeignPtr cf $ \ptr -> liftBool (c_in_QQ ptr)
isInGF_IO :: CF -> IO Bool
isInGF_IO cf = withForeignPtr cf $ \ptr -> liftBool (c_in_GF ptr)
isInFF_IO :: CF -> IO Bool
isInFF_IO cf = withForeignPtr cf $ \ptr -> liftBool (c_in_FF ptr)
foreign import ccall "in_BaseDomain" c_in_BaseDomain :: Ptr CanonicalForm -> IO CInt
foreign import ccall "in_CoeffDomain" c_in_CoeffDomain :: Ptr CanonicalForm -> IO CInt
foreign import ccall "in_PolyDomain" c_in_PolyDomain :: Ptr CanonicalForm -> IO CInt
foreign import ccall "in_Extension" c_in_Extension :: Ptr CanonicalForm -> IO CInt
foreign import ccall "in_QuotDomain" c_in_QuotDomain :: Ptr CanonicalForm -> IO CInt
isInBaseDomainIO :: CF -> IO Bool
isInBaseDomainIO cf = withForeignPtr cf $ \ptr -> liftBool (c_in_BaseDomain ptr)
isInCoeffDomainIO :: CF -> IO Bool
isInCoeffDomainIO cf = withForeignPtr cf $ \ptr -> liftBool (c_in_CoeffDomain ptr)
isInPolyDomainIO :: CF -> IO Bool
isInPolyDomainIO cf = withForeignPtr cf $ \ptr -> liftBool (c_in_PolyDomain ptr)
isInExtensionIO :: CF -> IO Bool
isInExtensionIO cf = withForeignPtr cf $ \ptr -> liftBool (c_in_Extension ptr)
isInQuotDomainIO :: CF -> IO Bool
isInQuotDomainIO cf = withForeignPtr cf $ \ptr -> liftBool (c_in_QuotDomain ptr)
--------------------------------------------------------------------------------
-- * basic properties
foreign import ccall "degree_of" c_degree_of :: Ptr CanonicalForm -> IO CInt
foreign import ccall "level_of" c_level_of :: Ptr CanonicalForm -> IO CInt
foreign import ccall "mvar_of" c_mvar_of :: Ptr CanonicalForm -> IO (Ptr Variable)
getDegree :: CF -> IO Int
getDegree cf = withForeignPtr cf $ \ptr -> fromIntegral <$> (c_degree_of ptr)
getLevel :: CF -> IO Int
getLevel cf = withForeignPtr cf $ \ptr -> fromIntegral <$> (c_level_of ptr)
getMainVar :: CF -> IO Var
getMainVar cf = withForeignPtr cf $ \ptr -> makeVar =<< (c_mvar_of ptr)
--------------------------------------------------------------------------------
-- * small values
foreign import ccall "smallint_value" c_smallint_value :: Ptr CanonicalForm -> IO CLong -- !!!
getSmallIntValue :: CF -> IO Int
getSmallIntValue cf = withForeignPtr cf $ \ptr -> fromIntegral <$> (c_smallint_value ptr)
foreign import ccall "numer" c_numer :: Ptr CanonicalForm -> IO (Ptr CanonicalForm)
foreign import ccall "denom" c_denom :: Ptr CanonicalForm -> IO (Ptr CanonicalForm)
getNumer :: CF -> IO CF
getNumer cf = withForeignPtr cf $ \ptr -> makeCF =<< (c_numer ptr)
getDenom :: CF -> IO CF
getDenom cf = withForeignPtr cf $ \ptr -> makeCF =<< (c_denom ptr)
foreign import ccall "index_poly" c_index_poly :: Ptr CanonicalForm -> Int -> IO (Ptr CanonicalForm)
foreign import ccall "map_into" c_map_into :: Ptr CanonicalForm -> IO (Ptr CanonicalForm)
foreign import ccall "substitute" c_substitute :: Ptr CanonicalForm -> Ptr Variable -> Ptr CanonicalForm -> IO (Ptr CanonicalForm)
--------------------------------------------------------------------------------
-- * Polynomial operations
-- | Get the given degree part
getCfAtIndex :: CF -> Int -> IO CF
getCfAtIndex cf idx = withForeignPtr cf $ \ptr -> makeCF =<< (c_index_poly ptr $ fromIntegral idx)
-- | Map into the current base domain
mapIntoIO :: CF -> IO CF
mapIntoIO cf = withForeignPtr cf $ \ptr -> makeCF =<< (c_map_into ptr)
-- | Map into the current base domain
substituteIO :: Var -> CF -> (CF -> IO CF)
substituteIO var what cf =
withForeignPtr var $ \pvar ->
withForeignPtr what $ \pwhat ->
withForeignPtr cf $ \pcf ->
makeCF =<< (c_substitute pcf pvar pwhat)
--------------------------------------------------------------------------------
-- * Binary operations
foreign import ccall "is_equal" c_is_equal :: Ptr CanonicalForm -> Ptr CanonicalForm -> IO CInt
isEqualIO :: CF -> CF -> IO Bool
isEqualIO x y = withForeignPtr x $ \p -> withForeignPtr y $ \q -> liftBool (c_is_equal p q)
foreign import ccall "plus_cf" c_plus_cf :: Ptr CanonicalForm -> Ptr CanonicalForm -> IO (Ptr CanonicalForm)
foreign import ccall "minus_cf" c_minus_cf :: Ptr CanonicalForm -> Ptr CanonicalForm -> IO (Ptr CanonicalForm)
foreign import ccall "times_cf" c_times_cf :: Ptr CanonicalForm -> Ptr CanonicalForm -> IO (Ptr CanonicalForm)
foreign import ccall "pow_cf" c_pow_cf :: Ptr CanonicalForm -> CInt -> IO (Ptr CanonicalForm)
foreign import ccall "div_cf" c_div_cf :: Ptr CanonicalForm -> Ptr CanonicalForm -> IO (Ptr CanonicalForm)
foreign import ccall "mod_cf" c_mod_cf :: Ptr CanonicalForm -> Ptr CanonicalForm -> IO (Ptr CanonicalForm)
foreign import ccall "gcd_poly_cf" c_gcd_poly_cf :: Ptr CanonicalForm -> Ptr CanonicalForm -> IO (Ptr CanonicalForm)
foreign import ccall "reduce_cf" c_reduce_cf :: Ptr CanonicalForm -> Ptr CanonicalForm -> IO (Ptr CanonicalForm)
plusIO :: CF -> CF -> IO CF
plusIO x y = withForeignPtr x $ \p -> withForeignPtr y $ \q -> makeCF =<< (c_plus_cf p q)
minusIO :: CF -> CF -> IO CF
minusIO x y = withForeignPtr x $ \p -> withForeignPtr y $ \q -> makeCF =<< (c_minus_cf p q)
timesIO :: CF -> CF -> IO CF
timesIO x y = withForeignPtr x $ \p -> withForeignPtr y $ \q -> makeCF =<< (c_times_cf p q)
powIO :: CF -> Int -> IO CF
powIO x n = withForeignPtr x $ \p -> makeCF =<< (c_pow_cf p $ fromIntegral n)
divIO :: CF -> CF -> IO CF
divIO x y = withForeignPtr x $ \p -> withForeignPtr y $ \q -> makeCF =<< (c_div_cf p q)
modIO :: CF -> CF -> IO CF
modIO x y = withForeignPtr x $ \p -> withForeignPtr y $ \q -> makeCF =<< (c_mod_cf p q)
gcdPolyIO :: CF -> CF -> IO CF
gcdPolyIO x y = withForeignPtr x $ \p -> withForeignPtr y $ \q -> makeCF =<< (c_gcd_poly_cf p q)
reduceIO :: CF -> CF -> IO CF
reduceIO x y = withForeignPtr x $ \p -> withForeignPtr y $ \q -> makeCF =<< (c_reduce_cf p q)
--------------------------------------------------------------------------------
-- * GMP compatibility layer
foreign import ccall "get_gmp_numerator" c_get_gmp_numerator :: Ptr CanonicalForm -> Ptr MPZ -> IO ()
foreign import ccall "get_gmp_denominator" c_get_gmp_denominator :: Ptr CanonicalForm -> Ptr MPZ -> IO ()
getGmpNumerator :: CF -> IO Integer
getGmpNumerator cf =
withForeignPtr cf $ \cfp ->
GMP.withOutInteger_ (\mpz_ptr -> c_get_gmp_numerator cfp mpz_ptr)
getGmpDenominator :: CF -> IO Integer
getGmpDenominator cf =
withForeignPtr cf $ \cfp ->
GMP.withOutInteger_ (\mpz_ptr -> c_get_gmp_denominator cfp mpz_ptr)
foreign import ccall "make_ZZ_from_gmp" c_make_ZZ_from_gmp :: Ptr MPZ -> IO (Ptr CanonicalForm)
foreign import ccall "make_QQ_from_gmp" c_make_QQ_from_gmp :: Ptr MPZ -> Ptr MPZ -> CInt -> IO (Ptr CanonicalForm)
makeIntegerCF :: Integer -> IO CF
makeIntegerCF n =
GMP.withInInteger n $ \mpz_ptr ->
makeCF =<< (c_make_ZZ_from_gmp mpz_ptr)
makeRationalCF :: Rational -> IO CF
makeRationalCF n =
GMP.withInInteger (numerator n) $ \mpz_ptr1 ->
GMP.withInInteger (denominator n) $ \mpz_ptr2 ->
makeCF =<< (c_make_QQ_from_gmp mpz_ptr1 mpz_ptr2 0)
--------------------------------------------------------------------------------
-- * Base domain characteristic
foreign import ccall "get_characteristic" c_get_characteristic :: IO CInt
foreign import ccall "set_characteristic1" c_set_characteristic1 :: CInt -> IO ()
-- foreign import ccall "set_characteristic2" c_set_characteristic2 :: CInt -> CInt -> IO ()
foreign import ccall "set_characteristic3" c_set_characteristic3 :: CInt -> CInt -> CChar -> IO ()
getCharacteristic :: IO Int
getCharacteristic = fromIntegral <$> c_get_characteristic
-- | prime fields and QQ
setCharacteristic1 :: Int -> IO ()
setCharacteristic1 = c_set_characteristic1 . fromIntegral
{-
-- | prime power fields (meaning FF?)
-- apparently they removed this ????
setCharacteristic2 :: Int -> Int -> IO ()
setCharacteristic2 p n = c_set_characteristic2 (fromIntegral p) (fromIntegral n)
-}
-- | Galois fields
setCharacteristic3 :: Int -> Int -> Char -> IO ()
setCharacteristic3 p n ch = c_set_characteristic3 (fromIntegral p) (fromIntegral n) (castCharToCChar ch)
foreign import ccall "get_gf_value" c_get_gf_value :: Ptr CanonicalForm -> IO CInt
foreign import ccall "is_FF_in_GF" c_is_FF_in_GF :: Ptr CanonicalForm -> IO CInt
foreign import ccall "get_GF_degree" c_get_GF_degree :: IO CInt
foreign import ccall "get_GF_generator" c_get_GF_generator :: IO (Ptr CanonicalForm)
-- | This returns the exponent of the canonical generator.
-- If the input is zero, it appears to return the order of the field, q, but don't rely on this...
getGFValue :: CF -> IO Int
getGFValue cf = withForeignPtr cf $ \ptr -> fromIntegral <$> (c_get_gf_value ptr)
-- | True if element of the prime subfield
isFFinGF_IO :: CF -> IO Bool
isFFinGF_IO cf = withForeignPtr cf $ \ptr -> liftBool (c_is_FF_in_GF ptr)
-- | Returns the degree of the Galois field (degree of extension over the prime field)
getGFDegree :: IO Int
getGFDegree = fromIntegral <$> c_get_GF_degree
-- | Returns the generator of the Galois field
getGFGenerator :: IO CF
getGFGenerator = makeCF =<< c_get_GF_generator
--------------------------------------------------------------------------------