pub mod add;
pub mod distribute;
pub mod imaginary;
pub mod multiply;
pub mod power;
pub mod root;
pub mod trigonometry;
use crate::symbolic::step_collector::StepCollector;
use super::{SymExpr, Primary, step::Step};
pub(crate) fn do_call(
expr: &SymExpr,
name: &str,
f: impl Copy + Fn(&[SymExpr]) -> Option<SymExpr>,
) -> Option<SymExpr> {
if let SymExpr::Primary(Primary::Call(target_name, args)) = expr {
if target_name == name {
return f(args);
}
}
None
}
pub(crate) fn do_add(expr: &SymExpr, f: impl Copy + Fn(&[SymExpr]) -> Option<SymExpr>) -> Option<SymExpr> {
if let SymExpr::Add(terms) = expr {
f(terms)
} else {
None
}
}
pub(crate) fn do_multiply(expr: &SymExpr, f: impl Copy + Fn(&[SymExpr]) -> Option<SymExpr>) -> Option<SymExpr> {
if let SymExpr::Mul(factors) = expr {
f(factors)
} else {
None
}
}
pub(crate) fn do_power(expr: &SymExpr, f: impl Copy + Fn(&SymExpr, &SymExpr) -> Option<SymExpr>) -> Option<SymExpr> {
if let SymExpr::Exp(lhs, rhs) = expr {
f(lhs, rhs)
} else {
None
}
}
pub fn all(expr: &SymExpr, step_collector: &mut dyn StepCollector<Step>) -> Option<SymExpr> {
add::all(expr, step_collector)
.or_else(|| multiply::all(expr, step_collector))
.or_else(|| power::all(expr, step_collector))
.or_else(|| distribute::all(expr, step_collector))
.or_else(|| imaginary::all(expr, step_collector))
.or_else(|| trigonometry::all(expr, step_collector))
.or_else(|| root::all(expr, step_collector))
}