{-# LANGUAGE BangPatterns, ScopedTypeVariables #-}
{-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}
{-# LANGUAGE TypeFamilies, StandaloneDeriving, ExistentialQuantification #-}
module Math.FiniteField.GaloisField.Zech.C where
import Data.Int
import GHC.TypeNats (Nat)
import Foreign.C
import Foreign.Ptr
import Foreign.ForeignPtr
import Foreign.Storable
import Foreign.Marshal
import System.Random ( RandomGen , randomR )
import System.IO
import System.IO.Unsafe as Unsafe
import qualified Data.Vector.Unboxed as Vec
import Math.FiniteField.Class
import Math.FiniteField.TypeLevel.Singleton
import qualified Math.FiniteField.GaloisField.Zech as Z
data WitnessC (p :: Nat) (m :: Nat)
= WitnessC (ForeignPtr Int32)
deriving Int -> WitnessC p m -> ShowS
forall (p :: Nat) (m :: Nat). Int -> WitnessC p m -> ShowS
forall (p :: Nat) (m :: Nat). [WitnessC p m] -> ShowS
forall (p :: Nat) (m :: Nat). WitnessC p m -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WitnessC p m] -> ShowS
$cshowList :: forall (p :: Nat) (m :: Nat). [WitnessC p m] -> ShowS
show :: WitnessC p m -> String
$cshow :: forall (p :: Nat) (m :: Nat). WitnessC p m -> String
showsPrec :: Int -> WitnessC p m -> ShowS
$cshowsPrec :: forall (p :: Nat) (m :: Nat). Int -> WitnessC p m -> ShowS
Show
fromWitnessC :: WitnessC p m -> ForeignPtr Int32
fromWitnessC :: forall (p :: Nat) (m :: Nat). WitnessC p m -> ForeignPtr Int32
fromWitnessC (WitnessC ForeignPtr Int32
fptr) = ForeignPtr Int32
fptr
data SomeWitnessC
= forall p m. SomeWitnessC (WitnessC p m)
deriving instance Show SomeWitnessC
mkCField :: Int -> Int -> Maybe SomeWitnessC
mkCField :: Int -> Int -> Maybe SomeWitnessC
mkCField Int
p Int
m = case Int -> Int -> Maybe SomeWitnessZech
Z.mkZechField Int
p Int
m of
Maybe SomeWitnessZech
Nothing -> forall a. Maybe a
Nothing
Just SomeWitnessZech
some -> case SomeWitnessZech
some of
Z.SomeWitnessZech WitnessZech p m
wzech -> forall a. a -> Maybe a
Just (forall (p :: Nat) (m :: Nat). WitnessC p m -> SomeWitnessC
SomeWitnessC (forall (p :: Nat) (m :: Nat). WitnessZech p m -> WitnessC p m
makeCZechTable WitnessZech p m
wzech))
unsafeCField :: Int -> Int -> SomeWitnessC
unsafeCField :: Int -> Int -> SomeWitnessC
unsafeCField Int
p Int
m = case Int -> Int -> Maybe SomeWitnessC
mkCField Int
p Int
m of
Maybe SomeWitnessC
Nothing -> forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"unsafeCField: cannot find Conway polynomial for GF(" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
p forall a. [a] -> [a] -> [a]
++ String
"^" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
m forall a. [a] -> [a] -> [a]
++ String
")"
Just SomeWitnessC
some -> SomeWitnessC
some
makeCZechTable :: Z.WitnessZech p m -> WitnessC p m
makeCZechTable :: forall (p :: Nat) (m :: Nat). WitnessZech p m -> WitnessC p m
makeCZechTable (Z.WitnessZech ZechTable
zechtable) = forall a. IO a -> a
unsafePerformIO (forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> WitnessC p m
WitnessC forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ZechTable -> IO (ForeignPtr Int32)
marshalZechTable ZechTable
zechtable)
marshalZechTable :: Z.ZechTable -> IO (ForeignPtr Int32)
marshalZechTable :: ZechTable -> IO (ForeignPtr Int32)
marshalZechTable ZechTable
ztable = do
let (Int32
p,Int32
m) = ZechTable -> (Int32, Int32)
Z._zechParams ZechTable
ztable
let q :: Int32
q = Int32
p forall a b. (Num a, Integral b) => a -> b -> a
^ Int32
m
let e :: Int32
e = if Int32
p forall a. Eq a => a -> a -> Bool
== Int32
2 then Int32
0 else forall a. Integral a => a -> a -> a
div (Int32
qforall a. Num a => a -> a -> a
-Int32
1) Int32
2
let len :: Int
len = Int
4 forall a. Num a => a -> a -> a
* forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int32
4 forall a. Num a => a -> a -> a
+ Int32
p forall a. Num a => a -> a -> a
+ Int32
qforall a. Num a => a -> a -> a
-Int32
1)
ForeignPtr Int32
fptr <- forall a. Int -> IO (ForeignPtr a)
mallocForeignPtrBytes Int
len :: IO (ForeignPtr Int32)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Int32
fptr forall a b. (a -> b) -> a -> b
$ \Ptr Int32
ptr -> do
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr Int32
ptr Int
0 Int32
p
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr Int32
ptr Int
1 Int32
m
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr Int32
ptr Int
2 (Int32
qforall a. Num a => a -> a -> a
-Int32
1)
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr Int32
ptr Int
3 Int32
e
let ofs :: Int
ofs = Int
4 forall a. Num a => a -> a -> a
* (Int
4 forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
p)
forall a. Storable a => Ptr a -> [a] -> IO ()
pokeArray (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Int32
ptr Int
16 ) (forall a. Unbox a => Vector a -> [a]
Vec.toList (ZechTable -> Vector Int32
Z._embedding ZechTable
ztable))
forall a. Storable a => Ptr a -> [a] -> IO ()
pokeArray (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Int32
ptr Int
ofs) (forall a. Unbox a => Vector a -> [a]
Vec.toList (ZechTable -> Vector Int32
Z._zechLogs ZechTable
ztable))
forall (m :: * -> *) a. Monad m => a -> m a
return ForeignPtr Int32
fptr
saveCZechTable :: FilePath -> WitnessC p q -> IO ()
saveCZechTable :: forall (p :: Nat) (q :: Nat). String -> WitnessC p q -> IO ()
saveCZechTable String
fname w :: WitnessC p q
w@(WitnessC ForeignPtr Int32
fptr) = do
let p :: Int
p = forall (p :: Nat) (m :: Nat). WitnessC p m -> Int
rawPrime WitnessC p q
w
let m :: Int
m = forall (p :: Nat) (m :: Nat). WitnessC p m -> Int
rawDim WitnessC p q
w
let q :: Int
q = Int
pforall a b. (Num a, Integral b) => a -> b -> a
^Int
m
let len :: Int
len = Int
4 forall a. Num a => a -> a -> a
* forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
4 forall a. Num a => a -> a -> a
+ Int
p forall a. Num a => a -> a -> a
+ Int
qforall a. Num a => a -> a -> a
-Int
1)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Int32
fptr forall a b. (a -> b) -> a -> b
$ \Ptr Int32
ptr -> do
Handle
h <- String -> IOMode -> IO Handle
openBinaryFile String
fname IOMode
WriteMode
forall a. Handle -> Ptr a -> Int -> IO ()
hPutBuf Handle
h Ptr Int32
ptr Int
len
Handle -> IO ()
hClose Handle
h
loadCZechTable :: FilePath -> IO (Maybe SomeWitnessC)
loadCZechTable :: String -> IO (Maybe SomeWitnessC)
loadCZechTable String
fname = do
Handle
h <- String -> IOMode -> IO Handle
openBinaryFile String
fname IOMode
ReadMode
Maybe SomeWitnessC
mb <- forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
16 forall a b. (a -> b) -> a -> b
$ \(Ptr Int32
header :: Ptr Int32) -> do
forall a. Handle -> Ptr a -> Int -> IO Int
hGetBuf Handle
h Ptr Int32
header Int
16
Int32
p <- forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Int32
header Int
0
Int32
m <- forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Int32
header Int
1
Int32
qm1 <- forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Int32
header Int
2
Int32
e <- forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Int32
header Int
3
let ok1 :: Bool
ok1 = Int32
qm1 forall a. Num a => a -> a -> a
+ Int32
1 forall a. Eq a => a -> a -> Bool
== Int32
pforall a b. (Num a, Integral b) => a -> b -> a
^Int32
m
ok2 :: Bool
ok2 = if Int32
p forall a. Eq a => a -> a -> Bool
== Int32
2 then Int32
e forall a. Eq a => a -> a -> Bool
== Int32
0 else Int32
e forall a. Eq a => a -> a -> Bool
== forall a. Integral a => a -> a -> a
div Int32
qm1 Int32
2
if Bool -> Bool
not (Bool
ok1 Bool -> Bool -> Bool
&& Bool
ok2)
then forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
else do
Handle -> SeekMode -> Integer -> IO ()
hSeek Handle
h SeekMode
AbsoluteSeek Integer
0
let len :: Int
len = Int
16 forall a. Num a => a -> a -> a
+ Int
4 forall a. Num a => a -> a -> a
* (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
qm1 forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
p)
ForeignPtr Int32
fptr <- forall a. Int -> IO (ForeignPtr a)
mallocForeignPtrBytes Int
len
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Int32
fptr forall a b. (a -> b) -> a -> b
$ \Ptr Int32
ptr -> forall a. Handle -> Ptr a -> Int -> IO Int
hGetBuf Handle
h Ptr Int32
ptr Int
len
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ case (Int64 -> SomeSNat64
someSNat64 (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
p), Int64 -> SomeSNat64
someSNat64 (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
m)) of
(SomeSNat64 SNat64 n
sp, SomeSNat64 SNat64 n
sm) -> forall a. a -> Maybe a
Just (forall (p :: Nat) (m :: Nat). WitnessC p m -> SomeWitnessC
SomeWitnessC (forall (p :: Nat) (m :: Nat).
SNat64 p -> SNat64 m -> ForeignPtr Int32 -> WitnessC p m
constructWitnessC SNat64 n
sp SNat64 n
sm ForeignPtr Int32
fptr))
Handle -> IO ()
hClose Handle
h
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe SomeWitnessC
mb
constructWitnessC :: SNat64 p -> SNat64 m -> ForeignPtr Int32 -> WitnessC p m
constructWitnessC :: forall (p :: Nat) (m :: Nat).
SNat64 p -> SNat64 m -> ForeignPtr Int32 -> WitnessC p m
constructWitnessC SNat64 p
_ SNat64 m
_ ForeignPtr Int32
fptr = forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> WitnessC p m
WitnessC ForeignPtr Int32
fptr
data CFq (p :: Nat) (m :: Nat)
= CFq {-# UNPACK #-} !(ForeignPtr Int32) {-# UNPACK #-} !Int32
instance Eq (CFq p m) where
== :: CFq p m -> CFq p m -> Bool
(==) (CFq ForeignPtr Int32
_ Int32
x) (CFq ForeignPtr Int32
_ Int32
y) = Int32
x forall a. Eq a => a -> a -> Bool
== Int32
y
instance Ord (CFq p m) where
compare :: CFq p m -> CFq p m -> Ordering
compare (CFq ForeignPtr Int32
_ Int32
x) (CFq ForeignPtr Int32
_ Int32
y) = forall a. Ord a => a -> a -> Ordering
compare Int32
x Int32
y
instance Show (CFq p m) where
show :: CFq p m -> String
show (CFq ForeignPtr Int32
_ Int32
k)
| Int32
k forall a. Eq a => a -> a -> Bool
== -Int32
1 = String
"0"
| Int32
k forall a. Eq a => a -> a -> Bool
== Int32
0 = String
"1"
| Int32
k forall a. Eq a => a -> a -> Bool
== Int32
1 = String
"g"
| Bool
otherwise = String
"g^" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int32
k
instance Num (CFq p m) where
fromInteger :: Integer -> CFq p m
fromInteger = forall a. HasCallStack => String -> a
error String
"GaloisField/Zech/C/fromInteger: cannot be implemented; use `embed` instead"
negate :: CFq p m -> CFq p m
negate (CFq ForeignPtr Int32
fptr Int32
x) = forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> Int32 -> CFq p m
CFq ForeignPtr Int32
fptr (forall (p :: Nat) (m :: Nat). Raw p m -> Int32
fromRaw (forall (p :: Nat) (m :: Nat). WitnessC p m -> Raw p m -> Raw p m
rawNeg (forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> WitnessC p m
WitnessC ForeignPtr Int32
fptr) (forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw Int32
x) ))
+ :: CFq p m -> CFq p m -> CFq p m
(+) (CFq ForeignPtr Int32
fptr Int32
x) (CFq ForeignPtr Int32
_ Int32
y) = forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> Int32 -> CFq p m
CFq ForeignPtr Int32
fptr (forall (p :: Nat) (m :: Nat). Raw p m -> Int32
fromRaw (forall (p :: Nat) (m :: Nat).
WitnessC p m -> Raw p m -> Raw p m -> Raw p m
rawAdd (forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> WitnessC p m
WitnessC ForeignPtr Int32
fptr) (forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw Int32
x) (forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw Int32
y)))
(-) (CFq ForeignPtr Int32
fptr Int32
x) (CFq ForeignPtr Int32
_ Int32
y) = forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> Int32 -> CFq p m
CFq ForeignPtr Int32
fptr (forall (p :: Nat) (m :: Nat). Raw p m -> Int32
fromRaw (forall (p :: Nat) (m :: Nat).
WitnessC p m -> Raw p m -> Raw p m -> Raw p m
rawSub (forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> WitnessC p m
WitnessC ForeignPtr Int32
fptr) (forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw Int32
x) (forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw Int32
y)))
* :: CFq p m -> CFq p m -> CFq p m
(*) (CFq ForeignPtr Int32
fptr Int32
x) (CFq ForeignPtr Int32
_ Int32
y) = forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> Int32 -> CFq p m
CFq ForeignPtr Int32
fptr (forall (p :: Nat) (m :: Nat). Raw p m -> Int32
fromRaw (forall (p :: Nat) (m :: Nat).
WitnessC p m -> Raw p m -> Raw p m -> Raw p m
rawMul (forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> WitnessC p m
WitnessC ForeignPtr Int32
fptr) (forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw Int32
x) (forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw Int32
y)))
abs :: CFq p m -> CFq p m
abs (CFq ForeignPtr Int32
fptr Int32
x) = forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> Int32 -> CFq p m
CFq ForeignPtr Int32
fptr Int32
x
signum :: CFq p m -> CFq p m
signum (CFq ForeignPtr Int32
fptr Int32
x) = forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> Int32 -> CFq p m
CFq ForeignPtr Int32
fptr Int32
0
instance Fractional (CFq p m) where
fromRational :: Rational -> CFq p m
fromRational = forall a. HasCallStack => String -> a
error String
"GaloisField/Zech/C/fromRational: cannot be implemented; use `embed` instead"
recip :: CFq p m -> CFq p m
recip (CFq ForeignPtr Int32
fptr Int32
x) = forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> Int32 -> CFq p m
CFq ForeignPtr Int32
fptr (forall (p :: Nat) (m :: Nat). Raw p m -> Int32
fromRaw (forall (p :: Nat) (m :: Nat). WitnessC p m -> Raw p m -> Raw p m
rawInv (forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> WitnessC p m
WitnessC ForeignPtr Int32
fptr) (forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw Int32
x) ))
/ :: CFq p m -> CFq p m -> CFq p m
(/) (CFq ForeignPtr Int32
fptr Int32
x) (CFq ForeignPtr Int32
_ Int32
y) = forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> Int32 -> CFq p m
CFq ForeignPtr Int32
fptr (forall (p :: Nat) (m :: Nat). Raw p m -> Int32
fromRaw (forall (p :: Nat) (m :: Nat).
WitnessC p m -> Raw p m -> Raw p m -> Raw p m
rawDiv (forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> WitnessC p m
WitnessC ForeignPtr Int32
fptr) (forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw Int32
x) (forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw Int32
y)))
instance Field (CFq p m) where
type Witness (CFq p m) = WitnessC p m
type Prime (CFq p m) = p
type Dim (CFq p m) = m
characteristic :: Witness (CFq p m) -> Integer
characteristic Witness (CFq p m)
w = forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall (p :: Nat) (m :: Nat). WitnessC p m -> Int
rawPrime Witness (CFq p m)
w)
dimension :: Witness (CFq p m) -> Integer
dimension Witness (CFq p m)
w = forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall (p :: Nat) (m :: Nat). WitnessC p m -> Int
rawDim Witness (CFq p m)
w)
fieldSize :: Witness (CFq p m) -> Integer
fieldSize Witness (CFq p m)
w = forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall (p :: Nat) (m :: Nat). WitnessC p m -> Int
rawFieldSize Witness (CFq p m)
w)
witnessOf :: CFq p m -> Witness (CFq p m)
witnessOf !CFq p m
x = case CFq p m
x of { CFq ForeignPtr Int32
fptr Int32
_ -> forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> WitnessC p m
WitnessC ForeignPtr Int32
fptr }
enumerate :: Witness (CFq p m) -> [CFq p m]
enumerate (WitnessC ForeignPtr Int32
fptr) = forall a b. (a -> b) -> [a] -> [b]
map (\Raw Any Any
r -> forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> Int32 -> CFq p m
CFq ForeignPtr Int32
fptr (forall (p :: Nat) (m :: Nat). Raw p m -> Int32
fromRaw Raw Any Any
r)) (forall (p :: Nat) (m :: Nat). WitnessC p m -> [Raw p m]
rawEnumerate (forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> WitnessC p m
WitnessC ForeignPtr Int32
fptr))
embed :: Witness (CFq p m) -> Integer -> CFq p m
embed (WitnessC ForeignPtr Int32
fptr) !Integer
k = forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> Int32 -> CFq p m
CFq ForeignPtr Int32
fptr (forall (p :: Nat) (m :: Nat). Raw p m -> Int32
fromRaw (forall (p :: Nat) (m :: Nat). WitnessC p m -> Int -> Raw p m
rawEmbed (forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> WitnessC p m
WitnessC ForeignPtr Int32
fptr) (forall a. Num a => Integer -> a
fromInteger Integer
k)))
embedSmall :: Witness (CFq p m) -> Int -> CFq p m
embedSmall (WitnessC ForeignPtr Int32
fptr) !Int
k = forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> Int32 -> CFq p m
CFq ForeignPtr Int32
fptr (forall (p :: Nat) (m :: Nat). Raw p m -> Int32
fromRaw (forall (p :: Nat) (m :: Nat). WitnessC p m -> Int -> Raw p m
rawEmbed (forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> WitnessC p m
WitnessC ForeignPtr Int32
fptr) Int
k ))
randomFieldElem :: forall gen.
RandomGen gen =>
Witness (CFq p m) -> gen -> (CFq p m, gen)
randomFieldElem Witness (CFq p m)
w = forall gen (p :: Nat) (m :: Nat).
RandomGen gen =>
WitnessC p m -> gen -> (CFq p m, gen)
randomCFq Witness (CFq p m)
w
randomInvertible :: forall gen.
RandomGen gen =>
Witness (CFq p m) -> gen -> (CFq p m, gen)
randomInvertible Witness (CFq p m)
w = forall gen (p :: Nat) (m :: Nat).
RandomGen gen =>
WitnessC p m -> gen -> (CFq p m, gen)
randomInvCFq Witness (CFq p m)
w
power :: CFq p m -> Integer -> CFq p m
power (CFq ForeignPtr Int32
fptr Int32
x) Integer
e = forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> Int32 -> CFq p m
CFq ForeignPtr Int32
fptr (forall (p :: Nat) (m :: Nat). Raw p m -> Int32
fromRaw (forall (p :: Nat) (m :: Nat).
WitnessC p m -> Raw p m -> Int -> Raw p m
rawPow (forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> WitnessC p m
WitnessC ForeignPtr Int32
fptr) (forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw Int32
x) (forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
e)))
powerSmall :: CFq p m -> Int -> CFq p m
powerSmall (CFq ForeignPtr Int32
fptr Int32
x) Int
e = forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> Int32 -> CFq p m
CFq ForeignPtr Int32
fptr (forall (p :: Nat) (m :: Nat). Raw p m -> Int32
fromRaw (forall (p :: Nat) (m :: Nat).
WitnessC p m -> Raw p m -> Int -> Raw p m
rawPow (forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> WitnessC p m
WitnessC ForeignPtr Int32
fptr) (forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw Int32
x) Int
e ))
zero :: Witness (CFq p m) -> CFq p m
zero (WitnessC ForeignPtr Int32
fptr) = forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> Int32 -> CFq p m
CFq ForeignPtr Int32
fptr (-Int32
1)
one :: Witness (CFq p m) -> CFq p m
one (WitnessC ForeignPtr Int32
fptr) = forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> Int32 -> CFq p m
CFq ForeignPtr Int32
fptr Int32
0
primGen :: Witness (CFq p m) -> CFq p m
primGen (WitnessC ForeignPtr Int32
fptr) = forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> Int32 -> CFq p m
CFq ForeignPtr Int32
fptr Int32
1
isZero :: CFq p m -> Bool
isZero (CFq ForeignPtr Int32
_ Int32
a) = Int32
a forall a. Eq a => a -> a -> Bool
== -Int32
1
isOne :: CFq p m -> Bool
isOne (CFq ForeignPtr Int32
_ Int32
a) = Int32
a forall a. Eq a => a -> a -> Bool
== Int32
0
randomCFq :: RandomGen gen => WitnessC p m -> gen -> (CFq p m, gen)
randomCFq :: forall gen (p :: Nat) (m :: Nat).
RandomGen gen =>
WitnessC p m -> gen -> (CFq p m, gen)
randomCFq w :: WitnessC p m
w@(WitnessC ForeignPtr Int32
fptr) gen
g =
let q :: Int
q = forall (p :: Nat) (m :: Nat). WitnessC p m -> Int
rawFieldSize WitnessC p m
w
in case forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (-Int
1,Int
qforall a. Num a => a -> a -> a
-Int
2) gen
g of (Int
k,gen
g') -> (forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> Int32 -> CFq p m
CFq ForeignPtr Int32
fptr (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k), gen
g')
randomInvCFq :: RandomGen gen => WitnessC p m -> gen -> (CFq p m, gen)
randomInvCFq :: forall gen (p :: Nat) (m :: Nat).
RandomGen gen =>
WitnessC p m -> gen -> (CFq p m, gen)
randomInvCFq w :: WitnessC p m
w@(WitnessC ForeignPtr Int32
fptr) gen
g =
let q :: Int
q = forall (p :: Nat) (m :: Nat). WitnessC p m -> Int
rawFieldSize WitnessC p m
w
in case forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (Int
0,Int
qforall a. Num a => a -> a -> a
-Int
2) gen
g of (Int
k,gen
g') -> (forall (p :: Nat) (m :: Nat). ForeignPtr Int32 -> Int32 -> CFq p m
CFq ForeignPtr Int32
fptr (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k), gen
g')
newtype Raw (p :: Nat) (m :: Nat)
= Raw Int32
deriving (Raw p m -> Raw p m -> Bool
forall (p :: Nat) (m :: Nat). Raw p m -> Raw p m -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Raw p m -> Raw p m -> Bool
$c/= :: forall (p :: Nat) (m :: Nat). Raw p m -> Raw p m -> Bool
== :: Raw p m -> Raw p m -> Bool
$c== :: forall (p :: Nat) (m :: Nat). Raw p m -> Raw p m -> Bool
Eq,Raw p m -> Raw p m -> Bool
Raw p m -> Raw p m -> Ordering
Raw p m -> Raw p m -> Raw p m
forall (p :: Nat) (m :: Nat). Eq (Raw p m)
forall (p :: Nat) (m :: Nat). Raw p m -> Raw p m -> Bool
forall (p :: Nat) (m :: Nat). Raw p m -> Raw p m -> Ordering
forall (p :: Nat) (m :: Nat). Raw p m -> Raw p m -> Raw p m
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Raw p m -> Raw p m -> Raw p m
$cmin :: forall (p :: Nat) (m :: Nat). Raw p m -> Raw p m -> Raw p m
max :: Raw p m -> Raw p m -> Raw p m
$cmax :: forall (p :: Nat) (m :: Nat). Raw p m -> Raw p m -> Raw p m
>= :: Raw p m -> Raw p m -> Bool
$c>= :: forall (p :: Nat) (m :: Nat). Raw p m -> Raw p m -> Bool
> :: Raw p m -> Raw p m -> Bool
$c> :: forall (p :: Nat) (m :: Nat). Raw p m -> Raw p m -> Bool
<= :: Raw p m -> Raw p m -> Bool
$c<= :: forall (p :: Nat) (m :: Nat). Raw p m -> Raw p m -> Bool
< :: Raw p m -> Raw p m -> Bool
$c< :: forall (p :: Nat) (m :: Nat). Raw p m -> Raw p m -> Bool
compare :: Raw p m -> Raw p m -> Ordering
$ccompare :: forall (p :: Nat) (m :: Nat). Raw p m -> Raw p m -> Ordering
Ord)
fromRaw :: Raw p m -> Int32
fromRaw :: forall (p :: Nat) (m :: Nat). Raw p m -> Int32
fromRaw (Raw Int32
k) = Int32
k
instance Show (Raw p m) where
show :: Raw p m -> String
show (Raw Int32
k)
| Int32
k forall a. Eq a => a -> a -> Bool
== -Int32
1 = String
"0"
| Int32
k forall a. Eq a => a -> a -> Bool
== Int32
0 = String
"1"
| Int32
k forall a. Eq a => a -> a -> Bool
== Int32
1 = String
"g"
| Bool
otherwise = String
"g^" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int32
k
rawNeg :: WitnessC p m -> Raw p m -> Raw p m
rawNeg :: forall (p :: Nat) (m :: Nat). WitnessC p m -> Raw p m -> Raw p m
rawNeg (WitnessC ForeignPtr Int32
fptr) (Raw Int32
x) = forall a. IO a -> a
unsafePerformIO (forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Int32
fptr (\Ptr Int32
ptr -> forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Int32 -> Int32 -> IO Int32
zech_neg Ptr Int32
ptr Int32
x))
rawAdd :: WitnessC p m -> Raw p m -> Raw p m -> Raw p m
rawAdd :: forall (p :: Nat) (m :: Nat).
WitnessC p m -> Raw p m -> Raw p m -> Raw p m
rawAdd (WitnessC ForeignPtr Int32
fptr) (Raw Int32
x) (Raw Int32
y) = forall a. IO a -> a
unsafePerformIO (forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Int32
fptr (\Ptr Int32
ptr -> forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Int32 -> Int32 -> Int32 -> IO Int32
zech_add Ptr Int32
ptr Int32
x Int32
y))
rawSub :: WitnessC p m -> Raw p m -> Raw p m -> Raw p m
rawSub :: forall (p :: Nat) (m :: Nat).
WitnessC p m -> Raw p m -> Raw p m -> Raw p m
rawSub (WitnessC ForeignPtr Int32
fptr) (Raw Int32
x) (Raw Int32
y) = forall a. IO a -> a
unsafePerformIO (forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Int32
fptr (\Ptr Int32
ptr -> forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Int32 -> Int32 -> Int32 -> IO Int32
zech_sub Ptr Int32
ptr Int32
x Int32
y))
rawInv :: WitnessC p m -> Raw p m -> Raw p m
rawInv :: forall (p :: Nat) (m :: Nat). WitnessC p m -> Raw p m -> Raw p m
rawInv (WitnessC ForeignPtr Int32
fptr) (Raw Int32
x) = forall a. IO a -> a
unsafePerformIO (forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Int32
fptr (\Ptr Int32
ptr -> forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Int32 -> Int32 -> IO Int32
zech_inv Ptr Int32
ptr Int32
x))
rawMul :: WitnessC p m -> Raw p m -> Raw p m -> Raw p m
rawMul :: forall (p :: Nat) (m :: Nat).
WitnessC p m -> Raw p m -> Raw p m -> Raw p m
rawMul (WitnessC ForeignPtr Int32
fptr) (Raw Int32
x) (Raw Int32
y) = forall a. IO a -> a
unsafePerformIO (forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Int32
fptr (\Ptr Int32
ptr -> forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Int32 -> Int32 -> Int32 -> IO Int32
zech_mul Ptr Int32
ptr Int32
x Int32
y))
rawDiv :: WitnessC p m -> Raw p m -> Raw p m -> Raw p m
rawDiv :: forall (p :: Nat) (m :: Nat).
WitnessC p m -> Raw p m -> Raw p m -> Raw p m
rawDiv (WitnessC ForeignPtr Int32
fptr) (Raw Int32
x) (Raw Int32
y) = forall a. IO a -> a
unsafePerformIO (forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Int32
fptr (\Ptr Int32
ptr -> forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Int32 -> Int32 -> Int32 -> IO Int32
zech_div Ptr Int32
ptr Int32
x Int32
y))
rawPow :: WitnessC p m -> Raw p m -> Int -> Raw p m
rawPow :: forall (p :: Nat) (m :: Nat).
WitnessC p m -> Raw p m -> Int -> Raw p m
rawPow (WitnessC ForeignPtr Int32
fptr) (Raw Int32
x) Int
e = forall a. IO a -> a
unsafePerformIO (forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Int32
fptr (\Ptr Int32
ptr -> forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Int32 -> Int32 -> CInt -> IO Int32
zech_pow Ptr Int32
ptr Int32
x (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
e)))
rawIsZero :: Raw p m -> Bool
rawIsZero :: forall (p :: Nat) (m :: Nat). Raw p m -> Bool
rawIsZero (Raw Int32
x) = (CBool -> Bool
cboolToBool forall a b. (a -> b) -> a -> b
$ Int32 -> CBool
zech_is_zero Int32
x)
rawIsOne :: Raw p m -> Bool
rawIsOne :: forall (p :: Nat) (m :: Nat). Raw p m -> Bool
rawIsOne (Raw Int32
x) = (CBool -> Bool
cboolToBool forall a b. (a -> b) -> a -> b
$ Int32 -> CBool
zech_is_one Int32
x)
rawZero :: Raw p m
rawZero :: forall (p :: Nat) (m :: Nat). Raw p m
rawZero = forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw (-Int32
1)
rawOne :: Raw p m
rawOne :: forall (p :: Nat) (m :: Nat). Raw p m
rawOne = forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw Int32
0
rawPrim :: Raw p m
rawPrim :: forall (p :: Nat) (m :: Nat). Raw p m
rawPrim = forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw Int32
1
rawEmbed :: WitnessC p m -> Int -> Raw p m
rawEmbed :: forall (p :: Nat) (m :: Nat). WitnessC p m -> Int -> Raw p m
rawEmbed (WitnessC ForeignPtr Int32
fptr) Int
k = forall a. IO a -> a
unsafePerformIO (forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Int32
fptr (\Ptr Int32
ptr -> forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Int32 -> CInt -> IO Int32
zech_embed Ptr Int32
ptr (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k)))
rawEnumerate :: WitnessC p m -> [Raw p m]
rawEnumerate :: forall (p :: Nat) (m :: Nat). WitnessC p m -> [Raw p m]
rawEnumerate (WitnessC ForeignPtr Int32
fptr) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ do
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Int32
fptr forall a b. (a -> b) -> a -> b
$ \Ptr Int32
ptr -> do
Int32
qminus1 <- forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Int32
ptr Int
2 :: IO Int32
let q :: Int
q = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
qminus1 forall a. Num a => a -> a -> a
+ Int
1 :: Int
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes (Int
4forall a. Num a => a -> a -> a
*Int
q) forall a b. (a -> b) -> a -> b
$ \Ptr Int32
tgt -> do
CInt
_ <- Ptr Int32 -> Ptr Int32 -> IO CInt
zech_enumerate Ptr Int32
ptr Ptr Int32
tgt
forall a b. (a -> b) -> [a] -> [b]
map forall (p :: Nat) (m :: Nat). Int32 -> Raw p m
Raw forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
q Ptr Int32
tgt
rawPrime :: WitnessC p m -> Int
rawPrime :: forall (p :: Nat) (m :: Nat). WitnessC p m -> Int
rawPrime (WitnessC ForeignPtr Int32
fptr) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Int32
fptr forall a b. (a -> b) -> a -> b
$ \Ptr Int32
ptr -> forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Int32
ptr Int
0
rawDim :: WitnessC p m -> Int
rawDim :: forall (p :: Nat) (m :: Nat). WitnessC p m -> Int
rawDim (WitnessC ForeignPtr Int32
fptr) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Int32
fptr forall a b. (a -> b) -> a -> b
$ \Ptr Int32
ptr -> forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Int32
ptr Int
1
rawFieldSize :: WitnessC p m -> Int
rawFieldSize :: forall (p :: Nat) (m :: Nat). WitnessC p m -> Int
rawFieldSize (WitnessC ForeignPtr Int32
fptr) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ do
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Int32
fptr forall a b. (a -> b) -> a -> b
$ \Ptr Int32
ptr -> do
Int32
qminus1 <- forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Int32
ptr Int
2 :: IO Int32
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
qminus1 forall a. Num a => a -> a -> a
+ Int
1)
cboolToBool :: CBool -> Bool
cboolToBool :: CBool -> Bool
cboolToBool CBool
b = (CBool
b forall a. Eq a => a -> a -> Bool
/= CBool
0)
foreign import ccall unsafe "zech_neg" zech_neg :: Ptr Int32 -> Int32 -> IO Int32
foreign import ccall unsafe "zech_add" zech_add :: Ptr Int32 -> Int32 -> Int32 -> IO Int32
foreign import ccall unsafe "zech_sub" zech_sub :: Ptr Int32 -> Int32 -> Int32 -> IO Int32
foreign import ccall unsafe "zech_inv" zech_inv :: Ptr Int32 -> Int32 -> IO Int32
foreign import ccall unsafe "zech_mul" zech_mul :: Ptr Int32 -> Int32 -> Int32 -> IO Int32
foreign import ccall unsafe "zech_div" zech_div :: Ptr Int32 -> Int32 -> Int32 -> IO Int32
foreign import ccall unsafe "zech_pow" zech_pow :: Ptr Int32 -> Int32 -> CInt -> IO Int32
foreign import ccall unsafe "zech_zero" zech_zero :: Int32
foreign import ccall unsafe "zech_one" zech_one :: Int32
foreign import ccall unsafe "zech_prim" zech_prim :: Int32
foreign import ccall unsafe "zech_is_zero" zech_is_zero :: Int32 -> CBool
foreign import ccall unsafe "zech_is_one" zech_is_one :: Int32 -> CBool
foreign import ccall unsafe "zech_embed" zech_embed :: Ptr Int32 -> CInt -> IO Int32
foreign import ccall unsafe "zech_enumerate" zech_enumerate :: Ptr Int32 -> Ptr Int32 -> IO CInt