computational-algebra-0.4.0.0: Algebra/Ring/Polynomial/Quotient.hs
{-# LANGUAGE ConstraintKinds, DataKinds, FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances, GADTs, GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MagicHash, MultiParamTypeClasses, PolyKinds, RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables, StandaloneDeriving, TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Algebra.Ring.Polynomial.Quotient
( Quotient(), QIdeal(), reifyQuotient, modIdeal
, modIdeal', quotRepr, withQuotient, vectorRep
, genQuotVars, genQuotVars', gBasis', matRep0
, standardMonomials, standardMonomials', matRepr'
, reduce, multWithTable, multUnamb, isZeroDimensional
)
where
import Algebra.Algorithms.Groebner (calcGroebnerBasis)
import Algebra.Field.Finite (F)
import Algebra.Internal
import Algebra.Prelude.Core
import Algebra.Ring.Polynomial.Univariate (Unipol)
import Control.DeepSeq
import Control.Lens (folded, ifoldMap, minimumOf)
import qualified Data.Coerce as C
import qualified Data.HashMap.Lazy as HM
import qualified Data.Map as Map
import qualified Data.Matrix as M
import Data.Monoid (Sum (..))
import Data.Reflection
import Data.Unamb (unamb)
import qualified Data.Vector as V
import qualified Numeric.Algebra as NA
import qualified Prelude as P
-- | The polynomial modulo the ideal indexed at the last type-parameter.
newtype Quotient poly ideal = Quotient { quotRepr_ :: poly }
deriving (Eq)
-- | Representative polynomial of given quotient polynomial.
quotRepr :: Quotient poly ideal -> poly
quotRepr = quotRepr_
data QIdeal poly = ZeroDimIdeal { _gBasis :: ![poly]
, _vBasis :: ![OrderedMonomial (MOrder poly) (Arity poly)]
, multTable :: Table poly
}
| QIdeal { _gBasis :: [poly]
}
instance NFData poly => NFData (Quotient poly ideal) where
rnf (Quotient op) = rnf op
type Table poly = HM.HashMap
(OrderedMonomial (MOrder poly) (Arity poly),
OrderedMonomial (MOrder poly) (Arity poly))
poly
vectorRep :: forall poly ideal.
(IsOrderedPolynomial poly, Reifies ideal (QIdeal poly))
=> Quotient poly ideal -> V.Vector (Coefficient poly)
vectorRep f =
let ZeroDimIdeal _ base _ = reflect f
mf = quotRepr f
in V.fromList $ map (flip coeff mf) base
{-# SPECIALISE INLINE
vectorRep :: (IsMonomialOrder n ord, CoeffRing r, KnownNat n,
Reifies ideal (QIdeal (OrderedPolynomial r ord n)))
=> Quotient (OrderedPolynomial r ord n) ideal -> V.Vector r
#-}
{-# SPECIALISE INLINE
vectorRep :: (CoeffRing r, Reifies ideal (QIdeal (Unipol r)))
=> Quotient (Unipol r) ideal -> V.Vector r
#-}
{-# SPECIALISE INLINE
vectorRep :: (IsMonomialOrder n ord, KnownNat n,
Reifies ideal (QIdeal (OrderedPolynomial Rational ord n)))
=> Quotient (OrderedPolynomial Rational ord n) ideal -> V.Vector Rational
#-}
{-# SPECIALISE INLINE
vectorRep :: (Reifies ideal (QIdeal (Unipol Rational)))
=> Quotient (Unipol Rational) ideal -> V.Vector Rational
#-}
{-# SPECIALISE INLINE
vectorRep :: (KnownNat p, IsMonomialOrder n ord, KnownNat n,
Reifies ideal (QIdeal (OrderedPolynomial (F p) ord n)))
=> Quotient (OrderedPolynomial (F p) ord n) ideal -> V.Vector (F p)
#-}
{-# SPECIALISE INLINE
vectorRep :: (Reifies ideal (QIdeal (Unipol (F p))), KnownNat p)
=> Quotient (Unipol (F p)) ideal -> V.Vector (F p)
#-}
{-# INLINE vectorRep #-}
matRepr' :: forall poly ideal.
(Field (Coefficient poly),
Reifies ideal (QIdeal poly), IsOrderedPolynomial poly)
=> Quotient poly ideal -> M.Matrix (Coefficient poly)
matRepr' f =
let ZeroDimIdeal _bs _ _ = reflect f
in C.coerce $ getSum $
ifoldMap
(\t c ->
Sum $ fmap (WrapAlgebra . (c *)) $ matRep0 (Proxy :: Proxy poly) (Proxy :: Proxy ideal) t)
(terms (quotRepr_ f))
{-# SPECIALISE INLINE
matRepr' :: (IsMonomialOrder n ord, CoeffRing r, KnownNat n, Field r,
Reifies ideal (QIdeal (OrderedPolynomial r ord n)))
=> Quotient (OrderedPolynomial r ord n) ideal -> M.Matrix r
#-}
{-# SPECIALISE INLINE
matRepr' :: (Field r, CoeffRing r, Reifies ideal (QIdeal (Unipol r)))
=> Quotient (Unipol r) ideal -> M.Matrix r
#-}
{-# SPECIALISE INLINE
matRepr' :: (IsMonomialOrder n ord, KnownNat n,
Reifies ideal (QIdeal (OrderedPolynomial Rational ord n)))
=> Quotient (OrderedPolynomial Rational ord n) ideal -> M.Matrix Rational
#-}
{-# SPECIALISE INLINE
matRepr' :: (Reifies ideal (QIdeal (Unipol Rational)))
=> Quotient (Unipol Rational) ideal -> M.Matrix Rational
#-}
{-# SPECIALISE INLINE
matRepr' :: (IsMonomialOrder n ord, KnownNat n, KnownNat p,
Reifies ideal (QIdeal (OrderedPolynomial (F p) ord n)))
=> Quotient (OrderedPolynomial (F p) ord n) ideal -> M.Matrix (F p)
#-}
{-# SPECIALISE INLINE
matRepr' :: (Reifies ideal (QIdeal (Unipol (F p))), KnownNat p)
=> Quotient (Unipol (F p)) ideal -> M.Matrix (F p)
#-}
{-# INLINE matRepr' #-}
matRep0 :: forall poly ideal.
(IsOrderedPolynomial poly, Field (Coefficient poly), Reifies ideal (QIdeal poly))
=> Proxy poly -> Proxy ideal -> OrderedMonomial (MOrder poly) (Arity poly) -> M.Matrix (Coefficient poly)
matRep0 _ pxy m =
let ZeroDimIdeal _ bs table = reflect pxy
in foldr (M.<|>) (M.fromList 0 0 [])
[ M.colVector $ vectorRep $ modIdeal' pxy (HM.lookupDefault zero (m, b) table)
| b <- bs ]
{-# SPECIALISE INLINE
matRep0 :: (IsMonomialOrder n ord, Field r, CoeffRing r, KnownNat n,
Reifies ideal (QIdeal (OrderedPolynomial r ord n)))
=> Proxy (OrderedPolynomial r ord n) -> Proxy ideal -> OrderedMonomial ord n -> M.Matrix r
#-}
{-# SPECIALISE INLINE
matRep0 :: (CoeffRing r, Field r, Reifies ideal (QIdeal (Unipol r)))
=> Proxy (Unipol r) -> Proxy ideal -> OrderedMonomial Grevlex 1 -> M.Matrix r
#-}
{-# SPECIALISE INLINE
matRep0 :: (IsMonomialOrder n ord,KnownNat n,
Reifies ideal (QIdeal (OrderedPolynomial Rational ord n)))
=> Proxy (OrderedPolynomial Rational ord n) -> Proxy ideal -> OrderedMonomial ord n -> M.Matrix Rational
#-}
{-# SPECIALISE INLINE
matRep0 :: (Reifies ideal (QIdeal (Unipol Rational)))
=> Proxy (Unipol Rational) -> Proxy ideal -> OrderedMonomial Grevlex 1 -> M.Matrix Rational
#-}
{-# SPECIALISE INLINE
matRep0 :: (IsMonomialOrder n ord,KnownNat n, KnownNat p,
Reifies ideal (QIdeal (OrderedPolynomial (F p) ord n)))
=> Proxy (OrderedPolynomial (F p) ord n) -> Proxy ideal -> OrderedMonomial ord n -> M.Matrix (F p)
#-}
{-# SPECIALISE INLINE
matRep0 :: (Reifies ideal (QIdeal (Unipol (F p))), KnownNat p)
=> Proxy (Unipol (F p)) -> Proxy ideal -> OrderedMonomial Grevlex 1 -> M.Matrix (F p)
#-}
{-# INLINE matRep0 #-}
multUnamb :: (IsOrderedPolynomial poly, Field (Coefficient poly),
Reifies ideal (QIdeal poly))
=> Quotient poly ideal -> Quotient poly ideal
-> Quotient poly ideal
multUnamb a b = unamb (a * b) (multWithTable a b)
{-# SPECIALISE INLINE
multUnamb :: (CoeffRing r, IsMonomialOrder n ord, KnownNat n,
Field r, Reifies ideal (QIdeal (OrderedPolynomial r ord n)))
=> Quotient (OrderedPolynomial r ord n) ideal
-> Quotient (OrderedPolynomial r ord n) ideal
-> Quotient (OrderedPolynomial r ord n) ideal
#-}
{-# SPECIALISE INLINE
multUnamb :: (CoeffRing r, Field r, Reifies ideal (QIdeal (Unipol r)))
=> Quotient (Unipol r) ideal
-> Quotient (Unipol r) ideal
-> Quotient (Unipol r) ideal
#-}
{-# SPECIALISE INLINE
multUnamb :: (IsMonomialOrder n ord, KnownNat n,
Reifies ideal (QIdeal (OrderedPolynomial Rational ord n)))
=> Quotient (OrderedPolynomial Rational ord n) ideal
-> Quotient (OrderedPolynomial Rational ord n) ideal
-> Quotient (OrderedPolynomial Rational ord n) ideal
#-}
{-# SPECIALISE INLINE
multUnamb :: (Reifies ideal (QIdeal (Unipol Rational)))
=> Quotient (Unipol Rational) ideal
-> Quotient (Unipol Rational) ideal
-> Quotient (Unipol Rational) ideal
#-}
{-# SPECIALISE INLINE
multUnamb :: (IsMonomialOrder n ord, KnownNat n, KnownNat p,
Reifies ideal (QIdeal (OrderedPolynomial (F p) ord n)))
=> Quotient (OrderedPolynomial (F p) ord n) ideal
-> Quotient (OrderedPolynomial (F p) ord n) ideal
-> Quotient (OrderedPolynomial (F p) ord n) ideal
#-}
{-# SPECIALISE INLINE
multUnamb :: (Reifies ideal (QIdeal (Unipol (F p))), KnownNat p)
=> Quotient (Unipol (F p)) ideal
-> Quotient (Unipol (F p)) ideal
-> Quotient (Unipol (F p)) ideal
#-}
{-# INLINE multUnamb #-}
multWithTable :: (IsOrderedPolynomial poly, Reifies ideal (QIdeal poly))
=> Quotient poly ideal -> Quotient poly ideal
-> Quotient poly ideal
multWithTable f g =
let qid = reflect f
table = multTable qid
in sum [ Quotient $ c .*. d .*. (HM.lookupDefault zero (l, r) table)
| (l,c) <- Map.toList $ terms $ quotRepr_ f
, (r,d) <- Map.toList $ terms $ quotRepr_ g
]
{-# SPECIALISE INLINE
multWithTable :: (CoeffRing r, IsMonomialOrder n ord, KnownNat n,
Reifies ideal (QIdeal (OrderedPolynomial r ord n)))
=> Quotient (OrderedPolynomial r ord n) ideal
-> Quotient (OrderedPolynomial r ord n) ideal
-> Quotient (OrderedPolynomial r ord n) ideal
#-}
{-# SPECIALISE INLINE
multWithTable :: (CoeffRing r, Reifies ideal (QIdeal (Unipol r)))
=> Quotient (Unipol r) ideal
-> Quotient (Unipol r) ideal
-> Quotient (Unipol r) ideal
#-}
{-# INLINE multWithTable #-}
instance Show poly => Show (Quotient poly ideal) where
show (Quotient f) = show f
buildMultTable :: (IsOrderedPolynomial poly, Field (Coefficient poly))
=> [poly] -> [OrderedMonomial (MOrder poly) (Arity poly)] -> Table poly
buildMultTable bs ms =
HM.fromList [ ((p, q), (toPolynomial (one, p) * toPolynomial (one, q)) `modPolynomial` bs)
| p <- ms, q <- ms]
{-# SPECIALISE INLINE
buildMultTable :: (IsMonomialOrder n ord, Field r, CoeffRing r, KnownNat n)
=> [OrderedPolynomial r ord n]
-> [OrderedMonomial ord n]
-> Table (OrderedPolynomial r ord n)
#-}
{-# SPECIALISE INLINE
buildMultTable :: (Field r, CoeffRing r)
=> [Unipol r]
-> [OrderedMonomial Grevlex 1]
-> Table (Unipol r)
#-}
stdMonoms :: forall poly.
(IsOrderedPolynomial poly, Field (Coefficient poly))
=> [poly] -> Maybe [OrderedMonomial (MOrder poly) (Arity poly)]
stdMonoms basis = do
let lms = map leadingTerm basis
dim = sing :: SNat (Arity poly)
tests = zip (diag 1 0 dim) (diag 0 1 dim)
mexp (val, test) = [ P.foldr (+) 0 $ zipWithSame (*) val $ getMonomial lm0
| (c, lm0) <- lms, c /= zero
, let a = P.foldr (+) 0 $ zipWithSame (*) (getMonomial lm0) test
, a == 0
]
degs <- mapM (minimumOf folded . mexp) tests
return $ sort [ monom
| ds0 <- sequence $ map (enumFromTo 0) degs
, let monom = OrderedMonomial $ fromList dim ds0
, let ds = toPolynomial (one, monom)
, ds `modPolynomial` basis == ds
]
{-# SPECIALISE
stdMonoms :: (IsMonomialOrder n ord, Field r, CoeffRing r, KnownNat n)
=> [OrderedPolynomial r ord n]
-> Maybe [OrderedMonomial ord n]
#-}
{-# SPECIALISE
stdMonoms :: (Field r, CoeffRing r)
=> [Unipol r]
-> Maybe [OrderedMonomial Grevlex 1]
#-}
diag :: a -> a -> SNat n -> [Sized' n a]
diag d z n = [ generate n (\j -> if i == j then d else z)
| i <- enumOrdinal n
]
{-# INLINE diag #-}
-- | Find the standard monomials of the quotient ring for the zero-dimensional ideal,
-- which are form the basis of it as k-vector space.
standardMonomials' :: (IsOrderedPolynomial poly, Field (Coefficient poly),
Reifies ideal (QIdeal poly))
=> Proxy ideal -> Maybe [Quotient poly ideal]
standardMonomials' pxy =
case reflect pxy of
ZeroDimIdeal _ vB _ -> Just $ map (modIdeal . toPolynomial . (,) one) vB
_ -> Nothing
{-# SPECIALISE INLINE
standardMonomials' :: (IsMonomialOrder n ord, CoeffRing r, KnownNat n, Field r,
Reifies ideal (QIdeal (OrderedPolynomial r ord n)))
=> Proxy ideal -> Maybe [Quotient (OrderedPolynomial r ord n) ideal]
#-}
{-# SPECIALISE INLINE
standardMonomials' :: (CoeffRing r, Field r, Reifies ideal (QIdeal (Unipol r)))
=> Proxy ideal -> Maybe [Quotient (Unipol r) ideal]
#-}
{-# INLINE standardMonomials' #-}
standardMonomials :: forall poly ideal.
(IsOrderedPolynomial poly, Field (Coefficient poly),
Reifies ideal (QIdeal poly))
=> Maybe [Quotient poly ideal]
standardMonomials = standardMonomials' (Proxy :: Proxy ideal)
{-# SPECIALISE INLINE
standardMonomials :: (IsMonomialOrder n ord, CoeffRing r, KnownNat n, Field r,
Reifies ideal (QIdeal (OrderedPolynomial r ord n)))
=> Maybe [Quotient (OrderedPolynomial r ord n) ideal]
#-}
{-# SPECIALISE INLINE
standardMonomials :: (CoeffRing r, Field r, Reifies ideal (QIdeal (Unipol r)))
=> Maybe [Quotient (Unipol r) ideal]
#-}
{-# INLINE standardMonomials #-}
genQuotVars' :: forall poly ideal.
(IsOrderedPolynomial poly, Field (Coefficient poly),
Reifies ideal (QIdeal poly))
=> Proxy ideal -> [Quotient poly ideal]
genQuotVars' pxy = map (modIdeal' pxy) vars
{-# SPECIALISE INLINE
genQuotVars' :: (IsMonomialOrder n ord, CoeffRing r, KnownNat n, Field r,
Reifies ideal (QIdeal (OrderedPolynomial r ord n)))
=> Proxy ideal -> [Quotient (OrderedPolynomial r ord n) ideal]
#-}
{-# SPECIALISE INLINE
genQuotVars' :: (CoeffRing r, Field r, Reifies ideal (QIdeal (Unipol r)))
=> Proxy ideal -> [Quotient (Unipol r) ideal]
#-}
{-# INLINE genQuotVars' #-}
genQuotVars :: forall poly ideal. (IsOrderedPolynomial poly, Field (Coefficient poly),
Reifies ideal (QIdeal poly))
=> [Quotient poly ideal]
genQuotVars = genQuotVars' (Proxy :: Proxy ideal)
{-# SPECIALISE INLINE
genQuotVars :: (IsMonomialOrder n ord, CoeffRing r, KnownNat n, Field r,
Reifies ideal (QIdeal (OrderedPolynomial r ord n)))
=> [Quotient (OrderedPolynomial r ord n) ideal]
#-}
{-# SPECIALISE INLINE
genQuotVars :: (CoeffRing r, Field r, Reifies ideal (QIdeal (Unipol r)))
=> [Quotient (Unipol r) ideal]
#-}
{-# INLINE genQuotVars #-}
-- | Polynomial modulo ideal.
modIdeal :: forall poly ideal.
(IsOrderedPolynomial poly, Field (Coefficient poly),
Reifies ideal (QIdeal poly))
=> poly -> Quotient poly ideal
modIdeal = modIdeal' (Proxy :: Proxy ideal)
gBasis' :: (Reifies ideal (QIdeal poly))
=> Proxy ideal -> [poly]
gBasis' pxy = _gBasis (reflect pxy)
{-# SPECIALISE INLINE
gBasis' :: (Reifies ideal (QIdeal (OrderedPolynomial r ord n)))
=> Proxy ideal -> [OrderedPolynomial r ord n]
#-}
{-# SPECIALISE INLINE
gBasis' :: (Reifies ideal (QIdeal (Unipol r)))
=> Proxy ideal -> [Unipol r]
#-}
{-# INLINE gBasis' #-}
-- | Polynomial modulo ideal given by @Proxy@.
modIdeal' :: (IsOrderedPolynomial poly, Field (Coefficient poly),
Reifies ideal (QIdeal poly))
=> Proxy ideal -> poly -> Quotient poly ideal
modIdeal' pxy f = Quotient $ f `modPolynomial` _gBasis (reflect pxy)
{-# SPECIALISE INLINE
modIdeal' :: (IsMonomialOrder n ord, CoeffRing r, KnownNat n, Field r,
Reifies ideal (QIdeal (OrderedPolynomial r ord n)))
=> Proxy ideal -> OrderedPolynomial r ord n
-> Quotient (OrderedPolynomial r ord n) ideal
#-}
{-# SPECIALISE INLINE
modIdeal' :: (CoeffRing r, Field r,
Reifies ideal (QIdeal (Unipol r)))
=> Proxy ideal -> Unipol r
-> Quotient (Unipol r) ideal
#-}
{-# INLINE modIdeal' #-}
buildQIdeal :: (IsOrderedPolynomial poly, Field (Coefficient poly))
=> Ideal poly -> QIdeal poly
buildQIdeal ideal =
let bs = sortBy (comparing leadingMonomial) $! calcGroebnerBasis ideal
in case stdMonoms bs of
Nothing -> QIdeal bs
Just ms -> ZeroDimIdeal bs ms (buildMultTable bs ms)
{-# SPECIALISE INLINE
buildQIdeal :: (IsMonomialOrder n ord, CoeffRing r, KnownNat n, Field r)
=> Ideal (OrderedPolynomial r ord n)
-> QIdeal (OrderedPolynomial r ord n)
#-}
{-# SPECIALISE INLINE
buildQIdeal :: (CoeffRing r, Field r)
=> Ideal (Unipol r)
-> QIdeal (Unipol r)
#-}
{-# INLINE buildQIdeal #-}
-- | Reifies the ideal at the type-level. The ideal can be recovered with 'reflect'.
reifyQuotient :: (IsOrderedPolynomial poly, Field (Coefficient poly))
=> Ideal poly
-> (forall (ideal :: *). Reifies ideal (QIdeal poly) => Proxy ideal -> a)
-> a
reifyQuotient ideal = reify (buildQIdeal ideal)
{-# INLINE reifyQuotient #-}
-- | Computes polynomial modulo ideal.
withQuotient :: (IsOrderedPolynomial poly, Field (Coefficient poly))
=> Ideal poly
-> (forall (ideal :: *). Reifies ideal (QIdeal poly) => Quotient poly ideal)
-> poly
withQuotient ideal v = reifyQuotient ideal (quotRepr_ . asProxyOf v)
{-# INLINE withQuotient #-}
asProxyOf :: f s -> Proxy s -> f s
asProxyOf a _ = a
{-# INLINE asProxyOf #-}
deriving instance Additive poly => Additive (Quotient poly ideal)
deriving instance Monoidal poly => Monoidal (Quotient poly ideal)
deriving instance Group poly => Group (Quotient poly ideal)
deriving instance Abelian poly => Abelian (Quotient poly ideal)
instance Monoidal poly
=> LeftModule Natural (Quotient poly ideal) where
r .* f = Quotient $ r .* quotRepr_ f
instance Monoidal poly
=> RightModule Natural (Quotient poly ideal) where
f *. r = Quotient $ r .* quotRepr_ f
instance Group poly
=> LeftModule Integer (Quotient poly ideal) where
r .* f = Quotient $ r .* quotRepr_ f
instance Group poly
=> RightModule Integer (Quotient poly ideal) where
f *. r = Quotient $ r .* quotRepr_ f
instance (Field (Coefficient poly), IsOrderedPolynomial poly, Reifies ideal (QIdeal poly))
=> Multiplicative (Quotient poly ideal) where
f * g = modIdeal $ quotRepr_ f * quotRepr_ g
instance (Field (Coefficient poly), IsOrderedPolynomial poly, Reifies ideal (QIdeal poly))
=> Semiring (Quotient poly ideal)
instance (Field (Coefficient poly), IsOrderedPolynomial poly, Reifies ideal (QIdeal poly))
=> Unital (Quotient poly ideal) where
one = modIdeal one
instance (Field (Coefficient poly), IsOrderedPolynomial poly,
Reifies ideal (QIdeal poly))
=> Rig (Quotient poly ideal)
instance (Field (Coefficient poly),
IsOrderedPolynomial poly,
Reifies ideal (QIdeal poly))
=> Ring (Quotient poly ideal)
instance (r ~ (Coefficient poly), Field (Coefficient poly),
IsOrderedPolynomial poly)
=> LeftModule (Scalar r) (Quotient poly ideal) where
r .* f = Quotient $ r .* quotRepr_ f
instance (r ~ (Coefficient poly), IsOrderedPolynomial poly)
=> RightModule (Scalar r) (Quotient poly ideal) where
f *. r = Quotient $ quotRepr_ f *. r
instance (Field (Coefficient poly), UnitNormalForm poly, IsOrderedPolynomial poly,
Reifies ideal (QIdeal poly))
=> P.Num (Quotient poly ideal) where
(+) = (NA.+)
(*) = (NA.*)
fromInteger = Quotient . unwrapAlgebra . P.fromInteger
signum = Quotient . unwrapAlgebra . P.signum . WrapAlgebra . quotRepr_
abs = Quotient . unwrapAlgebra . P.abs . WrapAlgebra . quotRepr_
negate = Quotient . unwrapAlgebra . P.negate . WrapAlgebra . quotRepr_
-- | Reduce polynomial modulo ideal.
reduce :: (IsOrderedPolynomial poly, Field (Coefficient poly))
=> poly -> Ideal poly -> poly
reduce f i = withQuotient i $ modIdeal f
{-# SPECIALISE INLINE
reduce :: (IsMonomialOrder n ord, CoeffRing r, KnownNat n, Field r)
=> OrderedPolynomial r ord n
-> Ideal (OrderedPolynomial r ord n)
-> OrderedPolynomial r ord n
#-}
{-# SPECIALISE INLINE
reduce :: (CoeffRing r, Field r)
=> Unipol r
-> Ideal (Unipol r)
-> Unipol r
#-}
{-# INLINE reduce #-}
isZeroDimensional :: (IsOrderedPolynomial poly, Field (Coefficient poly))
=> [poly] -> Bool
isZeroDimensional ii = isJust $ stdMonoms $ calcGroebnerBasis $ toIdeal ii
{-# INLINE isZeroDimensional #-}