use mathhook_core::algebra::equation_analyzer::SmartEquationSolver;
use mathhook_core::algebra::solvers::SolverResult;
use mathhook_core::{symbol, Expression};
#[test]
fn test_left_division_through_smart_solver() {
let solver = SmartEquationSolver::new();
let a = symbol!(A; matrix);
let x = symbol!(X; matrix);
let b = symbol!(B; matrix);
let equation = Expression::add(vec![
Expression::mul(vec![
Expression::symbol(a.clone()),
Expression::symbol(x.clone()),
]),
Expression::mul(vec![Expression::integer(-1), Expression::symbol(b.clone())]),
]);
let (result, _explanation) = solver.solve_with_equation(&equation, &x);
match result {
SolverResult::Single(solution) => {
assert!(solution.to_string().contains("A"));
assert!(solution.to_string().contains("B"));
}
_ => panic!("Expected single solution for left division"),
}
}
#[test]
fn test_right_division_through_smart_solver() {
let solver = SmartEquationSolver::new();
let a = symbol!(A; matrix);
let x = symbol!(X; matrix);
let b = symbol!(B; matrix);
let equation = Expression::add(vec![
Expression::mul(vec![
Expression::symbol(x.clone()),
Expression::symbol(a.clone()),
]),
Expression::mul(vec![Expression::integer(-1), Expression::symbol(b.clone())]),
]);
let (result, _explanation) = solver.solve_with_equation(&equation, &x);
match result {
SolverResult::Single(solution) => {
assert!(solution.to_string().contains("A"));
assert!(solution.to_string().contains("B"));
}
_ => panic!("Expected single solution for right division"),
}
}
#[test]
fn test_operator_equation_through_smart_solver() {
let solver = SmartEquationSolver::new();
let h = symbol!(H; operator);
let psi = symbol!(psi; operator);
let e = symbol!(E; operator);
let equation = Expression::add(vec![
Expression::mul(vec![
Expression::symbol(h.clone()),
Expression::symbol(psi.clone()),
]),
Expression::mul(vec![
Expression::integer(-1),
Expression::mul(vec![
Expression::symbol(e.clone()),
Expression::symbol(psi.clone()),
]),
]),
]);
let (result, _explanation) = solver.solve_with_equation(&equation, &psi);
match result {
SolverResult::Single(_) | SolverResult::NoSolution => {
}
_ => {}
}
}
#[test]
fn test_scalar_equations_still_work() {
let solver = SmartEquationSolver::new();
let x = symbol!(x);
let equation = Expression::add(vec![
Expression::mul(vec![Expression::integer(2), Expression::symbol(x.clone())]),
Expression::integer(3),
]);
let (result, _explanation) = solver.solve_with_equation(&equation, &x);
match result {
SolverResult::Single(solution) => {
let simplified = solution.to_string();
assert!(simplified.contains("-3") || simplified.contains("3"));
}
_ => panic!("Expected single solution for linear equation"),
}
}
#[test]
fn test_matrix_equation_with_explanation() {
let solver = SmartEquationSolver::new();
let a = symbol!(A; matrix);
let x = symbol!(X; matrix);
let b = symbol!(B; matrix);
let equation = Expression::add(vec![
Expression::mul(vec![
Expression::symbol(a.clone()),
Expression::symbol(x.clone()),
]),
Expression::mul(vec![Expression::integer(-1), Expression::symbol(b.clone())]),
]);
let (result, explanation) = solver.solve_with_equation(&equation, &x);
assert!(matches!(result, SolverResult::Single(_)));
let explanation_text = format!("{:?}", explanation);
assert!(
explanation_text.contains("matrix") || explanation_text.contains("noncommutative"),
"Explanation should mention matrix/noncommutative symbols"
);
}
#[test]
fn test_mixed_matrix_scalar_equation() {
let solver = SmartEquationSolver::new();
let a = symbol!(A; matrix);
let x = symbol!(x);
let equation = Expression::add(vec![
Expression::mul(vec![
Expression::symbol(a.clone()),
Expression::symbol(x.clone()),
]),
Expression::integer(-1),
]);
let (_result, _explanation) = solver.solve_with_equation(&equation, &x);
}