module Symtegration.Symbolic.Simplify.Fraction (simplify) where
import Symtegration.Symbolic
simplify :: Expression -> Expression
simplify :: Expression -> Expression
simplify e :: Expression
e@(Expression
_ :/: Number Integer
0) = Expression
e
simplify (Number Integer
n :/: Number Integer
m)
| Integer
m Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0 = Integer -> Expression
Number (Integer
n Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
g) Expression -> Expression -> Expression
:/: Integer -> Expression
Number (Integer
m Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
g)
| Bool
otherwise = Integer -> Expression
Number ((-Integer
n) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
g) Expression -> Expression -> Expression
:/: Integer -> Expression
Number ((-Integer
m) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
g)
where
g :: Integer
g = Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
gcd Integer
n Integer
m
simplify (Expression
x :/: Expression
y) = Integer -> Expression -> Expression
divideFactor Integer
g Expression
x' Expression -> Expression -> Expression
:/: Integer -> Expression -> Expression
divideFactor Integer
g Expression
y'
where
g :: Integer
g
| (Number Integer
n) <- Expression
y, Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 = Integer -> Integer
forall a. Num a => a -> a
negate (Integer -> Integer) -> Integer -> Integer
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
gcd (Expression -> Integer
commonFactor Expression
x') Integer
n
| Bool
otherwise = Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
gcd (Expression -> Integer
commonFactor Expression
x') (Expression -> Integer
commonFactor Expression
y')
x' :: Expression
x' = Expression -> Expression
simplify Expression
x
y' :: Expression
y' = Expression -> Expression
simplify Expression
y
simplify ((Expression
1 :/: Expression
x) :*: Expression
y) = (Expression
1 Expression -> Expression -> Expression
:/: Integer -> Expression -> Expression
divideFactor Integer
g Expression
x') Expression -> Expression -> Expression
:*: Integer -> Expression -> Expression
divideFactor Integer
g Expression
y'
where
g :: Integer
g = Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
gcd (Expression -> Integer
commonFactor Expression
x') (Expression -> Integer
commonFactor Expression
y')
x' :: Expression
x' = Expression -> Expression
simplify Expression
x
y' :: Expression
y' = Expression -> Expression
simplify Expression
y
simplify (UnaryApply UnaryFunction
func Expression
x) = UnaryFunction -> Expression -> Expression
UnaryApply UnaryFunction
func (Expression -> Expression) -> Expression -> Expression
forall a b. (a -> b) -> a -> b
$ Expression -> Expression
simplify Expression
x
simplify (BinaryApply BinaryFunction
func Expression
x Expression
y) = BinaryFunction -> Expression -> Expression -> Expression
BinaryApply BinaryFunction
func (Expression -> Expression
simplify Expression
x) (Expression -> Expression
simplify Expression
y)
simplify Expression
e = Expression
e
commonFactor :: Expression -> Integer
commonFactor :: Expression -> Integer
commonFactor (Number Integer
n) = Integer
n
commonFactor (Expression
x :+: Expression
y) = Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
gcd (Expression -> Integer
commonFactor Expression
x) (Expression -> Integer
commonFactor Expression
y)
commonFactor (Expression
x :-: Expression
y) = Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
gcd (Expression -> Integer
commonFactor Expression
x) (Expression -> Integer
commonFactor Expression
y)
commonFactor (Number Integer
n :*: Expression
_) = Integer
n
commonFactor Expression
_ = Integer
1
divideFactor :: Integer -> Expression -> Expression
divideFactor :: Integer -> Expression -> Expression
divideFactor Integer
0 Expression
e = Expression
e
divideFactor Integer
1 Expression
e = Expression
e
divideFactor Integer
g (Number Integer
n) = Integer -> Expression
Number (Integer -> Expression) -> Integer -> Expression
forall a b. (a -> b) -> a -> b
$ Integer
n Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
g
divideFactor Integer
g (Expression
x :+: Expression
y) = Integer -> Expression -> Expression
divideFactor Integer
g Expression
x Expression -> Expression -> Expression
:+: Integer -> Expression -> Expression
divideFactor Integer
g Expression
y
divideFactor Integer
g (Number Integer
n :*: Expression
x) = Integer -> Expression
Number (Integer
n Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
g) Expression -> Expression -> Expression
:*: Expression
x
divideFactor Integer
g Expression
e = Expression
e Expression -> Expression -> Expression
:/: Integer -> Expression
Number Integer
g