module Domain.Math.Equation.BalanceRules
( plusRule, minusRule, timesRule, divisionRule
) where
import Control.Monad
import Domain.Math.Data.Relation
import Domain.Math.Expr
import Domain.Math.Numeric.Views
import Ideas.Common.Library
factorRef, termRef :: Ref Expr
factorRef = makeRef "factor"
termRef = makeRef "term"
plusRule :: Functor f => ParamTrans Expr (f Expr)
plusRule = parameter1 termRef $ \a -> Just . fmap (:+: a)
minusRule :: Functor f => ParamTrans Expr (f Expr)
minusRule = parameter1 termRef $ \a -> Just . fmap (:-: a)
timesRule :: Functor f => ParamTrans Expr (f Expr)
timesRule = parameter1 factorRef $ \a -> unlessZero a . fmap (a :*:)
divisionRule :: ParamTrans Expr (Equation Expr)
divisionRule = parameter1 factorRef $ \a -> unlessZero a . fmap (:/: a)
unlessZero :: Expr -> a -> Maybe a
unlessZero e a = do
r <- matchM rationalView e
guard (r /= 0)
return a