mathhook-core 0.2.0

Core mathematical engine for MathHook - expressions, algebra, and solving
Documentation
//! Advanced function and special function tests

use mathhook_core::prelude::*;

#[test]
// ln(1) = 0
fn test_logarithm_simplification() {
    let expr = Expression::function("ln", vec![Expression::integer(1)]);
    let result = expr.simplify();

    println!("ln(1) = {}", result);

    match result {
        Expression::Number(Number::Integer(0)) => assert_eq!(0, 0),
        _ => println!("ln(1) result: {}", result),
    }
}

#[test]
// log(x) + log(y) = log(xy)
fn test_logcombine_1() {
    let x = symbol!(x);
    let y = symbol!(y);

    let expr = Expression::add(vec![
        Expression::function("log", vec![Expression::symbol(x.clone())]),
        Expression::function("log", vec![Expression::symbol(y.clone())]),
    ]);

    let result = expr.simplify();
    println!("log(x) + log(y) = {}", result);

    // Advanced logarithm combination not implemented yet
    assert!(!result.is_zero());
}

#[test]
// 5! = 120
fn test_factorial_simplify() {
    let expr = Expression::function("factorial", vec![Expression::integer(5)]);
    let result = expr.simplify();

    println!("5! = {}", result);

    match result {
        Expression::Number(Number::Integer(120)) => assert_eq!(120, 120),
        _ => println!("5! result: {}", result),
    }
}

#[test]
// numeric simplification
fn test_nsimplify() {
    let expr = Expression::number(Number::float(0.333333333));
    let result = expr.simplify();

    println!("0.333333333 simplified = {}", result);

    assert!(!result.is_zero());
}

#[test]
// complex expression simplification
fn test_simplify_expr() {
    let x = symbol!(x);

    let expr = Expression::add(vec![
        Expression::pow(Expression::symbol(x.clone()), Expression::integer(2)),
        Expression::mul(vec![
            Expression::integer(-1),
            Expression::pow(Expression::symbol(x.clone()), Expression::integer(2)),
        ]),
        Expression::symbol(x.clone()),
    ]);

    let result = expr.simplify();
    println!("x^2 - x^2 + x = {}", result);

    assert!(!result.is_zero());
}

#[test]
// sign simplification from SymPy
fn test_signsimp() {
    let x = symbol!(x);

    let expr = Expression::add(vec![
        Expression::integer(1),
        Expression::symbol(x.clone()),
        Expression::mul(vec![
            Expression::integer(-1),
            Expression::add(vec![Expression::integer(1), Expression::symbol(x.clone())]),
        ]),
    ]);

    let result = expr.simplify();

    // 1 + x + (-1)*(1 + x) = 1 + x - 1 - x = 0
    assert!(
        result.is_zero(),
        "Expected 0 from sign simplification, got: {}",
        result
    );
}

#[test]
// sqrt(4) = 2
fn test_special_function_patterns() {
    let expr = Expression::function("sqrt", vec![Expression::integer(4)]);
    let result = expr.simplify();

    println!("sqrt(4) = {}", result);

    // Test exp(0) = 1
    let expr = Expression::function("exp", vec![Expression::integer(0)]);
    let result = expr.simplify();

    println!("exp(0) = {}", result);

    // Test sin(0) = 0
    let expr = Expression::function("sin", vec![Expression::integer(0)]);
    let result = expr.simplify();

    println!("sin(0) = {}", result);

    // Should produce valid function result
    match result {
        Expression::Function { .. } | Expression::Number(_) => (),
        _ => panic!("Function evaluation should produce valid result"),
    }
}

#[test]
// ln(exp(x)) = x
fn test_advanced_function_combinations() {
    let x = symbol!(x);

    let expr = Expression::function(
        "ln",
        vec![Expression::function(
            "exp",
            vec![Expression::symbol(x.clone())],
        )],
    );

    let result = expr.simplify();
    println!("ln(exp(x)) = {}", result);

    match result {
        Expression::Symbol(s) if s.name() == "x" => assert_eq!(s.name(), "x"),
        _ => println!("ln(exp(x)) result: {}", result),
    }
}

#[test]
// combination of multiple function types
fn test_mathematical_function_mastery() {
    let x = symbol!(x);

    let expr = Expression::add(vec![
        Expression::function("sin", vec![Expression::integer(0)]),
        Expression::function("cos", vec![Expression::integer(0)]),
        Expression::function("factorial", vec![Expression::integer(3)]),
        Expression::symbol(x.clone()),
    ]);

    let result = expr.simplify();
    println!("sin(0) + cos(0) + 3! + x = {}", result);

    assert!(!result.is_zero());
}

#[test]
// Ultimate function test for 100% coverage
fn test_ultimate_100_percent_operation_3() {
    let x = symbol!(x);

    let expr = Expression::function(
        "sqrt",
        vec![Expression::add(vec![
            Expression::pow(Expression::symbol(x.clone()), Expression::integer(2)),
            Expression::mul(vec![Expression::integer(2), Expression::symbol(x.clone())]),
            Expression::integer(1),
        ])],
    );

    let result = expr.simplify();
    println!("sqrt(x^2 + 2x + 1) = {}", result);

    // This is sqrt((x + 1)^2) = |x + 1|
    assert!(!result.is_zero());
}