module Language.Egison.Math.Arith
( mathPlus
, mathMinus
, mathMult
, mathDiv
, mathPower
, mathNumerator
, mathDenominator
) where
import Language.Egison.Math.Expr
import Language.Egison.Math.Normalize
mathPlus :: ScalarData -> ScalarData -> ScalarData
mathPlus :: ScalarData -> ScalarData -> ScalarData
mathPlus (Div PolyExpr
m1 PolyExpr
n1) (Div PolyExpr
m2 PolyExpr
n2) = ScalarData -> ScalarData
mathNormalize' (ScalarData -> ScalarData) -> ScalarData -> ScalarData
forall a b. (a -> b) -> a -> b
$ PolyExpr -> PolyExpr -> ScalarData
Div (PolyExpr -> PolyExpr -> PolyExpr
mathPlusPoly (PolyExpr -> PolyExpr -> PolyExpr
mathMultPoly PolyExpr
m1 PolyExpr
n2) (PolyExpr -> PolyExpr -> PolyExpr
mathMultPoly PolyExpr
m2 PolyExpr
n1)) (PolyExpr -> PolyExpr -> PolyExpr
mathMultPoly PolyExpr
n1 PolyExpr
n2)
mathPlusPoly :: PolyExpr -> PolyExpr -> PolyExpr
mathPlusPoly :: PolyExpr -> PolyExpr -> PolyExpr
mathPlusPoly (Plus [TermExpr]
ts1) (Plus [TermExpr]
ts2) = [TermExpr] -> PolyExpr
Plus ([TermExpr]
ts1 [TermExpr] -> [TermExpr] -> [TermExpr]
forall a. [a] -> [a] -> [a]
++ [TermExpr]
ts2)
mathMinus :: ScalarData -> ScalarData -> ScalarData
mathMinus :: ScalarData -> ScalarData -> ScalarData
mathMinus ScalarData
s1 ScalarData
s2 = ScalarData -> ScalarData -> ScalarData
mathPlus ScalarData
s1 (ScalarData -> ScalarData
mathNegate ScalarData
s2)
mathMult :: ScalarData -> ScalarData -> ScalarData
mathMult :: ScalarData -> ScalarData -> ScalarData
mathMult (Div PolyExpr
m1 PolyExpr
n1) (Div PolyExpr
m2 PolyExpr
n2) = ScalarData -> ScalarData
mathNormalize' (ScalarData -> ScalarData) -> ScalarData -> ScalarData
forall a b. (a -> b) -> a -> b
$ PolyExpr -> PolyExpr -> ScalarData
Div (PolyExpr -> PolyExpr -> PolyExpr
mathMultPoly PolyExpr
m1 PolyExpr
m2) (PolyExpr -> PolyExpr -> PolyExpr
mathMultPoly PolyExpr
n1 PolyExpr
n2)
mathMultPoly :: PolyExpr -> PolyExpr -> PolyExpr
mathMultPoly :: PolyExpr -> PolyExpr -> PolyExpr
mathMultPoly (Plus []) (Plus [TermExpr]
_) = [TermExpr] -> PolyExpr
Plus []
mathMultPoly (Plus [TermExpr]
_) (Plus []) = [TermExpr] -> PolyExpr
Plus []
mathMultPoly (Plus [TermExpr]
ts1) (Plus [TermExpr]
ts2) = (PolyExpr -> PolyExpr -> PolyExpr)
-> PolyExpr -> [PolyExpr] -> PolyExpr
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl PolyExpr -> PolyExpr -> PolyExpr
mathPlusPoly ([TermExpr] -> PolyExpr
Plus []) ((TermExpr -> PolyExpr) -> [TermExpr] -> [PolyExpr]
forall a b. (a -> b) -> [a] -> [b]
map (\(Term Integer
a Monomial
xs) -> [TermExpr] -> PolyExpr
Plus ((TermExpr -> TermExpr) -> [TermExpr] -> [TermExpr]
forall a b. (a -> b) -> [a] -> [b]
map (\(Term Integer
b Monomial
ys) -> Integer -> Monomial -> TermExpr
Term (Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
b) (Monomial
xs Monomial -> Monomial -> Monomial
forall a. [a] -> [a] -> [a]
++ Monomial
ys)) [TermExpr]
ts2)) [TermExpr]
ts1)
mathDiv :: ScalarData -> ScalarData -> ScalarData
mathDiv :: ScalarData -> ScalarData -> ScalarData
mathDiv ScalarData
s (Div PolyExpr
p1 PolyExpr
p2) = ScalarData -> ScalarData -> ScalarData
mathMult ScalarData
s (PolyExpr -> PolyExpr -> ScalarData
Div PolyExpr
p2 PolyExpr
p1)
mathPower :: ScalarData -> Integer -> ScalarData
mathPower :: ScalarData -> Integer -> ScalarData
mathPower ScalarData
_ Integer
0 = Integer -> Monomial -> ScalarData
SingleTerm Integer
1 []
mathPower ScalarData
s Integer
1 = ScalarData
s
mathPower ScalarData
s Integer
n | Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
2 = ScalarData -> ScalarData -> ScalarData
mathMult ScalarData
s (ScalarData -> Integer -> ScalarData
mathPower ScalarData
s (Integer
n Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1))
mathNumerator :: ScalarData -> ScalarData
mathNumerator :: ScalarData -> ScalarData
mathNumerator (Div PolyExpr
m PolyExpr
_) = PolyExpr -> PolyExpr -> ScalarData
Div PolyExpr
m ([TermExpr] -> PolyExpr
Plus [Integer -> Monomial -> TermExpr
Term Integer
1 []])
mathDenominator :: ScalarData -> ScalarData
mathDenominator :: ScalarData -> ScalarData
mathDenominator (Div PolyExpr
_ PolyExpr
n) = PolyExpr -> PolyExpr -> ScalarData
Div PolyExpr
n ([TermExpr] -> PolyExpr
Plus [Integer -> Monomial -> TermExpr
Term Integer
1 []])