{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, NoMonomorphismRestriction, ScopedTypeVariables, DeriveFunctor #-}
module Math.Combinatorics.CombinatorialHopfAlgebra where
import Prelude hiding ( (*>) )
import Data.List as L
import Data.Maybe (fromJust)
import qualified Data.Set as S
import Math.Core.Field
import Math.Core.Utils
import Math.Algebras.VectorSpace hiding (E)
import Math.Algebras.TensorProduct
import Math.Algebras.Structures
import Math.Combinatorics.Poset
import Math.CommutativeAlgebra.Polynomial
class Graded b where
grade :: b -> Int
instance Graded b => Graded (Dual b) where grade (Dual b) = grade b
class (Eq k, Num k, Ord b, Graded b, HopfAlgebra k b) => CombinatorialHopfAlgebra k b where
zeta :: Vect k b -> Vect k ()
gradedConnectedAntipode
:: (Eq k, Num k, Ord b, Bialgebra k b, Graded b) =>
Vect k b -> Vect k b
gradedConnectedAntipode = linear antipode' where
antipode' b = if grade b == 0
then return b
else (negatev . mult . (id `tf` gradedConnectedAntipode) . removeLeftGradeZero . comult . return) b
removeLeftGradeZero (V ts) = V $ filter (\((l,r),_) -> grade l /= 0) ts
newtype Shuffle a = Sh [a] deriving (Eq,Ord,Show)
instance Graded (Shuffle a) where grade (Sh xs) = length xs
sh :: [a] -> Vect Q (Shuffle a)
sh = return . Sh
shuffles (x:xs) (y:ys) = map (x:) (shuffles xs (y:ys)) ++ map (y:) (shuffles (x:xs) ys)
shuffles xs [] = [xs]
shuffles [] ys = [ys]
instance (Eq k, Num k, Ord a) => Algebra k (Shuffle a) where
unit x = x *> return (Sh [])
mult = linear mult' where
mult' (Sh xs, Sh ys) = sumv [return (Sh zs) | zs <- shuffles xs ys]
deconcatenations xs = zip (inits xs) (tails xs)
instance (Eq k, Num k, Ord a) => Coalgebra k (Shuffle a) where
counit = unwrap . linear counit' where counit' (Sh xs) = if null xs then 1 else 0
comult = linear comult' where
comult' (Sh xs) = sumv [return (Sh us, Sh vs) | (us, vs) <- deconcatenations xs]
instance (Eq k, Num k, Ord a) => Bialgebra k (Shuffle a) where {}
instance (Eq k, Num k, Ord a) => HopfAlgebra k (Shuffle a) where
antipode = linear (\(Sh xs) -> (-1)^length xs *> return (Sh (reverse xs)))
newtype SSymF = SSymF [Int] deriving (Eq)
instance Ord SSymF where
compare (SSymF xs) (SSymF ys) = compare (length xs, xs) (length ys, ys)
instance Show SSymF where
show (SSymF xs) = "F " ++ show xs
instance Graded SSymF where grade (SSymF xs) = length xs
ssymF :: [Int] -> Vect Q SSymF
ssymF xs | L.sort xs == [1..n] = return (SSymF xs)
| otherwise = error "Not a permutation of [1..n]"
where n = length xs
shiftedConcat (SSymF xs) (SSymF ys) = let k = length xs in SSymF (xs ++ map (+k) ys)
prop_Associative f (x,y,z) = f x (f y z) == f (f x y) z
instance (Eq k, Num k) => Algebra k SSymF where
unit x = x *> return (SSymF [])
mult = linear mult' where
mult' (SSymF xs, SSymF ys) =
let k = length xs
in sumv [return (SSymF zs) | zs <- shuffles xs (map (+k) ys)]
flatten xs = let mapping = zip (L.sort xs) [1..]
in [y | x <- xs, let Just y = lookup x mapping]
instance (Eq k, Num k) => Coalgebra k SSymF where
counit = unwrap . linear counit' where counit' (SSymF xs) = if null xs then 1 else 0
comult = linear comult'
where comult' (SSymF xs) = sumv [return (SSymF (st us), SSymF (st vs)) | (us, vs) <- deconcatenations xs]
st = flatten
instance (Eq k, Num k) => Bialgebra k SSymF where {}
instance (Eq k, Num k) => HopfAlgebra k SSymF where
antipode = gradedConnectedAntipode
instance HasInverses SSymF where
inverse (SSymF xs) = SSymF $ map snd $ L.sort $ map (\(s,t)->(t,s)) $ zip [1..] xs
instance (Eq k, Num k) => HasPairing k SSymF SSymF where
pairing = linear pairing' where
pairing' (x,y) = delta x (inverse y)
newtype SSymM = SSymM [Int] deriving (Eq)
instance Ord SSymM where
compare (SSymM xs) (SSymM ys) = compare (length xs, xs) (length ys, ys)
instance Show SSymM where
show (SSymM xs) = "M " ++ show xs
instance Graded SSymM where grade (SSymM xs) = length xs
ssymM :: [Int] -> Vect Q SSymM
ssymM xs | L.sort xs == [1..n] = return (SSymM xs)
| otherwise = error "Not a permutation of [1..n]"
where n = length xs
inversions xs = let ixs = zip [1..] xs
in [(i,j) | ((i,xi),(j,xj)) <- pairs ixs, xi > xj]
weakOrder xs ys = inversions xs `isSubsetAsc` inversions ys
mu (set,po) x y = mu' x y where
mu' x y | x == y = 1
| po x y = negate $ sum [mu' x z | z <- set, po x z, po z y, z /= y]
| otherwise = 0
ssymMtoF :: (Eq k, Num k) => Vect k SSymM -> Vect k SSymF
ssymMtoF = linear ssymMtoF' where
ssymMtoF' (SSymM u) = sumv [mu (set,po) u v *> return (SSymF v) | v <- set, po u v]
where set = L.permutations u
po = weakOrder
ssymFtoM :: (Eq k, Num k) => Vect k SSymF -> Vect k SSymM
ssymFtoM = linear ssymFtoM' where
ssymFtoM' (SSymF u) = sumv [return (SSymM v) | v <- set, po u v]
where set = L.permutations u
po = weakOrder
instance (Eq k, Num k) => Algebra k SSymM where
unit x = x *> return (SSymM [])
mult = ssymFtoM . mult . (ssymMtoF `tf` ssymMtoF)
instance (Eq k, Num k) => Coalgebra k SSymM where
counit = unwrap . linear counit' where counit' (SSymM xs) = if null xs then 1 else 0
comult = linear comult'
where comult' (SSymM xs) = sumv [return (SSymM (flatten ys), SSymM (flatten zs))
| (ys,zs) <- deconcatenations xs,
minimum (infinity:ys) > maximum (0:zs)]
infinity = maxBound :: Int
instance (Eq k, Num k) => Bialgebra k SSymM where {}
instance (Eq k, Num k) => HopfAlgebra k SSymM where
antipode = gradedConnectedAntipode
instance (Eq k, Num k) => Algebra k (Dual SSymF) where
unit x = x *> return (Dual (SSymF []))
mult = linear mult' where
mult' (Dual (SSymF xs), Dual (SSymF ys)) =
sumv [(return . Dual . SSymF) (xs'' ++ ys'')
| xs' <- combinationsOf r [1..r+s], let ys' = diffAsc [1..r+s] xs',
xs'' <- L.permutations xs', flatten xs'' == xs,
ys'' <- L.permutations ys', flatten ys'' == ys ]
where r = length xs; s = length ys
instance (Eq k, Num k) => Coalgebra k (Dual SSymF) where
counit = unwrap . linear counit' where counit' (Dual (SSymF xs)) = if null xs then 1 else 0
comult = linear comult' where
comult' (Dual (SSymF xs)) =
sumv [return (Dual (SSymF ys), Dual (SSymF (flatten zs))) | i <- [0..n], let (ys,zs) = L.partition (<=i) xs ]
where n = length xs
instance (Eq k, Num k) => Bialgebra k (Dual SSymF) where {}
instance (Eq k, Num k) => HopfAlgebra k (Dual SSymF) where
antipode = gradedConnectedAntipode
instance (Eq k, Num k) => HasPairing k SSymF (Dual SSymF) where
pairing = linear pairing' where
pairing' (x, Dual y) = delta x y
ssymFtoDual :: (Eq k, Num k) => Vect k SSymF -> Vect k (Dual SSymF)
ssymFtoDual = nf . fmap (Dual . inverse)
data PBT a = T (PBT a) a (PBT a) | E deriving (Eq, Show, Functor)
instance Ord a => Ord (PBT a) where
compare u v = compare (shapeSignature u, prefix u) (shapeSignature v, prefix v)
newtype YSymF a = YSymF (PBT a) deriving (Eq, Ord, Functor)
instance Show a => Show (YSymF a) where
show (YSymF t) = "F(" ++ show t ++ ")"
instance Graded (YSymF a) where grade (YSymF t) = nodecount t
ysymF :: PBT a -> Vect Q (YSymF a)
ysymF t = return (YSymF t)
nodecount (T l x r) = 1 + nodecount l + nodecount r
nodecount E = 0
leafcount (T l x r) = leafcount l + leafcount r
leafcount E = 1
prefix E = []
prefix (T l x r) = x : prefix l ++ prefix r
shapeSignature t = shapeSignature' (nodeCountTree t)
where shapeSignature' E = [0]
shapeSignature' (T l x r) = x : shapeSignature' r ++ shapeSignature' l
nodeCountTree E = E
nodeCountTree (T l _ r) = T l' n r'
where l' = nodeCountTree l
r' = nodeCountTree r
n = 1 + (case l' of E -> 0; T _ lc _ -> lc) + (case r' of E -> 0; T _ rc _ -> rc)
leafCountTree E = E
leafCountTree (T l _ r) = T l' n r'
where l' = leafCountTree l
r' = leafCountTree r
n = (case l' of E -> 1; T _ lc _ -> lc) + (case r' of E -> 1; T _ rc _ -> rc)
lrCountTree E = E
lrCountTree (T l _ r) = T l' (lc,rc) r'
where l' = lrCountTree l
r' = lrCountTree r
lc = case l' of E -> 0; T _ (llc,lrc) _ -> 1 + llc + lrc
rc = case r' of E -> 0; T _ (rlc,rrc) _ -> 1 + rlc + rrc
shape :: PBT a -> PBT ()
shape t = fmap (\_ -> ()) t
numbered t = numbered' 1 t
where numbered' _ E = E
numbered' i (T l x r) = let k = nodecount l in T (numbered' i l) (i+k) (numbered' (i+k+1) r)
splits E = [(E,E)]
splits (T l x r) = [(u, T v x r) | (u,v) <- splits l] ++ [(T l x u, v) | (u,v) <- splits r]
instance (Eq k, Num k, Ord a) => Coalgebra k (YSymF a) where
counit = unwrap . linear counit' where counit' (YSymF E) = 1; counit' (YSymF (T _ _ _)) = 0
comult = linear comult'
where comult' (YSymF t) = sumv [return (YSymF u, YSymF v) | (u,v) <- splits t]
multisplits 1 t = [ [t] ]
multisplits 2 t = [ [u,v] | (u,v) <- splits t ]
multisplits n t = [ u:ws | (u,v) <- splits t, ws <- multisplits (n-1) v ]
graft [t] E = t
graft ts (T l x r) = let (ls,rs) = splitAt (leafcount l) ts
in T (graft ls l) x (graft rs r)
instance (Eq k, Num k, Ord a) => Algebra k (YSymF a) where
unit x = x *> return (YSymF E)
mult = linear mult' where
mult' (YSymF t, YSymF u) = sumv [return (YSymF (graft ts u)) | ts <- multisplits (leafcount u) t]
instance (Eq k, Num k, Ord a) => Bialgebra k (YSymF a) where {}
instance (Eq k, Num k, Ord a) => HopfAlgebra k (YSymF a) where
antipode = gradedConnectedAntipode
newtype YSymM = YSymM (PBT ()) deriving (Eq, Ord)
instance Show YSymM where
show (YSymM t) = "M(" ++ show t ++ ")"
instance Graded YSymM where grade (YSymM t) = nodecount t
ysymM :: PBT () -> Vect Q YSymM
ysymM t = return (YSymM t)
trees :: Int -> [PBT ()]
trees 0 = [E]
trees n = [T l () r | i <- [0..n-1], l <- trees (n-1-i), r <- trees i]
tamariCovers :: PBT a -> [PBT a]
tamariCovers E = []
tamariCovers (T t@(T u x v) y w) = [T t' y w | t' <- tamariCovers t]
++ [T t y w' | w' <- tamariCovers w]
++ [T u y (T v x w)]
tamariCovers (T E x u) = [T E x u' | u' <- tamariCovers u]
tamariUpSet :: Ord a => PBT a -> [PBT a]
tamariUpSet t = upSet' [] [t]
where upSet' interior boundary =
if null boundary
then interior
else let interior' = setUnionAsc interior boundary
boundary' = toSet $ concatMap tamariCovers boundary
in upSet' interior' boundary'
tamariOrder :: PBT a -> PBT a -> Bool
tamariOrder u v = weakOrder (minPerm u) (minPerm v)
ysymMtoF :: (Eq k, Num k) => Vect k YSymM -> Vect k (YSymF ())
ysymMtoF = linear ysymMtoF' where
ysymMtoF' (YSymM t) = sumv [mu (set,po) t s *> return (YSymF s) | s <- set]
where po = tamariOrder
set = tamariUpSet t
ysymFtoM :: (Eq k, Num k) => Vect k (YSymF ()) -> Vect k YSymM
ysymFtoM = linear ysymFtoM' where
ysymFtoM' (YSymF t) = sumv [return (YSymM s) | s <- tamariUpSet t]
instance (Eq k, Num k) => Algebra k YSymM where
unit x = x *> return (YSymM E)
mult = ysymFtoM . mult . (ysymMtoF `tf` ysymMtoF)
instance (Eq k, Num k) => Coalgebra k YSymM where
counit = unwrap . linear counit' where counit' (YSymM E) = 1; counit' (YSymM (T _ _ _)) = 0
comult = linear comult' where
comult' (YSymM t) = sumv [return (YSymM r, YSymM s) | (rs,ss) <- deconcatenations (underDecomposition t),
let r = foldl under E rs, let s = foldl under E ss]
instance (Eq k, Num k) => Bialgebra k YSymM where {}
instance (Eq k, Num k) => HopfAlgebra k YSymM where
antipode = gradedConnectedAntipode
compositions :: Int -> [[Int]]
compositions 0 = [[]]
compositions n = [i:is | i <- [1..n], is <- compositions (n-i)]
quasiShuffles :: [Int] -> [Int] -> [[Int]]
quasiShuffles (x:xs) (y:ys) = map (x:) (quasiShuffles xs (y:ys)) ++
map ((x+y):) (quasiShuffles xs ys) ++
map (y:) (quasiShuffles (x:xs) ys)
quasiShuffles xs [] = [xs]
quasiShuffles [] ys = [ys]
newtype QSymM = QSymM [Int] deriving (Eq)
instance Ord QSymM where
compare (QSymM xs) (QSymM ys) = compare (sum xs, xs) (sum ys, ys)
instance Show QSymM where
show (QSymM xs) = "M " ++ show xs
instance Graded QSymM where grade (QSymM xs) = sum xs
qsymM :: [Int] -> Vect Q QSymM
qsymM xs | all (>0) xs = return (QSymM xs)
| otherwise = error "qsymM: not a composition"
instance (Eq k, Num k) => Algebra k QSymM where
unit x = x *> return (QSymM [])
mult = linear mult' where
mult' (QSymM alpha, QSymM beta) = sumv [return (QSymM gamma) | gamma <- quasiShuffles alpha beta]
instance (Eq k, Num k) => Coalgebra k QSymM where
counit = unwrap . linear counit' where counit' (QSymM alpha) = if null alpha then 1 else 0
comult = linear comult' where
comult' (QSymM gamma) = sumv [return (QSymM alpha, QSymM beta) | (alpha,beta) <- deconcatenations gamma]
instance (Eq k, Num k) => Bialgebra k QSymM where {}
instance (Eq k, Num k) => HopfAlgebra k QSymM where
antipode = gradedConnectedAntipode
coarsenings (x1:x2:xs) = map (x1:) (coarsenings (x2:xs)) ++ coarsenings ((x1+x2):xs)
coarsenings xs = [xs]
refinements (x:xs) = [y++ys | y <- compositions x, ys <- refinements xs]
refinements [] = [[]]
newtype QSymF = QSymF [Int] deriving (Eq)
instance Ord QSymF where
compare (QSymF xs) (QSymF ys) = compare (sum xs, xs) (sum ys, ys)
instance Show QSymF where
show (QSymF xs) = "F " ++ show xs
instance Graded QSymF where grade (QSymF xs) = sum xs
qsymF :: [Int] -> Vect Q QSymF
qsymF xs | all (>0) xs = return (QSymF xs)
| otherwise = error "qsymF: not a composition"
qsymMtoF :: (Eq k, Num k) => Vect k QSymM -> Vect k QSymF
qsymMtoF = linear qsymMtoF' where
qsymMtoF' (QSymM alpha) = sumv [(-1) ^ (length beta - length alpha) *> return (QSymF beta) | beta <- refinements alpha]
qsymFtoM :: (Eq k, Num k) => Vect k QSymF -> Vect k QSymM
qsymFtoM = linear qsymFtoM' where
qsymFtoM' (QSymF alpha) = sumv [return (QSymM beta) | beta <- refinements alpha]
instance (Eq k, Num k) => Algebra k QSymF where
unit x = x *> return (QSymF [])
mult = qsymMtoF . mult . (qsymFtoM `tf` qsymFtoM)
instance (Eq k, Num k) => Coalgebra k QSymF where
counit = unwrap . linear counit' where counit' (QSymF xs) = if null xs then 1 else 0
comult = (qsymMtoF `tf` qsymMtoF) . comult . qsymFtoM
instance (Eq k, Num k) => Bialgebra k QSymF where {}
instance (Eq k, Num k) => HopfAlgebra k QSymF where
antipode = gradedConnectedAntipode
qsymPoly :: Int -> [Int] -> GlexPoly Q String
qsymPoly n is = sum [product (zipWith (^) xs' is) | xs' <- combinationsOf r xs]
where xs = [glexvar ("x" ++ show i) | i <- [1..n] ]
r = length is
newtype SymM = SymM [Int] deriving (Eq,Show)
instance Ord SymM where
compare (SymM xs) (SymM ys) = compare (sum xs, ys) (sum ys, xs)
instance Graded SymM where grade (SymM xs) = sum xs
symM :: [Int] -> Vect Q SymM
symM xs | all (>0) xs = return (SymM $ sortDesc xs)
| otherwise = error "symM: not a partition"
instance (Eq k, Num k) => Algebra k SymM where
unit x = x *> return (SymM [])
mult = linear mult' where
mult' (SymM lambda, SymM mu) = sumv [return (SymM nu) | nu <- symMult lambda mu]
compositionsFromPartition = foldr (\l rs -> concatMap (shuffles l) rs) [[]] . L.group
symMult xs ys = filter isWeaklyDecreasing $ concat
[quasiShuffles xs' ys' | xs' <- compositionsFromPartition xs, ys' <- compositionsFromPartition ys]
instance (Eq k, Num k) => Coalgebra k SymM where
counit = unwrap . linear counit' where counit' (SymM lambda) = if null lambda then 1 else 0
comult = linear comult' where
comult' (SymM lambda) = sumv [return (SymM mu, SymM nu) | mu <- toSet (powersetdfs lambda), let nu = diffDesc lambda mu]
instance (Eq k, Num k) => Bialgebra k SymM where {}
instance (Eq k, Num k) => HopfAlgebra k SymM where
antipode = gradedConnectedAntipode
newtype SymE = SymE [Int] deriving (Eq,Ord,Show)
instance Graded SymE where grade (SymE xs) = sum xs
symE :: [Int] -> Vect Q SymE
symE xs | all (>0) xs = return (SymE $ sortDesc xs)
| otherwise = error "symE: not a partition"
instance (Eq k, Num k) => Algebra k SymE where
unit x = x *> return (SymE [])
mult = linear (\(SymE lambda, SymE mu) -> return $ SymE $ multisetSumDesc lambda mu)
instance (Eq k, Num k) => Coalgebra k SymE where
counit = unwrap . linear counit' where counit' (SymE lambda) = if null lambda then 1 else 0
comult = linear comult' where
comult' (SymE [n]) = sumv [return (e i, e (n-i)) | i <- [0..n] ]
comult' (SymE lambda) = product [comult' (SymE [n]) | n <- lambda]
e 0 = SymE []
e i = SymE [i]
instance (Eq k, Num k) => Bialgebra k SymE where {}
symEtoM :: (Eq k, Num k) => Vect k SymE -> Vect k SymM
symEtoM = linear symEtoM' where
symEtoM' (SymE [n]) = return (SymM (replicate n 1))
symEtoM' (SymE lambda) = product [symEtoM' (SymE [p]) | p <- lambda]
newtype SymH = SymH [Int] deriving (Eq,Ord,Show)
symH :: [Int] -> Vect Q SymH
symH xs | all (>0) xs = return (SymH $ sortDesc xs)
| otherwise = error "symH: not a partition"
instance (Eq k, Num k) => Algebra k SymH where
unit x = x *> return (SymH [])
mult = linear (\(SymH lambda, SymH mu) -> return $ SymH $ multisetSumDesc lambda mu)
instance (Eq k, Num k) => Coalgebra k SymH where
counit = unwrap . linear counit' where counit' (SymH lambda) = if null lambda then 1 else 0
comult = linear comult' where
comult' (SymH [n]) = sumv [return (h i, h (n-i)) | i <- [0..n] ]
comult' (SymH lambda) = product [comult' (SymH [n]) | n <- lambda]
h 0 = SymH []
h i = SymH [i]
instance (Eq k, Num k) => Bialgebra k SymH where {}
symHtoM :: (Eq k, Num k) => Vect k SymH -> Vect k SymM
symHtoM = linear symHtoM' where
symHtoM' (SymH [n]) = sumv [return (SymM mu) | mu <- integerPartitions n]
symHtoM' (SymH lambda) = product [symHtoM' (SymH [p]) | p <- lambda]
newtype NSym = NSym [Int] deriving (Eq,Ord,Show)
instance Graded NSym where grade (NSym xs) = sum xs
nsym :: [Int] -> Vect Q NSym
nsym xs | all (>0) xs = return (NSym xs)
| otherwise = error "nsym: not a composition"
instance (Eq k, Num k) => Algebra k NSym where
unit x = x *> return (NSym [])
mult = linear mult' where
mult' (NSym xs, NSym ys) = return $ NSym $ xs ++ ys
instance (Eq k, Num k) => Coalgebra k NSym where
counit = unwrap . linear counit' where counit' (NSym zs) = if null zs then 1 else 0
comult = linear comult' where
comult' (NSym [n]) = sumv [return (z i, z (n-i)) | i <- [0..n] ]
comult' (NSym zs) = product [comult' (NSym [n]) | n <- zs]
z 0 = NSym []
z i = NSym [i]
instance (Eq k, Num k) => Bialgebra k NSym where {}
instance (Eq k, Num k) => HopfAlgebra k NSym where
antipode = linear antipode' where
antipode' (NSym alpha) = sumv [(-1)^length beta *> return (NSym beta) | beta <- refinements (reverse alpha)]
descendingTree [] = E
descendingTree [x] = T E x E
descendingTree xs = T l x r
where x = maximum xs
(ls,_:rs) = L.break (== x) xs
l = descendingTree ls
r = descendingTree rs
descendingTreeMap :: (Eq k, Num k) => Vect k SSymF -> Vect k (YSymF ())
descendingTreeMap = nf . fmap (YSymF . shape . descendingTree')
where descendingTree' (SSymF xs) = descendingTree xs
minPerm t = minPerm' (lrCountTree t)
where minPerm' E = []
minPerm' (T l (lc,rc) r) = minPerm' l ++ [lc+rc+1] ++ map (+lc) (minPerm' r)
maxPerm t = maxPerm' (lrCountTree t)
where maxPerm' E = []
maxPerm' (T l (lc,rc) r) = map (+rc) (maxPerm' l) ++ [lc+rc+1] ++ maxPerm' r
leftLeafComposition E = []
leftLeafComposition t = cuts $ tail $ leftLeafs t
where leftLeafs (T l x E) = leftLeafs l ++ [False]
leftLeafs (T l x r) = leftLeafs l ++ leftLeafs r
leftLeafs E = [True]
cuts bs = case break id bs of
(ls,r:rs) -> (length ls + 1) : cuts rs
(ls,[]) -> [length ls]
leftLeafComposition' (YSymF t) = QSymF (leftLeafComposition t)
leftLeafCompositionMap :: (Eq k, Num k) => Vect k (YSymF a) -> Vect k QSymF
leftLeafCompositionMap = nf . fmap leftLeafComposition'
descents [] = []
descents xs = map (+1) $ L.elemIndices True $ zipWith (>) xs (tail xs)
descentComposition [] = []
descentComposition xs = descComp 0 xs where
descComp c (x1:x2:xs) = if x1 < x2 then descComp (c+1) (x2:xs) else (c+1) : descComp 0 (x2:xs)
descComp c [x] = [c+1]
descentMap :: (Eq k, Num k) => Vect k SSymF -> Vect k QSymF
descentMap = nf . fmap (\(SSymF xs) -> QSymF (descentComposition xs))
underComposition (QSymF ps) = foldr under (SSymF []) [SSymF [1..p] | p <- ps]
where under (SSymF xs) (SSymF ys) = let q = length ys
zs = map (+q) xs ++ ys
in SSymF zs
under E t = t
under (T l x r) t = T l x (under r t)
isUnderIrreducible (T l x E) = True
isUnderIrreducible _ = False
underDecomposition (T l x r) = T l x E : underDecomposition r
underDecomposition E = []
ysymmToSh = fmap ysymmToSh'
where ysymmToSh' (YSymM t) = Sh (underDecomposition t)
symToQSymM :: (Eq k, Num k) => Vect k SymM -> Vect k QSymM
symToQSymM = linear symToQSymM' where
symToQSymM' (SymM ps) = sumv [return (QSymM c) | c <- compositionsFromPartition ps]
nsymToSymH :: (Eq k, Num k) => Vect k NSym -> Vect k SymH
nsymToSymH = linear nsymToSym' where
nsymToSym' (NSym zs) = return (SymH $ sortDesc zs)
nsymToSSym = linear nsymToSSym' where
nsymToSSym' (NSym xs) = product [return (SSymF [1..n]) | n <- xs]
instance (Eq k, Num k) => HasPairing k SymH SymM where
pairing = linear pairing' where
pairing' (SymH alpha, SymM beta) = delta alpha beta
instance (Eq k, Num k) => HasPairing k NSym QSymM where
pairing = linear pairing' where
pairing' (NSym alpha, QSymM beta) = delta alpha beta