-- | Multivariate monomials where the set of variables is given by 
-- the inhabitants of a type

{-# LANGUAGE CPP, BangPatterns, TypeFamilies, KindSignatures, StandaloneDeriving, FlexibleContexts #-}
module Math.Algebra.Polynomial.Monomial.Generic where

--------------------------------------------------------------------------------

import Data.Maybe
import Data.List
import Data.Foldable as F

import Data.Proxy
import Data.Typeable

#if MIN_VERSION_base(4,11,0)        
import Data.Semigroup
import Data.Monoid
import Data.List.NonEmpty ( NonEmpty )
#else
import Data.Monoid
#endif

import Data.Map.Strict (Map) ; import qualified Data.Map.Strict as Map 

import Math.Algebra.Polynomial.Class
import Math.Algebra.Polynomial.FreeModule
import Math.Algebra.Polynomial.Pretty
import Math.Algebra.Polynomial.Misc

--------------------------------------------------------------------------------
-- * Monomials

-- | A monomial over the set of variables represented by the inhabitants 
-- of the type @v@.
-- The invariant we keep is that the exponents present in the @Map@ are always positive.
newtype Monom v 
  = Monom (Map v Int)
  deriving (Monom v -> Monom v -> Bool
(Monom v -> Monom v -> Bool)
-> (Monom v -> Monom v -> Bool) -> Eq (Monom v)
forall v. Eq v => Monom v -> Monom v -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Monom v -> Monom v -> Bool
$c/= :: forall v. Eq v => Monom v -> Monom v -> Bool
== :: Monom v -> Monom v -> Bool
$c== :: forall v. Eq v => Monom v -> Monom v -> Bool
Eq,Eq (Monom v)
Eq (Monom v)
-> (Monom v -> Monom v -> Ordering)
-> (Monom v -> Monom v -> Bool)
-> (Monom v -> Monom v -> Bool)
-> (Monom v -> Monom v -> Bool)
-> (Monom v -> Monom v -> Bool)
-> (Monom v -> Monom v -> Monom v)
-> (Monom v -> Monom v -> Monom v)
-> Ord (Monom v)
Monom v -> Monom v -> Bool
Monom v -> Monom v -> Ordering
Monom v -> Monom v -> Monom v
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall v. Ord v => Eq (Monom v)
forall v. Ord v => Monom v -> Monom v -> Bool
forall v. Ord v => Monom v -> Monom v -> Ordering
forall v. Ord v => Monom v -> Monom v -> Monom v
min :: Monom v -> Monom v -> Monom v
$cmin :: forall v. Ord v => Monom v -> Monom v -> Monom v
max :: Monom v -> Monom v -> Monom v
$cmax :: forall v. Ord v => Monom v -> Monom v -> Monom v
>= :: Monom v -> Monom v -> Bool
$c>= :: forall v. Ord v => Monom v -> Monom v -> Bool
> :: Monom v -> Monom v -> Bool
$c> :: forall v. Ord v => Monom v -> Monom v -> Bool
<= :: Monom v -> Monom v -> Bool
$c<= :: forall v. Ord v => Monom v -> Monom v -> Bool
< :: Monom v -> Monom v -> Bool
$c< :: forall v. Ord v => Monom v -> Monom v -> Bool
compare :: Monom v -> Monom v -> Ordering
$ccompare :: forall v. Ord v => Monom v -> Monom v -> Ordering
$cp1Ord :: forall v. Ord v => Eq (Monom v)
Ord,Int -> Monom v -> ShowS
[Monom v] -> ShowS
Monom v -> String
(Int -> Monom v -> ShowS)
-> (Monom v -> String) -> ([Monom v] -> ShowS) -> Show (Monom v)
forall v. Show v => Int -> Monom v -> ShowS
forall v. Show v => [Monom v] -> ShowS
forall v. Show v => Monom v -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Monom v] -> ShowS
$cshowList :: forall v. Show v => [Monom v] -> ShowS
show :: Monom v -> String
$cshow :: forall v. Show v => Monom v -> String
showsPrec :: Int -> Monom v -> ShowS
$cshowsPrec :: forall v. Show v => Int -> Monom v -> ShowS
Show,Typeable)

unMonom :: Monom v -> Map v Int
unMonom :: Monom v -> Map v Int
unMonom (Monom Map v Int
table) = Map v Int
table

normalizeMonom :: Ord v => Monom v -> Monom v 
normalizeMonom :: Monom v -> Monom v
normalizeMonom (Monom Map v Int
m) = Map v Int -> Monom v
forall v. Map v Int -> Monom v
Monom (Map v Int -> Monom v) -> Map v Int -> Monom v
forall a b. (a -> b) -> a -> b
$ (Int -> Bool) -> Map v Int -> Map v Int
forall a k. (a -> Bool) -> Map k a -> Map k a
Map.filter (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
0) Map v Int
m

isNormalMonom :: Monom v -> Bool
isNormalMonom :: Monom v -> Bool
isNormalMonom (Monom Map v Int
m) = (Int -> Bool) -> [Int] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
0) (Map v Int -> [Int]
forall k a. Map k a -> [a]
Map.elems Map v Int
m)

monomToList :: Ord v => Monom v -> [(v,Int)]
monomToList :: Monom v -> [(v, Int)]
monomToList (Monom Map v Int
m) = Map v Int -> [(v, Int)]
forall k a. Map k a -> [(k, a)]
Map.toList Map v Int
m

monomFromList :: Ord v => [(v,Int)] -> Monom v
monomFromList :: [(v, Int)] -> Monom v
monomFromList [(v, Int)]
list = Map v Int -> Monom v
forall v. Map v Int -> Monom v
Monom (Map v Int -> Monom v) -> Map v Int -> Monom v
forall a b. (a -> b) -> a -> b
$ [(v, Int)] -> Map v Int
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(v, Int)] -> Map v Int) -> [(v, Int)] -> Map v Int
forall a b. (a -> b) -> a -> b
$ ((v, Int) -> Bool) -> [(v, Int)] -> [(v, Int)]
forall a. (a -> Bool) -> [a] -> [a]
filter (v, Int) -> Bool
forall a a. (Ord a, Num a) => (a, a) -> Bool
f [(v, Int)]
list where
  f :: (a, a) -> Bool
f (a
v,a
e) | a
e a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<  a
0    = String -> Bool
forall a. HasCallStack => String -> a
error String
"monomFromList: negative exponent"
          | a
e a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0    = Bool
False
          | Bool
otherwise = Bool
True

-- | Note: we can collapse variables together!
mapMonom :: (Ord v, Ord w) => (v -> w) -> Monom v -> Monom w
mapMonom :: (v -> w) -> Monom v -> Monom w
mapMonom v -> w
f (Monom Map v Int
old) = Map w Int -> Monom w
forall v. Map v Int -> Monom v
Monom (Map w Int -> Monom w) -> Map w Int -> Monom w
forall a b. (a -> b) -> a -> b
$ (Int -> Int -> Int) -> (v -> w) -> Map v Int -> Map w Int
forall k2 a k1.
Ord k2 =>
(a -> a -> a) -> (k1 -> k2) -> Map k1 a -> Map k2 a
Map.mapKeysWith Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) v -> w
f Map v Int
old 

emptyMonom :: Monom v
emptyMonom :: Monom v
emptyMonom = Map v Int -> Monom v
forall v. Map v Int -> Monom v
Monom Map v Int
forall k a. Map k a
Map.empty

isEmptyMonom :: Monom v -> Bool
isEmptyMonom :: Monom v -> Bool
isEmptyMonom (Monom Map v Int
m) = Map v Int -> Bool
forall k a. Map k a -> Bool
Map.null Map v Int
m

mulMonom :: Ord v => Monom v -> Monom v -> Monom v
mulMonom :: Monom v -> Monom v -> Monom v
mulMonom (Monom Map v Int
m1) (Monom Map v Int
m2) = Map v Int -> Monom v
forall v. Map v Int -> Monom v
Monom ((Int -> Int -> Int) -> Map v Int -> Map v Int -> Map v Int
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) Map v Int
m1 Map v Int
m2)

divMonom :: Ord v => Monom v -> Monom v -> Maybe (Monom v)
divMonom :: Monom v -> Monom v -> Maybe (Monom v)
divMonom (Monom Map v Int
m1) (Monom Map v Int
m2) = 
  if (Int -> Bool) -> [Int] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>=Int
0) (Map v Int -> [Int]
forall k a. Map k a -> [a]
Map.elems Map v Int
pre_monom) 
    then Monom v -> Maybe (Monom v)
forall a. a -> Maybe a
Just (Monom v -> Maybe (Monom v)) -> Monom v -> Maybe (Monom v)
forall a b. (a -> b) -> a -> b
$ Map v Int -> Monom v
forall v. Map v Int -> Monom v
Monom Map v Int
pre_monom
    else Maybe (Monom v)
forall a. Maybe a
Nothing
  where
    minus_m2 :: Map v Int
minus_m2  = (Int -> Int) -> Map v Int -> Map v Int
forall a b k. (a -> b) -> Map k a -> Map k b
Map.map Int -> Int
forall a. Num a => a -> a
negate Map v Int
m2
    pre_monom :: Map v Int
pre_monom = (Int -> Bool) -> Map v Int -> Map v Int
forall a k. (a -> Bool) -> Map k a -> Map k a
Map.filter (Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/=Int
0) 
              (Map v Int -> Map v Int) -> Map v Int -> Map v Int
forall a b. (a -> b) -> a -> b
$ (Int -> Int -> Int) -> Map v Int -> Map v Int -> Map v Int
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) Map v Int
m1 Map v Int
minus_m2

{-# SPECIALIZE prodMonoms :: Ord v => [Monom v] ->  Monom v #-}
prodMonoms :: (Foldable f, Ord v) => f (Monom v) -> Monom v
prodMonoms :: f (Monom v) -> Monom v
prodMonoms f (Monom v)
list = Map v Int -> Monom v
forall v. Map v Int -> Monom v
Monom (Map v Int -> Monom v) -> Map v Int -> Monom v
forall a b. (a -> b) -> a -> b
$ (Int -> Int -> Int) -> [Map v Int] -> Map v Int
forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
(a -> a -> a) -> f (Map k a) -> Map k a
Map.unionsWith Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) ([Map v Int] -> Map v Int) -> [Map v Int] -> Map v Int
forall a b. (a -> b) -> a -> b
$ (Monom v -> Map v Int) -> [Monom v] -> [Map v Int]
forall a b. (a -> b) -> [a] -> [b]
map Monom v -> Map v Int
forall v. Monom v -> Map v Int
unMonom ([Monom v] -> [Map v Int]) -> [Monom v] -> [Map v Int]
forall a b. (a -> b) -> a -> b
$ f (Monom v) -> [Monom v]
forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList f (Monom v)
list

powMonom :: Ord v => Monom v -> Int -> Monom v
powMonom :: Monom v -> Int -> Monom v
powMonom (Monom Map v Int
m) Int
e 
  | Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0     = String -> Monom v
forall a. HasCallStack => String -> a
error String
"powMonom: expecting a non-negative exponent"
  | Int
e Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0    = Monom v
forall v. Monom v
emptyMonom
  | Bool
otherwise = Map v Int -> Monom v
forall v. Map v Int -> Monom v
Monom ((Int -> Int) -> Map v Int -> Map v Int
forall a b k. (a -> b) -> Map k a -> Map k b
Map.map (Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
e) Map v Int
m)

varMonom :: Ord v => v -> Monom v
varMonom :: v -> Monom v
varMonom v
v = Map v Int -> Monom v
forall v. Map v Int -> Monom v
Monom (v -> Int -> Map v Int
forall k a. k -> a -> Map k a
Map.singleton v
v Int
1)

singletonMonom :: Ord v => v -> Int -> Monom v
singletonMonom :: v -> Int -> Monom v
singletonMonom v
v Int
e 
  | Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0     = String -> Monom v
forall a. HasCallStack => String -> a
error String
"singletonMonom: expecting a non-negative exponent"
  | Int
e Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0    = Monom v
forall v. Monom v
emptyMonom
  | Bool
otherwise = Map v Int -> Monom v
forall v. Map v Int -> Monom v
Monom (v -> Int -> Map v Int
forall k a. k -> a -> Map k a
Map.singleton v
v Int
e)

maxDegMonom :: Monom v -> Int
maxDegMonom :: Monom v -> Int
maxDegMonom (Monom Map v Int
m) = [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum (Map v Int -> [Int]
forall k a. Map k a -> [a]
Map.elems Map v Int
m)

totalDegMonom :: Monom v -> Int
totalDegMonom :: Monom v -> Int
totalDegMonom (Monom Map v Int
m) = [Int] -> Int
forall a. Num a => [a] -> a
sum' (Map v Int -> [Int]
forall k a. Map k a -> [a]
Map.elems Map v Int
m)

evalMonom :: (Num c, Ord v) => (v -> c) -> Monom v -> c
evalMonom :: (v -> c) -> Monom v -> c
evalMonom v -> c
f (Monom Map v Int
m) = (c -> c -> c) -> c -> [c] -> c
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' c -> c -> c
forall a. Num a => a -> a -> a
(*) c
1 (((v, Int) -> c) -> [(v, Int)] -> [c]
forall a b. (a -> b) -> [a] -> [b]
map (v, Int) -> c
g ([(v, Int)] -> [c]) -> [(v, Int)] -> [c]
forall a b. (a -> b) -> a -> b
$ Map v Int -> [(v, Int)]
forall k a. Map k a -> [(k, a)]
Map.toList Map v Int
m) where
  g :: (v, Int) -> c
g (v
v,Int
e) = v -> c
f v
v c -> Int -> c
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
e

termSubsMonom :: (Num c, Ord v) => (v -> Maybe c) -> (Monom v, c) -> (Monom v, c)
termSubsMonom :: (v -> Maybe c) -> (Monom v, c) -> (Monom v, c)
termSubsMonom v -> Maybe c
f (Monom Map v Int
m , c
c0) = (Map v Int -> Monom v
forall v. Map v Int -> Monom v
Monom Map v Int
m' , c
c0c -> c -> c
forall a. Num a => a -> a -> a
*c
proj) where
  m' :: Map v Int
m'   = [(v, Int)] -> Map v Int
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(v, Int)] -> Map v Int) -> [(v, Int)] -> Map v Int
forall a b. (a -> b) -> a -> b
$ [Maybe (v, Int)] -> [(v, Int)]
forall a. [Maybe a] -> [a]
catMaybes [Maybe (v, Int)]
mbs
  list :: [(v, Int)]
list = Map v Int -> [(v, Int)]
forall k a. Map k a -> [(k, a)]
Map.toList Map v Int
m
  (c
proj, [Maybe (v, Int)]
mbs)  = (c -> (v, Int) -> (c, Maybe (v, Int)))
-> c -> [(v, Int)] -> (c, [Maybe (v, Int)])
forall (t :: * -> *) a b c.
Traversable t =>
(a -> b -> (a, c)) -> a -> t b -> (a, t c)
mapAccumL c -> (v, Int) -> (c, Maybe (v, Int))
g c
1 [(v, Int)]
list 
  g :: c -> (v, Int) -> (c, Maybe (v, Int))
g !c
s (!v
v,!Int
e) = case v -> Maybe c
f v
v of
    Maybe c
Nothing     -> ( c
s       , (v, Int) -> Maybe (v, Int)
forall a. a -> Maybe a
Just (v
v,Int
e) )   
    Just c
c      -> ( c
s c -> c -> c
forall a. Num a => a -> a -> a
* c
cc -> Int -> c
forall a b. (Num a, Integral b) => a -> b -> a
^Int
e , Maybe (v, Int)
forall a. Maybe a
Nothing    )

--------------------------------------------------------------------------------
-- * differentiation

diffMonom :: (Ord v, Num c) => v -> Int -> Monom v -> Maybe (Monom v, c)
diffMonom :: v -> Int -> Monom v -> Maybe (Monom v, c)
diffMonom v
_ Int
0 Monom v
mon           = (Monom v, c) -> Maybe (Monom v, c)
forall a. a -> Maybe a
Just (Monom v
mon,c
1)
diffMonom v
v Int
k (Monom Map v Int
table) =
  if Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
m 
    then Maybe (Monom v, c)
forall a. Maybe a
Nothing
    else (Monom v, c) -> Maybe (Monom v, c)
forall a. a -> Maybe a
Just (Map v Int -> Monom v
forall v. Map v Int -> Monom v
Monom Map v Int
table' , Integer -> c
forall a. Num a => Integer -> a
fromInteger Integer
c) 
  where
    m :: Int
m      = Int -> v -> Map v Int -> Int
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault Int
0 v
v Map v Int
table
    table' :: Map v Int
table' = v -> Int -> Map v Int -> Map v Int
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert v
v (Int
mInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
k) Map v Int
table
    c :: Integer
c      = [Integer] -> Integer
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
Data.List.product [ Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
mInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
i) | Int
i<-[Int
0..Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1] ] :: Integer

--------------------------------------------------------------------------------

-- Semigroup became a superclass of Monoid
#if MIN_VERSION_base(4,11,0)        

{-# SPECIALIZE prodMonoms :: Ord v => NonEmpty (Monom v) ->  Monom v #-}

instance Ord v => Semigroup (Monom v) where
  <> :: Monom v -> Monom v -> Monom v
(<>)    = Monom v -> Monom v -> Monom v
forall v. Ord v => Monom v -> Monom v -> Monom v
mulMonom
  sconcat :: NonEmpty (Monom v) -> Monom v
sconcat = NonEmpty (Monom v) -> Monom v
forall (f :: * -> *) v.
(Foldable f, Ord v) =>
f (Monom v) -> Monom v
prodMonoms

instance Ord v => Monoid (Monom v)  where
  mempty :: Monom v
mempty  = Monom v
forall v. Monom v
emptyMonom
  mconcat :: [Monom v] -> Monom v
mconcat = [Monom v] -> Monom v
forall (f :: * -> *) v.
(Foldable f, Ord v) =>
f (Monom v) -> Monom v
prodMonoms

#else

instance Ord v => Monoid (Monom v) where
  mempty  = emptyMonom
  mappend = mulMonom
  mconcat = prodMonoms

#endif

--------------------------------------------------------------------------------

instance Pretty v => Pretty (Monom v) where
  pretty :: Monom v -> String
pretty (Monom Map v Int
m) = [(v, Int)] -> String
forall a a. (Eq a, Num a, Pretty a, Show a) => [(a, a)] -> String
worker (Map v Int -> [(v, Int)]
forall k a. Map k a -> [(k, a)]
Map.toList Map v Int
m) where
    worker :: [(a, a)] -> String
worker []    = String
"1"
    worker [(a, a)]
pairs = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"*" (((a, a) -> String) -> [(a, a)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (a, a) -> String
forall a a. (Eq a, Num a, Pretty a, Show a) => (a, a) -> String
f [(a, a)]
pairs) where
      f :: (a, a) -> String
f (a
b,a
0) = String
"1"                                      -- shouldn't normall happen
      f (a
b,a
1) = a -> String
forall a. Pretty a => a -> String
pretty a
b
      f (a
b,a
k) = a -> String
forall a. Pretty a => a -> String
pretty a
b String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"^" String -> ShowS
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
k

--------------------------------------------------------------------------------

instance (Ord v, Pretty v) => Monomial (Monom v) where
  type VarM (Monom v) = v
  normalizeM :: Monom v -> Monom v
normalizeM  = Monom v -> Monom v
forall v. Ord v => Monom v -> Monom v
normalizeMonom
  isNormalM :: Monom v -> Bool
isNormalM   = Monom v -> Bool
forall v. Monom v -> Bool
isNormalMonom
  fromListM :: [(VarM (Monom v), Int)] -> Monom v
fromListM   = [(VarM (Monom v), Int)] -> Monom v
forall v. Ord v => [(v, Int)] -> Monom v
monomFromList
  toListM :: Monom v -> [(VarM (Monom v), Int)]
toListM     = Monom v -> [(VarM (Monom v), Int)]
forall v. Ord v => Monom v -> [(v, Int)]
monomToList
  emptyM :: Monom v
emptyM      = Monom v
forall v. Monom v
emptyMonom
  isEmptyM :: Monom v -> Bool
isEmptyM    = Monom v -> Bool
forall v. Monom v -> Bool
isEmptyMonom
  variableM :: VarM (Monom v) -> Monom v
variableM   = VarM (Monom v) -> Monom v
forall v. Ord v => v -> Monom v
varMonom
  singletonM :: VarM (Monom v) -> Int -> Monom v
singletonM  = VarM (Monom v) -> Int -> Monom v
forall v. Ord v => v -> Int -> Monom v
singletonMonom
  mulM :: Monom v -> Monom v -> Monom v
mulM        = Monom v -> Monom v -> Monom v
forall v. Ord v => Monom v -> Monom v -> Monom v
mulMonom
  divM :: Monom v -> Monom v -> Maybe (Monom v)
divM        = Monom v -> Monom v -> Maybe (Monom v)
forall v. Ord v => Monom v -> Monom v -> Maybe (Monom v)
divMonom
  productM :: [Monom v] -> Monom v
productM    = [Monom v] -> Monom v
forall (f :: * -> *) v.
(Foldable f, Ord v) =>
f (Monom v) -> Monom v
prodMonoms
  powM :: Monom v -> Int -> Monom v
powM        = Monom v -> Int -> Monom v
forall v. Ord v => Monom v -> Int -> Monom v
powMonom
  maxDegM :: Monom v -> Int
maxDegM     = Monom v -> Int
forall v. Monom v -> Int
maxDegMonom              
  totalDegM :: Monom v -> Int
totalDegM   = Monom v -> Int
forall v. Monom v -> Int
totalDegMonom
  diffM :: VarM (Monom v) -> Int -> Monom v -> Maybe (Monom v, c)
diffM       = VarM (Monom v) -> Int -> Monom v -> Maybe (Monom v, c)
forall v c.
(Ord v, Num c) =>
v -> Int -> Monom v -> Maybe (Monom v, c)
diffMonom
  evalM :: (VarM (Monom v) -> c) -> Monom v -> c
evalM       = (VarM (Monom v) -> c) -> Monom v -> c
forall c v. (Num c, Ord v) => (v -> c) -> Monom v -> c
evalMonom
  varSubsM :: (VarM (Monom v) -> VarM (Monom v)) -> Monom v -> Monom v
varSubsM    = (VarM (Monom v) -> VarM (Monom v)) -> Monom v -> Monom v
forall v w. (Ord v, Ord w) => (v -> w) -> Monom v -> Monom w
mapMonom
  termSubsM :: (VarM (Monom v) -> Maybe c) -> (Monom v, c) -> (Monom v, c)
termSubsM   = (VarM (Monom v) -> Maybe c) -> (Monom v, c) -> (Monom v, c)
forall c v.
(Num c, Ord v) =>
(v -> Maybe c) -> (Monom v, c) -> (Monom v, c)
termSubsMonom

--------------------------------------------------------------------------------