use mathhook_core::core::expression::evaluation::dispatch::evaluate_function_dispatch;
use mathhook_core::core::expression::Expression;
use mathhook_core::core::symbol::Symbol;
use mathhook_core::expr;
use mathhook_core::functions::elementary::abs_eval::abs;
use mathhook_core::functions::elementary::exp_eval::exp;
use mathhook_core::functions::elementary::log_eval::ln;
use mathhook_core::functions::elementary::sqrt_eval::sqrt;
use mathhook_core::functions::elementary::trigonometric::{cos, sin};
use mathhook_core::functions::special::gamma::gamma;
use mathhook_core::simplify::Simplify;
#[test]
fn test_direct_function_call_sin_zero() {
let result = sin(&Expression::integer(0));
assert_eq!(result, Expression::integer(0));
}
#[test]
fn test_direct_function_call_cos_zero() {
let result = cos(&Expression::integer(0));
assert_eq!(result, Expression::integer(1));
}
#[test]
fn test_direct_function_call_exp_zero() {
let result = exp(&Expression::integer(0));
assert_eq!(result, Expression::integer(1));
}
#[test]
fn test_direct_function_call_ln_one() {
let result = ln(&Expression::integer(1));
assert_eq!(result, Expression::integer(0));
}
#[test]
fn test_direct_function_call_sqrt_four() {
let result = sqrt(&Expression::integer(4));
assert_eq!(result, Expression::integer(2));
}
#[test]
fn test_direct_function_call_gamma_five() {
let result = gamma(&Expression::integer(5));
assert_eq!(result, Expression::integer(24));
}
#[test]
fn test_nested_function_composition_symbolic() {
let x = Symbol::scalar("x");
let nested = Expression::function(
"sin",
vec![Expression::function(
"cos",
vec![Expression::symbol(x.clone())],
)],
);
let result = nested.simplify();
assert!(result.to_string().contains("sin"));
assert!(result.to_string().contains("cos"));
}
#[test]
fn test_identity_simplification_exp_log() {
let expr = Expression::function("exp", vec![Expression::function("log", vec![expr!(x)])]);
let result = expr.simplify();
assert_eq!(result, expr!(x));
}
#[test]
fn test_direct_dispatch_works() {
let result = evaluate_function_dispatch("sin", &[Expression::integer(0)]);
assert!(result.is_some());
assert_eq!(result.unwrap(), Expression::integer(0));
let result = evaluate_function_dispatch("gamma", &[Expression::integer(5)]);
assert!(result.is_some());
assert_eq!(result.unwrap(), Expression::integer(24));
}
#[test]
fn test_function_in_addition_symbolic() {
let x = Symbol::scalar("x");
let expr = Expression::add(vec![
Expression::function("sin", vec![Expression::symbol(x.clone())]),
Expression::integer(3),
]);
let result = expr.simplify();
assert!(result.to_string().contains("sin"));
assert!(result.to_string().contains("3"));
}
#[test]
fn test_abs_evaluation_direct() {
let expr = Expression::mul(vec![Expression::integer(-1), Expression::integer(5)]);
let result = abs(&expr);
assert_eq!(result, Expression::integer(5));
}
#[test]
fn test_composite_expression_mixed_evaluation() {
let x = Symbol::scalar("x");
let y = Symbol::scalar("y");
let composite = Expression::add(vec![
Expression::mul(vec![
Expression::function(
"sin",
vec![Expression::add(vec![
Expression::pow(Expression::symbol(x.clone()), Expression::integer(2)),
Expression::integer(1),
])],
),
Expression::function("cos", vec![Expression::symbol(y.clone())]),
]),
Expression::mul(vec![
Expression::integer(-1),
Expression::function("sqrt", vec![Expression::integer(4)]),
]),
]);
let result = composite.simplify();
assert!(result.to_string().contains("sin"));
assert!(result.to_string().contains("cos"));
assert!(!result.to_string().contains("sqrt"));
assert!(result.to_string().contains("2"));
}
#[test]
fn test_evaluation_propagation_in_multiplication() {
let x = Symbol::scalar("x");
let expr = Expression::mul(vec![
Expression::integer(2),
Expression::function("sin", vec![Expression::integer(0)]),
Expression::function("exp", vec![Expression::symbol(x.clone())]),
Expression::function("sqrt", vec![Expression::integer(16)]),
]);
let result = expr.simplify();
assert_eq!(result, Expression::integer(0));
}
#[test]
fn test_special_values_in_nested_expressions() {
let expr = Expression::add(vec![
Expression::mul(vec![
Expression::function(
"sin",
vec![Expression::div(Expression::pi(), Expression::integer(2))],
),
Expression::function("cos", vec![Expression::integer(0)]),
]),
Expression::function("sqrt", vec![Expression::integer(9)]),
]);
let result = expr.simplify();
assert_eq!(result, Expression::integer(4));
}
#[test]
fn test_partial_evaluation_preserves_symbolic() {
let x = Symbol::scalar("x");
let y = Symbol::scalar("y");
let expr = Expression::add(vec![
Expression::function("sin", vec![Expression::symbol(x.clone())]),
Expression::function("cos", vec![Expression::symbol(y.clone())]),
Expression::function("sqrt", vec![Expression::integer(4)]),
]);
let result = expr.simplify();
assert!(result.to_string().contains("sin"));
assert!(result.to_string().contains("cos"));
assert!(!result.to_string().contains("sqrt"));
}
#[test]
fn test_gamma_function_evaluation_through_expression() {
let expr = Expression::function("gamma", vec![Expression::integer(5)]);
let result = expr.simplify();
assert_eq!(result, Expression::integer(24));
}
#[test]
fn test_multiple_special_values() {
let expr = Expression::add(vec![
Expression::function("sin", vec![Expression::integer(0)]),
Expression::function("cos", vec![Expression::integer(0)]),
Expression::function("exp", vec![Expression::integer(0)]),
Expression::function("log", vec![Expression::integer(1)]),
]);
let result = expr.simplify();
assert_eq!(result, Expression::integer(2));
}
#[test]
fn test_nested_sqrt_evaluation() {
let expr = Expression::function(
"sqrt",
vec![Expression::function("sqrt", vec![Expression::integer(16)])],
);
let result = expr.simplify();
assert_eq!(result, Expression::integer(2));
}
#[test]
fn test_function_in_subtraction() {
let x = Symbol::scalar("x");
let expr = Expression::add(vec![
Expression::function("cos", vec![Expression::symbol(x.clone())]),
Expression::mul(vec![
Expression::integer(-1),
Expression::function("sqrt", vec![Expression::integer(9)]),
]),
]);
let result = expr.simplify();
assert!(result.to_string().contains("cos"));
assert!(result.to_string().contains("3"));
assert!(!result.to_string().contains("sqrt"));
}
#[test]
fn test_composite_with_powers() {
let x = Symbol::scalar("x");
let expr = Expression::mul(vec![
Expression::function(
"sin",
vec![Expression::pow(
Expression::symbol(x.clone()),
Expression::integer(2),
)],
),
Expression::function("sqrt", vec![Expression::integer(4)]),
]);
let result = expr.simplify();
assert!(result.to_string().contains("sin"));
assert!(result.to_string().contains("2"));
assert!(!result.to_string().contains("sqrt"));
}
#[test]
fn test_symbolic_preservation_in_complex_expr() {
let x = Symbol::scalar("x");
let y = Symbol::scalar("y");
let expr = Expression::add(vec![
Expression::mul(vec![
Expression::add(vec![
Expression::function("sin", vec![Expression::symbol(x.clone())]),
Expression::function("cos", vec![Expression::symbol(y.clone())]),
]),
Expression::function("sqrt", vec![Expression::integer(4)]),
]),
Expression::mul(vec![
Expression::integer(-1),
Expression::function("exp", vec![Expression::integer(0)]),
]),
]);
let result = expr.simplify();
assert!(result.to_string().contains("sin"));
assert!(result.to_string().contains("cos"));
assert!(!result.to_string().contains("sqrt"));
assert!(!result.to_string().contains("exp"));
}
#[test]
fn test_evaluation_flow_numeric_propagation() {
let expr = Expression::mul(vec![
Expression::add(vec![Expression::integer(2), Expression::integer(3)]),
Expression::function("sin", vec![Expression::integer(0)]),
]);
let result = expr.simplify();
assert_eq!(result, Expression::integer(0));
}
#[test]
fn test_function_composition_with_constants() {
let expr = Expression::function(
"sin",
vec![Expression::function("cos", vec![Expression::integer(0)])],
);
let result = expr.simplify();
assert!(result.to_string().contains("sin"));
assert!(result.to_string().contains("1"));
}
#[test]
fn test_evaluation_dispatch_current_state() {
assert_eq!(sin(&Expression::integer(0)), Expression::integer(0));
assert_eq!(exp(&Expression::integer(0)), Expression::integer(1));
assert_eq!(sqrt(&Expression::integer(4)), Expression::integer(2));
let sin_expr = Expression::function("sin", vec![Expression::integer(0)]);
let simplified = sin_expr.simplify();
assert_eq!(simplified, Expression::integer(0));
}
#[test]
fn test_partial_debug() {
use mathhook_core::core::symbol::Symbol;
use mathhook_core::core::Expression;
use mathhook_core::simplify::Simplify;
let x = Symbol::scalar("x");
let y = Symbol::scalar("y");
let expr = Expression::add(vec![
Expression::function("sin", vec![Expression::symbol(x.clone())]),
Expression::function("cos", vec![Expression::symbol(y.clone())]),
Expression::function("sqrt", vec![Expression::integer(4)]),
]);
let result = expr.simplify();
println!("Result: {:?}", result);
println!("String: {}", result);
println!("Contains 'sin': {}", result.to_string().contains("sin"));
println!("Contains 'cos': {}", result.to_string().contains("cos"));
println!("Contains 'sqrt': {}", result.to_string().contains("sqrt"));
}