egison-4.1.0: hs-src/Language/Egison/Math/Arith.hs
{- |
Module : Language.Egison.Math.Arith
Licence : MIT
This module defines some basic arithmetic operations for Egison's computer
algebra system.
-}
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 (Div m1 n1) (Div m2 n2) = mathNormalize' $ Div (mathPlusPoly (mathMultPoly m1 n2) (mathMultPoly m2 n1)) (mathMultPoly n1 n2)
mathPlusPoly :: PolyExpr -> PolyExpr -> PolyExpr
mathPlusPoly (Plus ts1) (Plus ts2) = Plus (ts1 ++ ts2)
mathMinus :: ScalarData -> ScalarData -> ScalarData
mathMinus s1 s2 = mathPlus s1 (mathNegate s2)
mathMult :: ScalarData -> ScalarData -> ScalarData
mathMult (Div m1 n1) (Div m2 n2) = mathNormalize' $ Div (mathMultPoly m1 m2) (mathMultPoly n1 n2)
mathMultPoly :: PolyExpr -> PolyExpr -> PolyExpr
mathMultPoly (Plus []) (Plus _) = Plus []
mathMultPoly (Plus _) (Plus []) = Plus []
mathMultPoly (Plus ts1) (Plus ts2) = foldl mathPlusPoly (Plus []) (map (\(Term a xs) -> Plus (map (\(Term b ys) -> Term (a * b) (xs ++ ys)) ts2)) ts1)
mathDiv :: ScalarData -> ScalarData -> ScalarData
mathDiv s (Div p1 p2) = mathMult s (Div p2 p1)
mathPower :: ScalarData -> Integer -> ScalarData
mathPower _ 0 = SingleTerm 1 []
mathPower s 1 = s
mathPower s n | n >= 2 = mathMult s (mathPower s (n - 1))
mathNumerator :: ScalarData -> ScalarData
mathNumerator (Div m _) = Div m (Plus [Term 1 []])
mathDenominator :: ScalarData -> ScalarData
mathDenominator (Div _ n) = Div n (Plus [Term 1 []])