module Math.Operad.PolyBag where
import qualified Data.Map as Map
import Data.Maybe
import Math.Operad.PPrint
import Math.Operad.OrderedTree
import Control.Arrow
import Data.List (nub)
data (Show a, Ord a, Num n, TreeOrdering t) => OperadElement a n t = PB (OrderedTree a t) n [(OrderedTree a t,n)] deriving (Ord, Eq, Show, Read)
instance (Show a, Ord a, Num n, TreeOrdering t) => Num (OperadElement a n t) where
a@(PB ma ca baga) + b@(PB mb cb bagb)
| ma > mb = PB ma ca (baga ++ ((mb,cb):bagb))
| ma < mb = b + a
| ca+cb /= 0 = PB ma (ca+cb) (baga++bagb)
| otherwise = let
combinedMap = Map.fromListWith (+) (baga ++ bagb)
maybeSum = Map.maxViewWithKey combinedMap
in
if isNothing maybeSum then PB ma 0 []
else let
((mP,cP),mapP) = fromJust maybeSum
in
PB mP cP (Map.toList mapP)
(*) = undefined
negate pb = (1) .*. pb
abs = undefined
signum = undefined
fromInteger = undefined
collate :: (Show a, Ord a, Num n, TreeOrdering t) => OperadElement a n t -> OperadElement a n t
collate = fromList . toList
fromList :: (TreeOrdering t, Num n, Ord a, Show a) => [(OrderedTree a t,n)] -> OperadElement a n t
fromList lst = fromMaybe (PB (ot $ leaf 1) 0 []) $ do
((mP,cP),mapP) <- Map.maxViewWithKey (Map.fromList lst)
return $ PB mP cP (Map.toList mapP)
toList :: (TreeOrdering t, Num n, Ord a, Show a) => OperadElement a n t -> [(OrderedTree a t, n)]
toList (PB m c bag) = (m,c):bag
mapMonomials :: (Show a, Ord a, Show b, Ord b, Num n, TreeOrdering s, TreeOrdering t) =>
(OrderedTree a s -> OrderedTree b t) -> OperadElement a n s -> OperadElement b n t
mapMonomials f (PB m c bag) = collate (PB (f m) c (map (first f) bag))
foldMonomials :: (Show a, Ord a, Num n, TreeOrdering t) =>
((OrderedTree a t,n) -> [b] -> [b]) -> OperadElement a n t -> [b]
foldMonomials f (PB m c bag) = foldr f [] ((m,c):bag)
instance (Ord a, Show a, Num n, TreeOrdering t) => PPrint (OperadElement a n t) where
pp m = if str == "" then "0" else str
where str = foldMonomials (\(k,a) pstr -> pstr ++ "\n+" ++ show a ++ "*" ++ pp k) m
getTrees :: (Ord a, Show a, TreeOrdering t, Num n) =>
OperadElement a n t -> [OrderedTree a t]
getTrees (PB m _ bag) = nub $ m : (map fst bag)
(.*.) :: (Show a, Ord a, Num n, TreeOrdering t) => n -> OperadElement a n t -> OperadElement a n t
0 .*. (PB ma _ _) = PB ma 0 []
x .*. (PB ma ca baga) = PB ma (x*ca) (map (\(m,c) -> (m,x*c)) baga)
oe :: (Ord a, Show a, TreeOrdering t, Num n) => [(OrderedTree a t, n)] -> OperadElement a n t
oe = fromList
oet :: (Ord a, Show a, TreeOrdering t, Num n) => DecoratedTree a -> OperadElement a n t
oet dect = PB (ot dect) 1 []
oek :: (Ord a, Show a, TreeOrdering t, Num n) => DecoratedTree a -> n -> OperadElement a n t
oek dect n = PB (ot dect) n []
zero :: (Ord a, Show a, TreeOrdering t, Num n) => OperadElement a n t
zero = PB (ot $ leaf 1) 0 []
isZero :: (Ord a, Show a, TreeOrdering t, Num n) => OperadElement a n t -> Bool
isZero m = 0 == leadingCoefficient m
leadingTerm :: (Ord a, Show a, TreeOrdering t, Num n) => OperadElement a n t -> (OrderedTree a t, n)
leadingTerm (PB m c _) = (m,c)
leadingOMonomial :: (Ord a, Show a, TreeOrdering t, Num n) => OperadElement a n t -> OrderedTree a t
leadingOMonomial = fst . leadingTerm
leadingMonomial :: (Ord a, Show a, TreeOrdering t, Num n) => OperadElement a n t -> DecoratedTree a
leadingMonomial = dt .leadingOMonomial
leadingCoefficient :: (Ord a, Show a, TreeOrdering t, Num n) => OperadElement a n t -> n
leadingCoefficient = snd . leadingTerm