module Algebra.Field.Galois.Internal
(ConwayPolynomial(..),
Conway,
buildInstance,
parseLine) where
import Algebra.Field.Finite
import Algebra.Prelude.Core hiding (lex, lift)
import Algebra.Ring.Polynomial.Univariate (Unipol)
import Data.Char (isDigit)
import Data.Char (digitToInt)
import qualified Data.Map as M
import Data.Reflection
import qualified GHC.TypeLits as TL
import Language.Haskell.TH
import Language.Haskell.TH.Syntax (lift)
import Numeric (readInt)
import Prelude (lex)
class ConwayPolynomial (p :: TL.Nat) (n :: TL.Nat) where
conwayPolynomial :: proxy p -> proxy n -> Unipol (F p)
data Conway p n
instance (ConwayPolynomial p n) => Reifies (Conway p n) (Unipol (F p)) where
reflect _ = conwayPolynomial (Proxy :: Proxy p) (Proxy :: Proxy n)
parseLine :: String -> [(Integer, Integer, [Integer])]
parseLine ('[':xs) =
[(p,n,poly) | (f, ',':rest) <- lex xs
, (p, "") <- readInt 10 isDigit digitToInt f
, (n, ',':ys) <- readInt 10 isDigit digitToInt rest
, (poly, _) <- readList ys
]
parseLine _ = []
plusOp :: ExpQ -> ExpQ -> ExpQ
plusOp e f = infixApp e [| (+) |] f
toPoly :: [Integer] -> ExpQ
toPoly as =
foldl1 plusOp $
zipWith (\i c -> [| injectCoeff (modNat $(litE $ integerL c)) * var 0 ^ $(lift i) |])
[0 :: Integer ..] as
buildInstance :: (Integer, Integer, [Integer]) -> DecsQ
buildInstance (p,n,cs) =
let tp = litT $ numTyLit p
tn = litT $ numTyLit n
in [d| instance ConwayPolynomial $tp $tn where
conwayPolynomial _ _ = $(toPoly cs)
|]