use mathhook_core::prelude::*;
#[test]
fn test_derivative_basic_rules() {
let power_expr = expr!(x ^ 3);
let simplified = power_expr.simplify();
assert!(
matches!(simplified, Expression::Pow(_, _)),
"Expected x^3 to remain as power, got: {}",
simplified
);
}
#[test]
fn test_derivative_product_rule_pattern() {
let u = expr!(u);
let v = expr!(v);
let u_prime = expr!(u_prime);
let v_prime = expr!(v_prime);
let product_rule = Expression::add(vec![
Expression::mul(vec![u_prime, v.clone()]),
Expression::mul(vec![u, v_prime]),
]);
let simplified = product_rule.simplify();
assert!(
matches!(simplified, Expression::Add(_)),
"Expected product rule (u'v + uv') to remain as addition, got: {}",
simplified
);
}
#[test]
fn test_derivative_chain_rule_pattern() {
let f_prime = expr!(f_prime);
let g_prime = expr!(g_prime);
let chain_rule = Expression::mul(vec![f_prime, g_prime]);
let simplified = chain_rule.simplify();
assert!(
matches!(simplified, Expression::Mul(_) | Expression::Symbol(_)),
"Expected chain rule (f'(g) * g') to be multiplication or symbol, got: {}",
simplified
);
}
#[test]
fn test_integral_basic_patterns() {
let x = expr!(x);
let power_integral_pattern = Expression::mul(vec![
Expression::pow(x.clone(), Expression::integer(4)),
Expression::pow(Expression::integer(4), Expression::integer(-1)),
]);
let simplified = power_integral_pattern.simplify();
println!("Integral pattern: {}", simplified);
assert!(!simplified.is_zero());
}
#[test]
fn test_limit_basic_patterns() {
let x = expr!(x);
let h = expr!(h);
let difference_quotient_numerator = Expression::add(vec![
Expression::mul(vec![Expression::integer(2), x, h.clone()]),
Expression::pow(h, Expression::integer(2)),
]);
let simplified = difference_quotient_numerator.simplify();
assert!(
matches!(simplified, Expression::Add(_)),
"Expected difference quotient (2xh + h^2) to remain as addition, got: {}",
simplified
);
}
#[test]
fn test_series_expansion_patterns() {
let x = expr!(x);
let taylor_terms = Expression::add(vec![
Expression::integer(1),
x.clone(),
Expression::mul(vec![
Expression::pow(x.clone(), Expression::integer(2)),
Expression::pow(Expression::integer(2), Expression::integer(-1)),
]),
Expression::mul(vec![
Expression::pow(x, Expression::integer(3)),
Expression::pow(Expression::integer(6), Expression::integer(-1)),
]),
]);
let simplified = taylor_terms.simplify();
assert!(
matches!(simplified, Expression::Add(_)),
"Expected Taylor series to remain as addition, got: {}",
simplified
);
}
#[test]
fn test_partial_derivative_patterns() {
let x = expr!(x);
let y = expr!(y);
let mixed_partial = Expression::add(vec![
Expression::mul(vec![Expression::integer(2), x.clone(), y.clone()]),
Expression::mul(vec![Expression::integer(2), x, y]),
]);
let simplified = mixed_partial.simplify();
if matches!(simplified, Expression::Mul(_)) {
println!("Combined partial: {}", simplified);
} else {
println!("Partial derivative: {}", simplified);
}
assert!(
matches!(simplified, Expression::Mul(_) | Expression::Add(_)),
"Expected partial derivative to be multiplication or addition, got: {}",
simplified
);
}
#[test]
fn test_integration_by_parts_pattern() {
let u = expr!(u);
let v = expr!(v);
let du = expr!(du);
let integration_by_parts = Expression::add(vec![
Expression::mul(vec![u, v.clone()]),
Expression::mul(vec![Expression::integer(-1), Expression::mul(vec![v, du])]),
]);
let simplified = integration_by_parts.simplify();
assert!(
matches!(simplified, Expression::Add(_)),
"Expected integration by parts (uv - ∫v du) to remain as addition, got: {}",
simplified
);
}
#[test]
fn test_multivariable_calculus_patterns() {
let x = expr!(x);
let y = expr!(y);
let z = expr!(z);
let gradient_x = Expression::add(vec![
Expression::mul(vec![Expression::integer(2), x.clone(), y.clone()]),
z.clone(),
]);
let gradient_y = Expression::add(vec![
Expression::pow(x.clone(), Expression::integer(2)),
Expression::pow(z.clone(), Expression::integer(2)),
]);
let gradient_z = Expression::add(vec![
Expression::mul(vec![Expression::integer(2), y, z.clone()]),
x,
]);
let grad_x_simplified = gradient_x.simplify();
let grad_y_simplified = gradient_y.simplify();
let grad_z_simplified = gradient_z.simplify();
assert!(!grad_x_simplified.is_zero());
assert!(!grad_y_simplified.is_zero());
assert!(!grad_z_simplified.is_zero());
}
#[test]
fn test_vector_calculus_operations() {
let fx = expr!(Fx);
let fy = expr!(Fy);
let fz = expr!(Fz);
let divergence = Expression::add(vec![fx, fy, fz]);
let simplified = divergence.simplify();
assert!(
matches!(simplified, Expression::Add(_)),
"Expected divergence (∇·F) to remain as addition, got: {}",
simplified
);
}
#[test]
fn test_differential_equation_patterns() {
let y = expr!(y);
let y_prime = expr!(y_prime);
let x = expr!(x);
let ode_pattern = Expression::add(vec![y_prime, Expression::mul(vec![x, y])]);
let simplified = ode_pattern.simplify();
assert!(
matches!(simplified, Expression::Add(_)),
"Expected ODE pattern (y' + p(x)y) to remain as addition, got: {}",
simplified
);
}