{-# LANGUAGE ViewPatterns #-} module SequenceMonomial (Monomial(), MonomialOrder, length, viewl , totalDegree, viewr, lex, graded, revlex, grlex, grevlex, fromList) where import Control.DeepSeq import Data.Foldable import Data.Monoid import Data.Ord import Data.Sequence (Seq) import qualified Data.Sequence as S import Prelude hiding (length, lex, sum) length :: Monomial -> Int length = S.length . getSeq fromList :: [Int] -> Monomial fromList xs = Monomial (S.fromList xs) (sum xs) viewl :: Monomial -> ViewL viewl (Monomial sq deg) = case S.viewl sq of S.EmptyL -> EmptyL x S.:< xs -> x :< Monomial xs (deg - x) viewr :: Monomial -> ViewR viewr (Monomial sq deg) = case S.viewr sq of S.EmptyR -> EmptyR xs S.:> x -> Monomial xs (deg - x) :> x data ViewL = EmptyL | Int :< Monomial deriving (Read, Show, Eq, Ord) data ViewR = EmptyR | Monomial :> Int deriving (Read, Show, Eq, Ord) data Monomial = Monomial { getSeq :: Seq Int , totalDegree :: !Int } deriving (Read, Show, Eq, Ord) instance NFData Monomial where rnf (Monomial sq deg) = rnf sq `seq` rnf deg `seq` () type MonomialOrder = Monomial -> Monomial -> Ordering -- | Lexicographical order. This *is* a monomial order. lex :: MonomialOrder lex (viewl -> EmptyL) (viewl -> EmptyL) = EQ lex (viewl -> x :< xs) (viewl -> y :< ys) = x `compare` y <> xs `lex` ys {-# INLINE lex #-} -- | Reversed lexicographical order. This is *not* a monomial order. revlex :: Monomial -> Monomial -> Ordering revlex (viewr -> xs :> x) (viewr -> ys :> y) = y `compare` x <> xs `revlex` ys revlex (viewr -> EmptyR) (viewr -> EmptyR) = EQ {-# INLINE revlex #-} -- | Convert ordering into graded one. graded :: (Monomial -> Monomial -> Ordering) -> (Monomial -> Monomial -> Ordering) graded cmp xs ys = comparing totalDegree xs ys <> cmp xs ys {-# INLINE graded #-} -- | Graded lexicographical order. This *is* a monomial order. grlex :: MonomialOrder grlex = graded lex {-# INLINE grlex #-} -- | Graded reversed lexicographical order. This *is* a monomial order. grevlex :: MonomialOrder grevlex = graded revlex {-# INLINE grevlex #-}