-- Copyright (c) David Amos, 2008. All rights reserved.{-# OPTIONS_GHC -fglasgow-exts #-}moduleMath.Algebra.Commutative.MonomialwhereimportqualifiedData.MapasMimportData.ListasLimportControl.Arrow-- MONOMIALnewtypeMonomialord=Monomial(M.MapStringInt)deriving(Eq)instanceShow(Monomialord)whereshow(Monomiala)|M.nulla="1"|otherwise=concatMapshowVar$M.toListawhereshowVar(v,1)=vshowVar(v,i)=v++"^"++showiinstanceNum(Monomialord)whereMonomiala*Monomialb=Monomial$M.filter(/=0)$M.unionWith(+)ab-- The filter (/=0) here means we can handle Laurent monomials, and isn't significantly slower-- Monomial a * Monomial b = Monomial $ M.unionWith (+) a bfromInteger1=MonomialM.emptyinstanceFractional(Monomialord)whererecip(Monomialm)=Monomial$M.mapnegatem-- can only do the above if (*) is doing filter (/=0)-- Monomial a / Monomial b = Monomial $ M.filter (/=0) $ M.unionWith (+) a (M.map negate b)dataLexdataGlexdataGrevlexdataElim-- a term order for eliminationdiffsab=M.elemsmwhereMonomialm=a/b-- note that we're guaranteed that all elts of diffs a b are non-zeroinstanceOrd(MonomialLex)wherecompareab=casediffsabof[]->EQas->ifheadas>0thenGTelseLTinstanceOrd(MonomialGlex)wherecompareab=letds=diffsabincasecompare(sumds)0ofGT->GTLT->LTEQ->ifnulldsthenEQelseifheadds>0thenGTelseLTinstanceOrd(MonomialGrevlex)wherecompareab=letds=diffsabincasecompare(sumds)0ofGT->GTLT->LTEQ->ifnulldsthenEQelseiflastds<0thenGTelseLT-- a monomial order for terms in x1,x2,..,y1,y2,..,z1,z2,.. etc-- in which it is grevlex separately on first the xs, then if they're equal, the ys, then if they're equal, the zs, etcinstanceOrd(MonomialElim)wherecompareab=letMonomialm=a/bincaseM.assocsmof[]->EQ(l:s,i):vs->grevlex$i:mapsnd(takeWhile(\(l':_,_)->l'==l)vs)wheregrevlexds=casecompare(sumds)0ofGT->GTLT->LTEQ->iflastds<0thenGTelseLTconvertM::Monomiala->MonomialbconvertM(Monomialx)=MonomialxdegM(Monomialm)=sum$M.elemsmdividesM(Monomiala)(Monomialb)=M.isSubmapOfBy(<=)abproperlyDividesMab=dividesMab&&a/=blcmM(Monomiala)(Monomialb)=Monomial$M.unionWithmaxabgcdM(Monomiala)(Monomialb)=Monomial$M.intersectionWithminabcoprimeM(Monomiala)(Monomialb)=M.null$M.intersectionab-- the support of a monomial is the variables it containssupportM::Monomialord->[Monomialord]-- type signature needed to say that output has same term order as inputsupportM(Monomialm)=[Monomial(M.singletonv1)|v<-M.keysm]