#[cfg(test)]
mod tests {
use crate::engine::simplify::Simplifier;
use crate::core::{Expression, Number, BinaryOperator, UnaryOperator, MathConstant};
use num_bigint::BigInt;
fn create_simplifier() -> Simplifier {
Simplifier::new()
}
#[test]
fn test_basic_arithmetic_simplification() {
let mut simplifier = create_simplifier();
let expr = Expression::add(
Expression::Number(Number::zero()),
Expression::variable("x")
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::variable("x"));
let expr = Expression::add(
Expression::variable("x"),
Expression::Number(Number::zero())
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::variable("x"));
let expr = Expression::multiply(
Expression::Number(Number::one()),
Expression::variable("x")
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::variable("x"));
let expr = Expression::multiply(
Expression::variable("x"),
Expression::Number(Number::one())
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::variable("x"));
let expr = Expression::multiply(
Expression::Number(Number::zero()),
Expression::variable("x")
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::Number(Number::zero()));
}
#[test]
fn test_constant_folding() {
let mut simplifier = create_simplifier();
let expr = Expression::add(
Expression::Number(Number::integer(2)),
Expression::Number(Number::integer(3))
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::Number(Number::integer(5)));
let expr = Expression::subtract(
Expression::Number(Number::integer(5)),
Expression::Number(Number::integer(2))
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::Number(Number::integer(3)));
let expr = Expression::multiply(
Expression::Number(Number::integer(3)),
Expression::Number(Number::integer(4))
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::Number(Number::integer(12)));
let expr = Expression::divide(
Expression::Number(Number::integer(8)),
Expression::Number(Number::integer(2))
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::Number(Number::integer(4)));
}
#[test]
fn test_like_terms_combination() {
let mut simplifier = create_simplifier();
let expr = Expression::add(
Expression::variable("x"),
Expression::variable("x")
);
let result = simplifier.simplify(&expr).unwrap();
let expected = Expression::multiply(
Expression::Number(Number::integer(2)),
Expression::variable("x")
);
assert_eq!(result, expected);
let expr = Expression::add(
Expression::multiply(
Expression::Number(Number::integer(2)),
Expression::variable("x")
),
Expression::multiply(
Expression::Number(Number::integer(3)),
Expression::variable("x")
)
);
let result = simplifier.simplify(&expr).unwrap();
let expected = Expression::multiply(
Expression::Number(Number::integer(5)),
Expression::variable("x")
);
assert_eq!(result, expected);
let expr = Expression::subtract(
Expression::multiply(
Expression::Number(Number::integer(5)),
Expression::variable("x")
),
Expression::multiply(
Expression::Number(Number::integer(2)),
Expression::variable("x")
)
);
let result = simplifier.simplify(&expr).unwrap();
let expected = Expression::multiply(
Expression::Number(Number::integer(3)),
Expression::variable("x")
);
assert_eq!(result, expected);
}
#[test]
fn test_power_simplification() {
let mut simplifier = create_simplifier();
let expr = Expression::power(
Expression::variable("x"),
Expression::Number(Number::zero())
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::Number(Number::one()));
let expr = Expression::power(
Expression::variable("x"),
Expression::Number(Number::one())
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::variable("x"));
let expr = Expression::power(
Expression::Number(Number::one()),
Expression::variable("x")
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::Number(Number::one()));
let expr = Expression::power(
Expression::Number(Number::integer(2)),
Expression::Number(Number::integer(3))
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::Number(Number::integer(8)));
}
#[test]
fn test_negation_simplification() {
let mut simplifier = create_simplifier();
let expr = Expression::negate(
Expression::negate(Expression::variable("x"))
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::variable("x"));
let expr = Expression::negate(
Expression::add(
Expression::variable("a"),
Expression::variable("b")
)
);
let result = simplifier.simplify(&expr).unwrap();
let expected = Expression::subtract(
Expression::negate(Expression::variable("a")),
Expression::variable("b")
);
assert_eq!(result, expected);
let expr = Expression::negate(
Expression::subtract(
Expression::variable("a"),
Expression::variable("b")
)
);
let result = simplifier.simplify(&expr).unwrap();
let expected = Expression::subtract(
Expression::variable("b"),
Expression::variable("a")
);
assert_eq!(result, expected);
}
#[test]
fn test_absolute_value_simplification() {
let mut simplifier = create_simplifier();
let expr = Expression::abs(Expression::Number(Number::integer(5)));
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::Number(Number::integer(5)));
let expr = Expression::abs(Expression::Number(Number::integer(-3)));
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::Number(Number::integer(3)));
let expr = Expression::abs(
Expression::negate(Expression::variable("x"))
);
let result = simplifier.simplify(&expr).unwrap();
let expected = Expression::abs(Expression::variable("x"));
assert_eq!(result, expected);
}
#[test]
fn test_division_simplification() {
let mut simplifier = create_simplifier();
let expr = Expression::divide(
Expression::variable("x"),
Expression::Number(Number::one())
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::variable("x"));
let expr = Expression::divide(
Expression::variable("x"),
Expression::variable("x")
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::Number(Number::one()));
let expr = Expression::divide(
Expression::Number(Number::zero()),
Expression::variable("x")
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::Number(Number::zero()));
let expr = Expression::divide(
Expression::variable("x"),
Expression::Number(Number::integer(-1))
);
let result = simplifier.simplify(&expr).unwrap();
let expected = Expression::negate(Expression::variable("x"));
assert_eq!(result, expected);
}
#[test]
fn test_power_combination() {
let mut simplifier = create_simplifier();
let expr = Expression::multiply(
Expression::variable("x"),
Expression::variable("x")
);
let result = simplifier.simplify(&expr).unwrap();
let expected = Expression::power(
Expression::variable("x"),
Expression::Number(Number::integer(2))
);
assert_eq!(result, expected);
let expr = Expression::multiply(
Expression::power(
Expression::variable("x"),
Expression::Number(Number::integer(2))
),
Expression::power(
Expression::variable("x"),
Expression::Number(Number::integer(3))
)
);
let result = simplifier.simplify(&expr).unwrap();
let expected = Expression::power(
Expression::variable("x"),
Expression::Number(Number::integer(5))
);
assert_eq!(result, expected);
let expr = Expression::divide(
Expression::power(
Expression::variable("x"),
Expression::Number(Number::integer(5))
),
Expression::power(
Expression::variable("x"),
Expression::Number(Number::integer(2))
)
);
let result = simplifier.simplify(&expr).unwrap();
let expected = Expression::power(
Expression::variable("x"),
Expression::Number(Number::integer(3))
);
assert_eq!(result, expected);
}
#[test]
fn test_complex_expression_simplification() {
let mut simplifier = create_simplifier();
let expr = Expression::add(
Expression::multiply(
Expression::add(
Expression::variable("x"),
Expression::Number(Number::zero())
),
Expression::Number(Number::one())
),
Expression::Number(Number::zero())
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::variable("x"));
let expr = Expression::multiply(
Expression::Number(Number::integer(2)),
Expression::add(
Expression::Number(Number::integer(3)),
Expression::Number(Number::integer(4))
)
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::Number(Number::integer(14)));
}
#[test]
fn test_canonical_form() {
let mut simplifier = create_simplifier();
let expr = Expression::add(
Expression::variable("x"),
Expression::Number(Number::integer(2))
);
let result = simplifier.simplify(&expr).unwrap();
let expected = Expression::add(
Expression::Number(Number::integer(2)),
Expression::variable("x")
);
assert_eq!(result, expected);
let expr = Expression::multiply(
Expression::variable("x"),
Expression::Number(Number::integer(3))
);
let result = simplifier.simplify(&expr).unwrap();
let expected = Expression::multiply(
Expression::Number(Number::integer(3)),
Expression::variable("x")
);
assert_eq!(result, expected);
}
#[test]
fn test_mathematical_constants() {
let mut simplifier = create_simplifier();
let expr = Expression::add(
Expression::constant(MathConstant::Pi),
Expression::Number(Number::zero())
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::constant(MathConstant::Pi));
let expr = Expression::multiply(
Expression::constant(MathConstant::E),
Expression::Number(Number::one())
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::constant(MathConstant::E));
let expr = Expression::multiply(
Expression::constant(MathConstant::I),
Expression::constant(MathConstant::I)
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::Number(Number::integer(-1)));
}
#[test]
fn test_edge_cases() {
let mut simplifier = create_simplifier();
let expr = Expression::subtract(
Expression::variable("x"),
Expression::variable("x")
);
let result = simplifier.simplify(&expr).unwrap();
assert_eq!(result, Expression::Number(Number::zero()));
let expr = Expression::multiply(
Expression::Number(Number::integer(-1)),
Expression::variable("x")
);
let result = simplifier.simplify(&expr).unwrap();
let expected = Expression::negate(Expression::variable("x"));
assert_eq!(result, expected);
let expr = Expression::power(
Expression::power(
Expression::variable("x"),
Expression::Number(Number::integer(2))
),
Expression::Number(Number::integer(3))
);
let result = simplifier.simplify(&expr).unwrap();
let expected = Expression::power(
Expression::variable("x"),
Expression::Number(Number::integer(6))
);
assert_eq!(result, expected);
}
}