{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module ZkFold.Base.Algebra.Basic.Field (
IrreduciblePoly(..),
Zp,
toZp,
fromZp,
inv,
Ext2(..),
Ext3(..)
) where
import Control.Applicative ((<|>))
import Control.DeepSeq (NFData (..))
import Data.Aeson (FromJSON (..), ToJSON (..))
import Data.Bifunctor (first)
import Data.Bool (bool)
import qualified Data.Vector as V
import GHC.Generics (Generic)
import GHC.Real ((%))
import GHC.TypeLits (Symbol)
import Prelude hiding (Fractional (..), Num (..), div, length, (^))
import qualified Prelude as Haskell
import System.Random (Random (..), RandomGen, mkStdGen, uniformR)
import Test.QuickCheck hiding (scale)
import ZkFold.Base.Algebra.Basic.Class
import ZkFold.Base.Algebra.Basic.Number
import ZkFold.Base.Algebra.Polynomials.Univariate
import ZkFold.Base.Data.ByteString
import ZkFold.Prelude (log2ceiling)
newtype Zp (p :: Natural) = Zp Integer
deriving ((forall x. Zp p -> Rep (Zp p) x)
-> (forall x. Rep (Zp p) x -> Zp p) -> Generic (Zp p)
forall (p :: Natural) x. Rep (Zp p) x -> Zp p
forall (p :: Natural) x. Zp p -> Rep (Zp p) x
forall x. Rep (Zp p) x -> Zp p
forall x. Zp p -> Rep (Zp p) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall (p :: Natural) x. Zp p -> Rep (Zp p) x
from :: forall x. Zp p -> Rep (Zp p) x
$cto :: forall (p :: Natural) x. Rep (Zp p) x -> Zp p
to :: forall x. Rep (Zp p) x -> Zp p
Generic, Zp p -> ()
(Zp p -> ()) -> NFData (Zp p)
forall (p :: Natural). Zp p -> ()
forall a. (a -> ()) -> NFData a
$crnf :: forall (p :: Natural). Zp p -> ()
rnf :: Zp p -> ()
NFData)
{-# INLINE fromZp #-}
fromZp :: Zp p -> Natural
fromZp :: forall (p :: Natural). Zp p -> Natural
fromZp (Zp Integer
a) = Integer -> Natural
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
a
{-# INLINE residue #-}
residue :: forall p . KnownNat p => Integer -> Integer
residue :: forall (p :: Natural). KnownNat p => Integer -> Integer
residue = (Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`Haskell.mod` Natural -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall (n :: Natural). KnownNat n => Natural
value @p))
{-# INLINE toZp #-}
toZp :: forall p . KnownNat p => Integer -> Zp p
toZp :: forall (p :: Natural). KnownNat p => Integer -> Zp p
toZp = Integer -> Zp p
forall (p :: Natural). Integer -> Zp p
Zp (Integer -> Zp p) -> (Integer -> Integer) -> Integer -> Zp p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: Natural). KnownNat p => Integer -> Integer
residue @p
instance ToConstant (Zp p) where
type Const (Zp p) = Natural
toConstant :: Zp p -> Const (Zp p)
toConstant = Zp p -> Natural
Zp p -> Const (Zp p)
forall (p :: Natural). Zp p -> Natural
fromZp
instance (KnownNat p, KnownNat (NumberOfBits (Zp p))) => Finite (Zp p) where
type Order (Zp p) = p
instance KnownNat p => Eq (Zp p) where
Zp Integer
a == :: Zp p -> Zp p -> Bool
== Zp Integer
b = forall (p :: Natural). KnownNat p => Integer -> Integer
residue @p (Integer
a Integer -> Integer -> Integer
forall a. AdditiveGroup a => a -> a -> a
- Integer
b) Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0
instance KnownNat p => Ord (Zp p) where
Zp Integer
a <= :: Zp p -> Zp p -> Bool
<= Zp Integer
b = forall (p :: Natural). KnownNat p => Integer -> Integer
residue @p Integer
a Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= forall (p :: Natural). KnownNat p => Integer -> Integer
residue @p Integer
b
instance KnownNat p => AdditiveSemigroup (Zp p) where
Zp Integer
a + :: Zp p -> Zp p -> Zp p
+ Zp Integer
b = Integer -> Zp p
forall (p :: Natural). KnownNat p => Integer -> Zp p
toZp (Integer
a Integer -> Integer -> Integer
forall a. AdditiveSemigroup a => a -> a -> a
+ Integer
b)
instance KnownNat p => Scale Natural (Zp p) where
scale :: Natural -> Zp p -> Zp p
scale Natural
c (Zp Integer
a) = Integer -> Zp p
forall (p :: Natural). KnownNat p => Integer -> Zp p
toZp (Natural -> Integer -> Integer
forall b a. Scale b a => b -> a -> a
scale Natural
c Integer
a)
instance KnownNat p => AdditiveMonoid (Zp p) where
zero :: Zp p
zero = Integer -> Zp p
forall (p :: Natural). Integer -> Zp p
Zp Integer
0
instance KnownNat p => Scale Integer (Zp p) where
scale :: Integer -> Zp p -> Zp p
scale Integer
c (Zp Integer
a) = Integer -> Zp p
forall (p :: Natural). KnownNat p => Integer -> Zp p
toZp (Integer -> Integer -> Integer
forall b a. Scale b a => b -> a -> a
scale Integer
c Integer
a)
instance KnownNat p => AdditiveGroup (Zp p) where
negate :: Zp p -> Zp p
negate (Zp Integer
a) = Integer -> Zp p
forall (p :: Natural). KnownNat p => Integer -> Zp p
toZp (Integer -> Integer
forall a. AdditiveGroup a => a -> a
negate Integer
a)
Zp Integer
a - :: Zp p -> Zp p -> Zp p
- Zp Integer
b = Integer -> Zp p
forall (p :: Natural). KnownNat p => Integer -> Zp p
toZp (Integer
a Integer -> Integer -> Integer
forall a. AdditiveGroup a => a -> a -> a
- Integer
b)
instance KnownNat p => MultiplicativeSemigroup (Zp p) where
Zp Integer
a * :: Zp p -> Zp p -> Zp p
* Zp Integer
b = Integer -> Zp p
forall (p :: Natural). KnownNat p => Integer -> Zp p
toZp (Integer
a Integer -> Integer -> Integer
forall a. MultiplicativeSemigroup a => a -> a -> a
* Integer
b)
instance KnownNat p => Exponent (Zp p) Natural where
^ :: Zp p -> Natural -> Zp p
(^) = Zp p -> Natural -> Zp p
forall a. MultiplicativeMonoid a => a -> Natural -> a
natPow
instance KnownNat p => MultiplicativeMonoid (Zp p) where
one :: Zp p
one = Integer -> Zp p
forall (p :: Natural). Integer -> Zp p
Zp Integer
1
instance KnownNat p => FromConstant Natural (Zp p) where
fromConstant :: Natural -> Zp p
fromConstant = Integer -> Zp p
forall (p :: Natural). KnownNat p => Integer -> Zp p
toZp (Integer -> Zp p) -> (Natural -> Integer) -> Natural -> Zp p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Natural -> Integer
forall a b. FromConstant a b => a -> b
fromConstant
instance KnownNat p => Semiring (Zp p)
instance KnownNat p => SemiEuclidean (Zp p) where
divMod :: Zp p -> Zp p -> (Zp p, Zp p)
divMod Zp p
a Zp p
b = let (Natural
q, Natural
r) = Natural -> Natural -> (Natural, Natural)
forall a. Integral a => a -> a -> (a, a)
Haskell.divMod (Zp p -> Natural
forall (p :: Natural). Zp p -> Natural
fromZp Zp p
a) (Zp p -> Natural
forall (p :: Natural). Zp p -> Natural
fromZp Zp p
b)
in (Integer -> Zp p
forall (p :: Natural). KnownNat p => Integer -> Zp p
toZp (Integer -> Zp p) -> (Natural -> Integer) -> Natural -> Zp p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Natural -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Natural -> Zp p) -> Natural -> Zp p
forall a b. (a -> b) -> a -> b
$ Natural
q, Integer -> Zp p
forall (p :: Natural). KnownNat p => Integer -> Zp p
toZp (Integer -> Zp p) -> (Natural -> Integer) -> Natural -> Zp p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Natural -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Natural -> Zp p) -> Natural -> Zp p
forall a b. (a -> b) -> a -> b
$ Natural
r)
instance KnownNat p => FromConstant Integer (Zp p) where
fromConstant :: Integer -> Zp p
fromConstant = Integer -> Zp p
forall (p :: Natural). KnownNat p => Integer -> Zp p
toZp
instance KnownNat p => Ring (Zp p)
instance Prime p => Exponent (Zp p) Integer where
Zp p
a ^ :: Zp p -> Integer -> Zp p
^ Integer
n = Zp p -> Integer -> Zp p
forall a. Field a => a -> Integer -> a
intPowF Zp p
a (Integer
n Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`Haskell.mod` (Natural -> Integer
forall a b. FromConstant a b => a -> b
fromConstant (forall (n :: Natural). KnownNat n => Natural
value @p) Integer -> Integer -> Integer
forall a. AdditiveGroup a => a -> a -> a
- Integer
1))
instance Prime p => Field (Zp p) where
finv :: Zp p -> Zp p
finv (Zp Integer
a) = Natural -> Zp p
forall a b. FromConstant a b => a -> b
fromConstant (Natural -> Zp p) -> Natural -> Zp p
forall a b. (a -> b) -> a -> b
$ Integer -> Natural -> Natural
inv Integer
a (forall (n :: Natural). KnownNat n => Natural
value @p)
rootOfUnity :: Natural -> Maybe (Zp p)
rootOfUnity Natural
l
| Natural
l Natural -> Natural -> Bool
forall a. Eq a => a -> a -> Bool
== Natural
0 = Maybe (Zp p)
forall a. Maybe a
Nothing
| (forall (n :: Natural). KnownNat n => Natural
value @p Natural -> Natural -> Natural
-! Natural
1) Natural -> Natural -> Natural
forall a. Integral a => a -> a -> a
`Haskell.mod` Natural
n Natural -> Natural -> Bool
forall a. Eq a => a -> a -> Bool
/= Natural
0 = Maybe (Zp p)
forall a. Maybe a
Nothing
| Bool
otherwise = Zp p -> Maybe (Zp p)
forall a. a -> Maybe a
Just (Zp p -> Maybe (Zp p)) -> Zp p -> Maybe (Zp p)
forall a b. (a -> b) -> a -> b
$ StdGen -> Zp p
forall g. RandomGen g => g -> Zp p
rootOfUnity' (Int -> StdGen
mkStdGen Int
0)
where
n :: Natural
n = Natural
2 Natural -> Natural -> Natural
forall a b. Exponent a b => a -> b -> a
^ Natural
l
rootOfUnity' :: RandomGen g => g -> Zp p
rootOfUnity' :: forall g. RandomGen g => g -> Zp p
rootOfUnity' g
g =
let (Zp p
x, g
g') = (Natural -> Zp p) -> (Natural, g) -> (Zp p, g)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: Type -> Type -> Type) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first Natural -> Zp p
forall a b. FromConstant a b => a -> b
fromConstant ((Natural, g) -> (Zp p, g)) -> (Natural, g) -> (Zp p, g)
forall a b. (a -> b) -> a -> b
$ (Natural, Natural) -> g -> (Natural, g)
forall g a. (RandomGen g, UniformRange a) => (a, a) -> g -> (a, g)
uniformR (Natural
1, forall (n :: Natural). KnownNat n => Natural
value @p Natural -> Natural -> Natural
-! Natural
1) g
g
x' :: Zp p
x' = Zp p
x Zp p -> Natural -> Zp p
forall a b. Exponent a b => a -> b -> a
^ ((forall (n :: Natural). KnownNat n => Natural
value @p Natural -> Natural -> Natural
-! Natural
1) Natural -> Natural -> Natural
forall a. Integral a => a -> a -> a
`Haskell.div` Natural
n)
in Zp p -> Zp p -> Bool -> Zp p
forall a. a -> a -> Bool -> a
bool (g -> Zp p
forall g. RandomGen g => g -> Zp p
rootOfUnity' g
g') Zp p
x' (Zp p
x' Zp p -> Natural -> Zp p
forall a b. Exponent a b => a -> b -> a
^ (Natural
n Natural -> Natural -> Natural
forall a. Integral a => a -> a -> a
`Haskell.div` Natural
2) Zp p -> Zp p -> Bool
forall a. Eq a => a -> a -> Bool
/= Zp p
forall a. MultiplicativeMonoid a => a
one)
inv :: Integer -> Natural -> Natural
inv :: Integer -> Natural -> Natural
inv Integer
a Natural
p = Integer -> Natural
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> Natural) -> Integer -> Natural
forall a b. (a -> b) -> a -> b
$ (Integer, Integer) -> Integer
forall a b. (a, b) -> b
snd ((Integer, Integer) -> (Integer, Integer) -> (Integer, Integer)
forall {b}.
(Eq b, Num b, SemiEuclidean b, AdditiveGroup b) =>
(b, b) -> (b, b) -> (b, b)
egcd (Integer
a, Integer
1) (Natural -> Integer
forall a b. FromConstant a b => a -> b
fromConstant Natural
p, Integer
0)) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`Haskell.mod` Natural -> Integer
forall a b. FromConstant a b => a -> b
fromConstant Natural
p
where
egcd :: (b, b) -> (b, b) -> (b, b)
egcd (b
x, b
y) (b
0, b
_) = (b
x, b
y)
egcd (b
x, b
y) (b
x', b
y') = (b, b) -> (b, b) -> (b, b)
egcd (b
x', b
y') (b
x b -> b -> b
forall a. AdditiveGroup a => a -> a -> a
- b
q b -> b -> b
forall a. MultiplicativeSemigroup a => a -> a -> a
* b
x', b
y b -> b -> b
forall a. AdditiveGroup a => a -> a -> a
- b
q b -> b -> b
forall a. MultiplicativeSemigroup a => a -> a -> a
* b
y')
where q :: b
q = b
x b -> b -> b
forall a. SemiEuclidean a => a -> a -> a
`div` b
x'
instance Prime p => BinaryExpansion (Zp p) where
type Bits (Zp p) = [Zp p]
binaryExpansion :: Zp p -> Bits (Zp p)
binaryExpansion = (Natural -> Zp p) -> [Natural] -> [Zp p]
forall a b. (a -> b) -> [a] -> [b]
map (Integer -> Zp p
forall (p :: Natural). Integer -> Zp p
Zp (Integer -> Zp p) -> (Natural -> Integer) -> Natural -> Zp p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Natural -> Integer
forall a b. FromConstant a b => a -> b
fromConstant) ([Natural] -> [Zp p]) -> (Zp p -> [Natural]) -> Zp p -> [Zp p]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Natural -> [Natural]
Natural -> Bits Natural
forall a. BinaryExpansion a => a -> Bits a
binaryExpansion (Natural -> [Natural]) -> (Zp p -> Natural) -> Zp p -> [Natural]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Zp p -> Natural
forall (p :: Natural). Zp p -> Natural
fromZp
instance Prime p => DiscreteField' (Zp p)
instance Prime p => TrichotomyField (Zp p)
instance KnownNat p => Haskell.Num (Zp p) where
fromInteger :: Integer -> Zp p
fromInteger = Integer -> Zp p
forall (p :: Natural). KnownNat p => Integer -> Zp p
toZp
+ :: Zp p -> Zp p -> Zp p
(+) = Zp p -> Zp p -> Zp p
forall a. AdditiveSemigroup a => a -> a -> a
(+)
(-) = (-)
* :: Zp p -> Zp p -> Zp p
(*) = Zp p -> Zp p -> Zp p
forall a. MultiplicativeSemigroup a => a -> a -> a
(*)
negate :: Zp p -> Zp p
negate = Zp p -> Zp p
forall a. AdditiveGroup a => a -> a
negate
abs :: Zp p -> Zp p
abs = Zp p -> Zp p
forall a. a -> a
id
signum :: Zp p -> Zp p
signum = Zp p -> Zp p -> Zp p
forall a b. a -> b -> a
const Zp p
1
instance Prime p => Haskell.Fractional (Zp p) where
fromRational :: Rational -> Zp p
fromRational = [Char] -> Rational -> Zp p
forall a. HasCallStack => [Char] -> a
error [Char]
"`fromRational` is not implemented for `Zp p`"
recip :: Zp p -> Zp p
recip = Zp p -> Zp p
forall a. Field a => a -> a
finv
/ :: Zp p -> Zp p -> Zp p
(/) = Zp p -> Zp p -> Zp p
forall a. Field a => a -> a -> a
(//)
instance Show (Zp p) where
show :: Zp p -> [Char]
show (Zp Integer
a) = Integer -> [Char]
forall a. Show a => a -> [Char]
show Integer
a
instance ToJSON (Zp p) where
toJSON :: Zp p -> Value
toJSON (Zp Integer
a) = Integer -> Value
forall a. ToJSON a => a -> Value
toJSON Integer
a
instance FromJSON (Zp p) where
parseJSON :: Value -> Parser (Zp p)
parseJSON = (Integer -> Zp p) -> Parser Integer -> Parser (Zp p)
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap Integer -> Zp p
forall (p :: Natural). Integer -> Zp p
Zp (Parser Integer -> Parser (Zp p))
-> (Value -> Parser Integer) -> Value -> Parser (Zp p)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Parser Integer
forall a. FromJSON a => Value -> Parser a
parseJSON
instance KnownNat p => Binary (Zp p) where
put :: Zp p -> Put
put (Zp Integer
x) = Integer -> Natural -> Put
forall {t}. Integral t => t -> Natural -> Put
go Integer
x (forall (n :: Natural). KnownNat n => Natural
wordCount @p)
where
go :: t -> Natural -> Put
go t
_ Natural
0 = () -> Put
forall a. a -> PutM a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ()
go t
n Natural
count =
let (t
n', t
r) = t
n t -> t -> (t, t)
forall a. Integral a => a -> a -> (a, a)
`Haskell.divMod` t
256
in Word8 -> Put
putWord8 (t -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral t
r) Put -> Put -> Put
forall a. Semigroup a => a -> a -> a
<> t -> Natural -> Put
go t
n' (Natural
count Natural -> Natural -> Natural
-! Natural
1)
get :: Get (Zp p)
get = Integer -> Zp p
forall (p :: Natural). KnownNat p => Integer -> Zp p
toZp (Integer -> Zp p) -> Get Integer -> Get (Zp p)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Natural -> Get Integer
forall {a}.
(AdditiveMonoid a, MultiplicativeSemigroup a, Num a) =>
Natural -> Get a
go (forall (n :: Natural). KnownNat n => Natural
wordCount @p)
where
go :: Natural -> Get a
go Natural
0 = a -> Get a
forall a. a -> Get a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure a
forall a. AdditiveMonoid a => a
zero
go Natural
n = (Word8 -> a -> a) -> Get Word8 -> Get a -> Get a
forall a b c. (a -> b -> c) -> Get a -> Get b -> Get c
forall (f :: Type -> Type) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Word8 -> a -> a
forall {a} {a}.
(AdditiveSemigroup a, Integral a, MultiplicativeSemigroup a,
Num a) =>
a -> a -> a
combine Get Word8
getWord8 (Natural -> Get a
go (Natural -> Get a) -> Natural -> Get a
forall a b. (a -> b) -> a -> b
$ Natural
n Natural -> Natural -> Natural
-! Natural
1) Get a -> Get a -> Get a
forall a. Get a -> Get a -> Get a
forall (f :: Type -> Type) a. Alternative f => f a -> f a -> f a
<|> a -> Get a
forall a. a -> Get a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure a
forall a. AdditiveMonoid a => a
zero
combine :: a -> a -> a
combine a
r a
d = a -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
r a -> a -> a
forall a. AdditiveSemigroup a => a -> a -> a
+ a
256 a -> a -> a
forall a. MultiplicativeSemigroup a => a -> a -> a
* a
d
wordCount :: forall p. KnownNat p => Natural
wordCount :: forall (n :: Natural). KnownNat n => Natural
wordCount = Ratio Natural -> Natural
forall b. Integral b => Ratio Natural -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Ratio Natural -> Natural) -> Ratio Natural -> Natural
forall a b. (a -> b) -> a -> b
$ Natural -> Natural
forall a b. (Integral a, Integral b) => a -> b
log2ceiling (forall (n :: Natural). KnownNat n => Natural
value @p) Natural -> Natural -> Ratio Natural
forall a. Integral a => a -> a -> Ratio a
% (Natural
8 :: Natural)
instance KnownNat p => Arbitrary (Zp p) where
arbitrary :: Gen (Zp p)
arbitrary = Integer -> Zp p
forall (p :: Natural). KnownNat p => Integer -> Zp p
toZp (Integer -> Zp p) -> Gen Integer -> Gen (Zp p)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> (Integer, Integer) -> Gen Integer
chooseInteger (Integer
0, Natural -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall (n :: Natural). KnownNat n => Natural
value @p) Integer -> Integer -> Integer
forall a. AdditiveGroup a => a -> a -> a
- Integer
1)
instance KnownNat p => Random (Zp p) where
randomR :: forall g. RandomGen g => (Zp p, Zp p) -> g -> (Zp p, g)
randomR (Zp Integer
a, Zp Integer
b) g
g = (Integer -> Zp p
forall (p :: Natural). Integer -> Zp p
Zp Integer
r, g
g')
where
(Integer
r, g
g') = (Integer, Integer) -> g -> (Integer, g)
forall g. RandomGen g => (Integer, Integer) -> g -> (Integer, g)
forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (Integer
a, Integer
b) g
g
random :: forall g. RandomGen g => g -> (Zp p, g)
random g
g = (Integer -> Zp p
forall (p :: Natural). Integer -> Zp p
Zp Integer
r, g
g')
where
(Integer
r, g
g') = (Integer, Integer) -> g -> (Integer, g)
forall g. RandomGen g => (Integer, Integer) -> g -> (Integer, g)
forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (Integer
0, Natural -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall (n :: Natural). KnownNat n => Natural
value @p) Integer -> Integer -> Integer
forall a. AdditiveGroup a => a -> a -> a
- Integer
1) g
g
instance (MultiplicativeGroup a, Order a ~ p) => Exponent a (Zp p) where
a
a ^ :: a -> Zp p -> a
^ Zp p
n = a
a a -> Natural -> a
forall a b. Exponent a b => a -> b -> a
^ Zp p -> Natural
forall (p :: Natural). Zp p -> Natural
fromZp Zp p
n
class IrreduciblePoly f (e :: Symbol) | e -> f where
irreduciblePoly :: Poly f
data Ext2 f (e :: Symbol) = Ext2 f f
deriving (Ext2 f e -> Ext2 f e -> Bool
(Ext2 f e -> Ext2 f e -> Bool)
-> (Ext2 f e -> Ext2 f e -> Bool) -> Eq (Ext2 f e)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall f (e :: Symbol). Eq f => Ext2 f e -> Ext2 f e -> Bool
$c== :: forall f (e :: Symbol). Eq f => Ext2 f e -> Ext2 f e -> Bool
== :: Ext2 f e -> Ext2 f e -> Bool
$c/= :: forall f (e :: Symbol). Eq f => Ext2 f e -> Ext2 f e -> Bool
/= :: Ext2 f e -> Ext2 f e -> Bool
Eq, Int -> Ext2 f e -> ShowS
[Ext2 f e] -> ShowS
Ext2 f e -> [Char]
(Int -> Ext2 f e -> ShowS)
-> (Ext2 f e -> [Char]) -> ([Ext2 f e] -> ShowS) -> Show (Ext2 f e)
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
forall f (e :: Symbol). Show f => Int -> Ext2 f e -> ShowS
forall f (e :: Symbol). Show f => [Ext2 f e] -> ShowS
forall f (e :: Symbol). Show f => Ext2 f e -> [Char]
$cshowsPrec :: forall f (e :: Symbol). Show f => Int -> Ext2 f e -> ShowS
showsPrec :: Int -> Ext2 f e -> ShowS
$cshow :: forall f (e :: Symbol). Show f => Ext2 f e -> [Char]
show :: Ext2 f e -> [Char]
$cshowList :: forall f (e :: Symbol). Show f => [Ext2 f e] -> ShowS
showList :: [Ext2 f e] -> ShowS
Show)
instance Ord f => Ord (Ext2 f e) where
Ext2 f
a f
b <= :: Ext2 f e -> Ext2 f e -> Bool
<= Ext2 f
c f
d = [f
Item [f]
b, f
Item [f]
a] [f] -> [f] -> Bool
forall a. Ord a => a -> a -> Bool
<= ([f
Item [f]
d, f
Item [f]
c] :: [f])
instance (KnownNat (Order (Ext2 f e)), KnownNat (NumberOfBits (Ext2 f e))) => Finite (Ext2 f e) where
type Order (Ext2 f e) = Order f ^ 2
instance {-# OVERLAPPING #-} FromConstant (Ext2 f e) (Ext2 f e)
instance Field f => AdditiveSemigroup (Ext2 f e) where
Ext2 f
a f
b + :: Ext2 f e -> Ext2 f e -> Ext2 f e
+ Ext2 f
c f
d = f -> f -> Ext2 f e
forall f (e :: Symbol). f -> f -> Ext2 f e
Ext2 (f
a f -> f -> f
forall a. AdditiveSemigroup a => a -> a -> a
+ f
c) (f
b f -> f -> f
forall a. AdditiveSemigroup a => a -> a -> a
+ f
d)
instance Scale c f => Scale c (Ext2 f e) where
scale :: c -> Ext2 f e -> Ext2 f e
scale c
c (Ext2 f
a f
b) = f -> f -> Ext2 f e
forall f (e :: Symbol). f -> f -> Ext2 f e
Ext2 (c -> f -> f
forall b a. Scale b a => b -> a -> a
scale c
c f
a) (c -> f -> f
forall b a. Scale b a => b -> a -> a
scale c
c f
b)
instance Field f => AdditiveMonoid (Ext2 f e) where
zero :: Ext2 f e
zero = f -> f -> Ext2 f e
forall f (e :: Symbol). f -> f -> Ext2 f e
Ext2 f
forall a. AdditiveMonoid a => a
zero f
forall a. AdditiveMonoid a => a
zero
instance Field f => AdditiveGroup (Ext2 f e) where
negate :: Ext2 f e -> Ext2 f e
negate (Ext2 f
a f
b) = f -> f -> Ext2 f e
forall f (e :: Symbol). f -> f -> Ext2 f e
Ext2 (f -> f
forall a. AdditiveGroup a => a -> a
negate f
a) (f -> f
forall a. AdditiveGroup a => a -> a
negate f
b)
Ext2 f
a f
b - :: Ext2 f e -> Ext2 f e -> Ext2 f e
- Ext2 f
c f
d = f -> f -> Ext2 f e
forall f (e :: Symbol). f -> f -> Ext2 f e
Ext2 (f
a f -> f -> f
forall a. AdditiveGroup a => a -> a -> a
- f
c) (f
b f -> f -> f
forall a. AdditiveGroup a => a -> a -> a
- f
d)
instance {-# OVERLAPPING #-} (Field f, Eq f, IrreduciblePoly f e) => Scale (Ext2 f e) (Ext2 f e)
instance (Field f, Eq f, IrreduciblePoly f e) => MultiplicativeSemigroup (Ext2 f e) where
Ext2 f
a f
b * :: Ext2 f e -> Ext2 f e -> Ext2 f e
* Ext2 f
c f
d = Poly f -> Ext2 f e
forall a b. FromConstant a b => a -> b
fromConstant (Vector f -> Poly f
forall c. (Ring c, Eq c) => Vector c -> Poly c
toPoly [f
Item (Vector f)
a, f
Item (Vector f)
b] Poly f -> Poly f -> Poly f
forall a. MultiplicativeSemigroup a => a -> a -> a
* Vector f -> Poly f
forall c. (Ring c, Eq c) => Vector c -> Poly c
toPoly [f
Item (Vector f)
c, f
Item (Vector f)
d])
instance MultiplicativeMonoid (Ext2 f e) => Exponent (Ext2 f e) Natural where
^ :: Ext2 f e -> Natural -> Ext2 f e
(^) = Ext2 f e -> Natural -> Ext2 f e
forall a. MultiplicativeMonoid a => a -> Natural -> a
natPow
instance (Field f, Eq f, IrreduciblePoly f e) => MultiplicativeMonoid (Ext2 f e) where
one :: Ext2 f e
one = f -> f -> Ext2 f e
forall f (e :: Symbol). f -> f -> Ext2 f e
Ext2 f
forall a. MultiplicativeMonoid a => a
one f
forall a. AdditiveMonoid a => a
zero
instance Field (Ext2 f e) => Exponent (Ext2 f e) Integer where
^ :: Ext2 f e -> Integer -> Ext2 f e
(^) = Ext2 f e -> Integer -> Ext2 f e
forall a. Field a => a -> Integer -> a
intPowF
instance (Field f, Eq f, IrreduciblePoly f e) => Field (Ext2 f e) where
finv :: Ext2 f e -> Ext2 f e
finv (Ext2 f
a f
b) =
let (Poly f
g, Poly f
s) = Poly f -> Poly f -> (Poly f, Poly f)
forall c. (Field c, Eq c) => Poly c -> Poly c -> (Poly c, Poly c)
eea (Vector f -> Poly f
forall c. (Ring c, Eq c) => Vector c -> Poly c
toPoly [f
Item (Vector f)
a, f
Item (Vector f)
b]) (forall f (e :: Symbol). IrreduciblePoly f e => Poly f
irreduciblePoly @f @e)
in case Poly f -> Vector f
forall c. Poly c -> Vector c
fromPoly (Poly f -> Vector f) -> Poly f -> Vector f
forall a b. (a -> b) -> a -> b
$ f -> Natural -> Poly f -> Poly f
forall c. Ring c => c -> Natural -> Poly c -> Poly c
scaleP (f
forall a. MultiplicativeMonoid a => a
one f -> f -> f
forall a. Field a => a -> a -> a
// Poly f -> f
forall c. Poly c -> c
lt Poly f
g) Natural
0 Poly f
s of
[] -> f -> f -> Ext2 f e
forall f (e :: Symbol). f -> f -> Ext2 f e
Ext2 f
forall a. AdditiveMonoid a => a
zero f
forall a. AdditiveMonoid a => a
zero
[Item (Vector f)
x] -> f -> f -> Ext2 f e
forall f (e :: Symbol). f -> f -> Ext2 f e
Ext2 f
Item (Vector f)
x f
forall a. AdditiveMonoid a => a
zero
Vector f
v -> f -> f -> Ext2 f e
forall f (e :: Symbol). f -> f -> Ext2 f e
Ext2 (Vector f
v Vector f -> Int -> f
forall a. Vector a -> Int -> a
V.! Int
0) (Vector f
v Vector f -> Int -> f
forall a. Vector a -> Int -> a
V.! Int
1)
rootOfUnity :: Natural -> Maybe (Ext2 f e)
rootOfUnity Natural
n = (\f
r -> f -> f -> Ext2 f e
forall f (e :: Symbol). f -> f -> Ext2 f e
Ext2 f
r f
forall a. AdditiveMonoid a => a
zero) (f -> Ext2 f e) -> Maybe f -> Maybe (Ext2 f e)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Natural -> Maybe f
forall a. Field a => Natural -> Maybe a
rootOfUnity Natural
n
instance (FromConstant f f', Field f') => FromConstant f (Ext2 f' e) where
fromConstant :: f -> Ext2 f' e
fromConstant f
e = f' -> f' -> Ext2 f' e
forall f (e :: Symbol). f -> f -> Ext2 f e
Ext2 (f -> f'
forall a b. FromConstant a b => a -> b
fromConstant f
e) f'
forall a. AdditiveMonoid a => a
zero
instance {-# OVERLAPPING #-} (Field f, Eq f, IrreduciblePoly f e) => FromConstant (Poly f) (Ext2 f e) where
fromConstant :: Poly f -> Ext2 f e
fromConstant Poly f
p = case Poly f -> Vector f
forall c. Poly c -> Vector c
fromPoly (Poly f -> Vector f)
-> ((Poly f, Poly f) -> Poly f) -> (Poly f, Poly f) -> Vector f
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Poly f, Poly f) -> Poly f
forall a b. (a, b) -> b
snd ((Poly f, Poly f) -> Vector f) -> (Poly f, Poly f) -> Vector f
forall a b. (a -> b) -> a -> b
$ Poly f -> Poly f -> (Poly f, Poly f)
forall c. (Field c, Eq c) => Poly c -> Poly c -> (Poly c, Poly c)
qr Poly f
p (forall f (e :: Symbol). IrreduciblePoly f e => Poly f
irreduciblePoly @f @e) of
[] -> Ext2 f e
forall a. AdditiveMonoid a => a
zero
[Item (Vector f)
x] -> f -> Ext2 f e
forall a b. FromConstant a b => a -> b
fromConstant f
Item (Vector f)
x
Vector f
v -> f -> f -> Ext2 f e
forall f (e :: Symbol). f -> f -> Ext2 f e
Ext2 (Vector f
v Vector f -> Int -> f
forall a. Vector a -> Int -> a
V.! Int
0) (Vector f
v Vector f -> Int -> f
forall a. Vector a -> Int -> a
V.! Int
1)
instance (Field f, Eq f, IrreduciblePoly f e) => Semiring (Ext2 f e)
instance (Field f, Eq f, IrreduciblePoly f e) => Ring (Ext2 f e)
instance Binary f => Binary (Ext2 f e) where
put :: Ext2 f e -> Put
put (Ext2 f
a f
b) = f -> Put
forall t. Binary t => t -> Put
put f
a Put -> Put -> Put
forall a. Semigroup a => a -> a -> a
<> f -> Put
forall t. Binary t => t -> Put
put f
b
get :: Get (Ext2 f e)
get = f -> f -> Ext2 f e
forall f (e :: Symbol). f -> f -> Ext2 f e
Ext2 (f -> f -> Ext2 f e) -> Get f -> Get (f -> Ext2 f e)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Get f
forall t. Binary t => Get t
get Get (f -> Ext2 f e) -> Get f -> Get (Ext2 f e)
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Get f
forall t. Binary t => Get t
get
instance (Field f, Eq f, IrreduciblePoly f e, Arbitrary f) => Arbitrary (Ext2 f e) where
arbitrary :: Gen (Ext2 f e)
arbitrary = f -> f -> Ext2 f e
forall f (e :: Symbol). f -> f -> Ext2 f e
Ext2 (f -> f -> Ext2 f e) -> Gen f -> Gen (f -> Ext2 f e)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen f
forall a. Arbitrary a => Gen a
arbitrary Gen (f -> Ext2 f e) -> Gen f -> Gen (Ext2 f e)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Gen f
forall a. Arbitrary a => Gen a
arbitrary
data Ext3 f (e :: Symbol) = Ext3 f f f
deriving (Ext3 f e -> Ext3 f e -> Bool
(Ext3 f e -> Ext3 f e -> Bool)
-> (Ext3 f e -> Ext3 f e -> Bool) -> Eq (Ext3 f e)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall f (e :: Symbol). Eq f => Ext3 f e -> Ext3 f e -> Bool
$c== :: forall f (e :: Symbol). Eq f => Ext3 f e -> Ext3 f e -> Bool
== :: Ext3 f e -> Ext3 f e -> Bool
$c/= :: forall f (e :: Symbol). Eq f => Ext3 f e -> Ext3 f e -> Bool
/= :: Ext3 f e -> Ext3 f e -> Bool
Eq, Int -> Ext3 f e -> ShowS
[Ext3 f e] -> ShowS
Ext3 f e -> [Char]
(Int -> Ext3 f e -> ShowS)
-> (Ext3 f e -> [Char]) -> ([Ext3 f e] -> ShowS) -> Show (Ext3 f e)
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
forall f (e :: Symbol). Show f => Int -> Ext3 f e -> ShowS
forall f (e :: Symbol). Show f => [Ext3 f e] -> ShowS
forall f (e :: Symbol). Show f => Ext3 f e -> [Char]
$cshowsPrec :: forall f (e :: Symbol). Show f => Int -> Ext3 f e -> ShowS
showsPrec :: Int -> Ext3 f e -> ShowS
$cshow :: forall f (e :: Symbol). Show f => Ext3 f e -> [Char]
show :: Ext3 f e -> [Char]
$cshowList :: forall f (e :: Symbol). Show f => [Ext3 f e] -> ShowS
showList :: [Ext3 f e] -> ShowS
Show)
instance Ord f => Ord (Ext3 f e) where
Ext3 f
a f
b f
c <= :: Ext3 f e -> Ext3 f e -> Bool
<= Ext3 f
d f
e f
f = [f
Item [f]
c, f
Item [f]
b, f
Item [f]
a] [f] -> [f] -> Bool
forall a. Ord a => a -> a -> Bool
<= ([f
Item [f]
f, f
Item [f]
e, f
Item [f]
d] :: [f])
instance (KnownNat (Order (Ext3 f e)), KnownNat (NumberOfBits (Ext3 f e))) => Finite (Ext3 f e) where
type Order (Ext3 f e) = Order f ^ 3
instance {-# OVERLAPPING #-} FromConstant (Ext3 f e) (Ext3 f e)
instance Field f => AdditiveSemigroup (Ext3 f e) where
Ext3 f
a f
b f
c + :: Ext3 f e -> Ext3 f e -> Ext3 f e
+ Ext3 f
d f
e f
f = f -> f -> f -> Ext3 f e
forall f (e :: Symbol). f -> f -> f -> Ext3 f e
Ext3 (f
a f -> f -> f
forall a. AdditiveSemigroup a => a -> a -> a
+ f
d) (f
b f -> f -> f
forall a. AdditiveSemigroup a => a -> a -> a
+ f
e) (f
c f -> f -> f
forall a. AdditiveSemigroup a => a -> a -> a
+ f
f)
instance Scale c f => Scale c (Ext3 f e) where
scale :: c -> Ext3 f e -> Ext3 f e
scale c
c (Ext3 f
d f
e f
f) = f -> f -> f -> Ext3 f e
forall f (e :: Symbol). f -> f -> f -> Ext3 f e
Ext3 (c -> f -> f
forall b a. Scale b a => b -> a -> a
scale c
c f
d) (c -> f -> f
forall b a. Scale b a => b -> a -> a
scale c
c f
e) (c -> f -> f
forall b a. Scale b a => b -> a -> a
scale c
c f
f)
instance Field f => AdditiveMonoid (Ext3 f e) where
zero :: Ext3 f e
zero = f -> f -> f -> Ext3 f e
forall f (e :: Symbol). f -> f -> f -> Ext3 f e
Ext3 f
forall a. AdditiveMonoid a => a
zero f
forall a. AdditiveMonoid a => a
zero f
forall a. AdditiveMonoid a => a
zero
instance Field f => AdditiveGroup (Ext3 f e) where
negate :: Ext3 f e -> Ext3 f e
negate (Ext3 f
a f
b f
c) = f -> f -> f -> Ext3 f e
forall f (e :: Symbol). f -> f -> f -> Ext3 f e
Ext3 (f -> f
forall a. AdditiveGroup a => a -> a
negate f
a) (f -> f
forall a. AdditiveGroup a => a -> a
negate f
b) (f -> f
forall a. AdditiveGroup a => a -> a
negate f
c)
Ext3 f
a f
b f
c - :: Ext3 f e -> Ext3 f e -> Ext3 f e
- Ext3 f
d f
e f
f = f -> f -> f -> Ext3 f e
forall f (e :: Symbol). f -> f -> f -> Ext3 f e
Ext3 (f
a f -> f -> f
forall a. AdditiveGroup a => a -> a -> a
- f
d) (f
b f -> f -> f
forall a. AdditiveGroup a => a -> a -> a
- f
e) (f
c f -> f -> f
forall a. AdditiveGroup a => a -> a -> a
- f
f)
instance {-# OVERLAPPING #-} (Field f, Eq f, IrreduciblePoly f e) => Scale (Ext3 f e) (Ext3 f e)
instance (Field f, Eq f, IrreduciblePoly f e) => MultiplicativeSemigroup (Ext3 f e) where
Ext3 f
a f
b f
c * :: Ext3 f e -> Ext3 f e -> Ext3 f e
* Ext3 f
d f
e f
f = Poly f -> Ext3 f e
forall a b. FromConstant a b => a -> b
fromConstant (Vector f -> Poly f
forall c. (Ring c, Eq c) => Vector c -> Poly c
toPoly [f
Item (Vector f)
a, f
Item (Vector f)
b, f
Item (Vector f)
c] Poly f -> Poly f -> Poly f
forall a. MultiplicativeSemigroup a => a -> a -> a
* Vector f -> Poly f
forall c. (Ring c, Eq c) => Vector c -> Poly c
toPoly [f
Item (Vector f)
d, f
Item (Vector f)
e, f
Item (Vector f)
f])
instance MultiplicativeMonoid (Ext3 f e) => Exponent (Ext3 f e) Natural where
^ :: Ext3 f e -> Natural -> Ext3 f e
(^) = Ext3 f e -> Natural -> Ext3 f e
forall a. MultiplicativeMonoid a => a -> Natural -> a
natPow
instance (Field f, Eq f, IrreduciblePoly f e) => MultiplicativeMonoid (Ext3 f e) where
one :: Ext3 f e
one = f -> f -> f -> Ext3 f e
forall f (e :: Symbol). f -> f -> f -> Ext3 f e
Ext3 f
forall a. MultiplicativeMonoid a => a
one f
forall a. AdditiveMonoid a => a
zero f
forall a. AdditiveMonoid a => a
zero
instance Field (Ext3 f e) => Exponent (Ext3 f e) Integer where
^ :: Ext3 f e -> Integer -> Ext3 f e
(^) = Ext3 f e -> Integer -> Ext3 f e
forall a. Field a => a -> Integer -> a
intPowF
instance (Field f, Eq f, IrreduciblePoly f e) => Field (Ext3 f e) where
finv :: Ext3 f e -> Ext3 f e
finv (Ext3 f
a f
b f
c) =
let (Poly f
g, Poly f
s) = Poly f -> Poly f -> (Poly f, Poly f)
forall c. (Field c, Eq c) => Poly c -> Poly c -> (Poly c, Poly c)
eea (Vector f -> Poly f
forall c. (Ring c, Eq c) => Vector c -> Poly c
toPoly [f
Item (Vector f)
a, f
Item (Vector f)
b, f
Item (Vector f)
c]) (forall f (e :: Symbol). IrreduciblePoly f e => Poly f
irreduciblePoly @f @e)
in case Poly f -> Vector f
forall c. Poly c -> Vector c
fromPoly (Poly f -> Vector f) -> Poly f -> Vector f
forall a b. (a -> b) -> a -> b
$ f -> Natural -> Poly f -> Poly f
forall c. Ring c => c -> Natural -> Poly c -> Poly c
scaleP (f
forall a. MultiplicativeMonoid a => a
one f -> f -> f
forall a. Field a => a -> a -> a
// Poly f -> f
forall c. Poly c -> c
lt Poly f
g) Natural
0 Poly f
s of
[] -> f -> f -> f -> Ext3 f e
forall f (e :: Symbol). f -> f -> f -> Ext3 f e
Ext3 f
forall a. AdditiveMonoid a => a
zero f
forall a. AdditiveMonoid a => a
zero f
forall a. AdditiveMonoid a => a
zero
[Item (Vector f)
x] -> f -> f -> f -> Ext3 f e
forall f (e :: Symbol). f -> f -> f -> Ext3 f e
Ext3 f
Item (Vector f)
x f
forall a. AdditiveMonoid a => a
zero f
forall a. AdditiveMonoid a => a
zero
[Item (Vector f)
x, Item (Vector f)
y] -> f -> f -> f -> Ext3 f e
forall f (e :: Symbol). f -> f -> f -> Ext3 f e
Ext3 f
Item (Vector f)
x f
Item (Vector f)
y f
forall a. AdditiveMonoid a => a
zero
Vector f
v -> f -> f -> f -> Ext3 f e
forall f (e :: Symbol). f -> f -> f -> Ext3 f e
Ext3 (Vector f
v Vector f -> Int -> f
forall a. Vector a -> Int -> a
V.! Int
0) (Vector f
v Vector f -> Int -> f
forall a. Vector a -> Int -> a
V.! Int
1) (Vector f
v Vector f -> Int -> f
forall a. Vector a -> Int -> a
V.! Int
2)
rootOfUnity :: Natural -> Maybe (Ext3 f e)
rootOfUnity Natural
n = (\f
r -> f -> f -> f -> Ext3 f e
forall f (e :: Symbol). f -> f -> f -> Ext3 f e
Ext3 f
r f
forall a. AdditiveMonoid a => a
zero f
forall a. AdditiveMonoid a => a
zero) (f -> Ext3 f e) -> Maybe f -> Maybe (Ext3 f e)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Natural -> Maybe f
forall a. Field a => Natural -> Maybe a
rootOfUnity Natural
n
instance (FromConstant f f', Field f') => FromConstant f (Ext3 f' ip) where
fromConstant :: f -> Ext3 f' ip
fromConstant f
e = f' -> f' -> f' -> Ext3 f' ip
forall f (e :: Symbol). f -> f -> f -> Ext3 f e
Ext3 (f -> f'
forall a b. FromConstant a b => a -> b
fromConstant f
e) f'
forall a. AdditiveMonoid a => a
zero f'
forall a. AdditiveMonoid a => a
zero
instance {-# OVERLAPPING #-} (Field f, Eq f, IrreduciblePoly f e) => FromConstant (Poly f) (Ext3 f e) where
fromConstant :: Poly f -> Ext3 f e
fromConstant Poly f
p = case Poly f -> Vector f
forall c. Poly c -> Vector c
fromPoly (Poly f -> Vector f)
-> ((Poly f, Poly f) -> Poly f) -> (Poly f, Poly f) -> Vector f
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Poly f, Poly f) -> Poly f
forall a b. (a, b) -> b
snd ((Poly f, Poly f) -> Vector f) -> (Poly f, Poly f) -> Vector f
forall a b. (a -> b) -> a -> b
$ Poly f -> Poly f -> (Poly f, Poly f)
forall c. (Field c, Eq c) => Poly c -> Poly c -> (Poly c, Poly c)
qr Poly f
p (forall f (e :: Symbol). IrreduciblePoly f e => Poly f
irreduciblePoly @f @e) of
[] -> Ext3 f e
forall a. AdditiveMonoid a => a
zero
[Item (Vector f)
x] -> f -> Ext3 f e
forall a b. FromConstant a b => a -> b
fromConstant f
Item (Vector f)
x
[Item (Vector f)
x, Item (Vector f)
y] -> f -> f -> f -> Ext3 f e
forall f (e :: Symbol). f -> f -> f -> Ext3 f e
Ext3 f
Item (Vector f)
x f
Item (Vector f)
y f
forall a. AdditiveMonoid a => a
zero
Vector f
v -> f -> f -> f -> Ext3 f e
forall f (e :: Symbol). f -> f -> f -> Ext3 f e
Ext3 (Vector f
v Vector f -> Int -> f
forall a. Vector a -> Int -> a
V.! Int
0) (Vector f
v Vector f -> Int -> f
forall a. Vector a -> Int -> a
V.! Int
1) (Vector f
v Vector f -> Int -> f
forall a. Vector a -> Int -> a
V.! Int
2)
instance (Field f, Eq f, IrreduciblePoly f e) => Semiring (Ext3 f e)
instance (Field f, Eq f, IrreduciblePoly f e) => Ring (Ext3 f e)
instance Binary f => Binary (Ext3 f e) where
put :: Ext3 f e -> Put
put (Ext3 f
a f
b f
c) = f -> Put
forall t. Binary t => t -> Put
put f
a Put -> Put -> Put
forall a. Semigroup a => a -> a -> a
<> f -> Put
forall t. Binary t => t -> Put
put f
b Put -> Put -> Put
forall a. Semigroup a => a -> a -> a
<> f -> Put
forall t. Binary t => t -> Put
put f
c
get :: Get (Ext3 f e)
get = f -> f -> f -> Ext3 f e
forall f (e :: Symbol). f -> f -> f -> Ext3 f e
Ext3 (f -> f -> f -> Ext3 f e) -> Get f -> Get (f -> f -> Ext3 f e)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Get f
forall t. Binary t => Get t
get Get (f -> f -> Ext3 f e) -> Get f -> Get (f -> Ext3 f e)
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Get f
forall t. Binary t => Get t
get Get (f -> Ext3 f e) -> Get f -> Get (Ext3 f e)
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Get f
forall t. Binary t => Get t
get
instance (Field f, Eq f, IrreduciblePoly f e, Arbitrary f) => Arbitrary (Ext3 f e) where
arbitrary :: Gen (Ext3 f e)
arbitrary = f -> f -> f -> Ext3 f e
forall f (e :: Symbol). f -> f -> f -> Ext3 f e
Ext3 (f -> f -> f -> Ext3 f e) -> Gen f -> Gen (f -> f -> Ext3 f e)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen f
forall a. Arbitrary a => Gen a
arbitrary Gen (f -> f -> Ext3 f e) -> Gen f -> Gen (f -> Ext3 f e)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Gen f
forall a. Arbitrary a => Gen a
arbitrary Gen (f -> Ext3 f e) -> Gen f -> Gen (Ext3 f e)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Gen f
forall a. Arbitrary a => Gen a
arbitrary