extern crate self as mathhook_core;
pub mod algebra;
pub mod calculus;
pub mod core;
pub mod educational;
pub mod error;
pub mod formatter;
pub mod functions;
pub mod macros;
pub mod matrices;
pub mod parser;
pub mod pattern;
pub mod serialize;
pub mod simplify;
pub mod solvers;
pub use mathhook_macros::{expr, function, symbol, symbols};
pub use core::expression::eval_numeric::{EvalContext, EvalNumeric};
pub use core::{
Commutativity, Expression, MathConstant, Number, NumericMatrix, Symbol, SymbolType,
};
pub use algebra::{multivariate_gcd, polynomial_div, polynomial_quo, polynomial_rem};
pub use algebra::{
AdvancedPolynomial, AdvancedSimplify, Collect, ComplexOperations, EquationAnalyzer,
EquationType, Expand, Factor, PolynomialGcd, RationalSimplify, SmartEquationSolver,
ZeroDetection,
};
pub use calculus::derivatives::Derivative;
pub use calculus::{
BasicDerivatives, BasicIntegrals, ChainRule, ComplexAnalysis, FunctionIntegrals,
HigherOrderDerivatives, Integration, IntegrationMethods, LimitDirection, Limits, PowerRule,
ProductRule, ResidueCalculus, SeriesExpansion, SeriesType, Summation, SummationMethods,
};
pub use solvers::{MathSolver, SolverConfig, SolverResult};
pub use pattern::{Matchable, Pattern, PatternMatches, Substitutable};
pub use parser::config::ParserConfig;
pub use parser::error::ParseError;
pub use parser::Parser;
pub use error::MathError;
pub use formatter::{LaTeXFormatter, MathLanguage, SimpleFormatter, WolframFormatter};
pub use functions::elementary;
pub use functions::polynomials;
pub use functions::special;
pub use simplify::Simplify;
pub mod prelude {
pub use crate::macros::*;
pub use crate::{expr, function, symbol, symbols};
pub use crate::{
Commutativity, Expression, MathConstant, Number, NumericMatrix, Symbol, SymbolType,
};
pub use crate::{
AdvancedPolynomial, AdvancedSimplify, Collect, ComplexOperations, EquationAnalyzer,
EquationType, Expand, Factor, PolynomialGcd, RationalSimplify, Simplify,
SmartEquationSolver, ZeroDetection,
};
pub use crate::{multivariate_gcd, polynomial_div, polynomial_quo, polynomial_rem};
pub use crate::Derivative;
pub use crate::{
BasicDerivatives, BasicIntegrals, ChainRule, ComplexAnalysis, FunctionIntegrals,
HigherOrderDerivatives, Integration, IntegrationMethods, LimitDirection, Limits, PowerRule,
ProductRule, ResidueCalculus, SeriesExpansion, SeriesType, Summation, SummationMethods,
};
pub use crate::{Matchable, Pattern, PatternMatches, Substitutable};
pub use crate::educational::{
DifficultyLevel, EducationalExt, EducationalOperation, EducationalResult, EnhancedStep,
EnhancedStepExplanation, OperationContext, Step, StepByStep, StepByStepExplanation,
};
pub use crate::matrices::{
CoreMatrixOps, EigenOperations, Matrix, MatrixDecomposition, MatrixOperations,
};
pub use crate::{MathSolver, SolverConfig, SolverResult};
pub use crate::{Parser, ParserConfig};
pub use crate::{MathError, ParseError};
pub use crate::{LaTeXFormatter, MathLanguage, SimpleFormatter, WolframFormatter};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_expression_memory_optimization() {
let expression_size = std::mem::size_of::<Expression>();
println!("Clean Expression size: {} bytes", expression_size);
assert!(
expression_size <= 32,
"Expression should be ≤ 32 bytes, got {} bytes",
expression_size
);
}
#[test]
fn test_hybrid_api_basic_operations() {
let expr = Expression::add(vec![Expression::integer(2), Expression::integer(3)]);
let simplified = expr.simplify();
match simplified {
Expression::Number(num) => {
if let Number::Integer(i) = num {
assert_eq!(i, 5);
} else {
panic!("Expected integer result");
}
}
_ => panic!("Expected number result"),
}
}
#[test]
fn test_solver_object_api() {
let solver = MathSolver::new();
let equation = Expression::equation(expr!(x), expr!(42));
let result = solver.solve(&equation, &symbol!(x));
match result {
SolverResult::Single(solution) => match solution {
Expression::Number(num) => {
if let Number::Integer(i) = num {
assert_eq!(i, 42);
} else {
panic!("Expected integer solution");
}
}
_ => panic!("Expected number solution"),
},
_ => panic!("Expected single solution"),
}
}
#[test]
fn test_hot_path_performance() {
let start = std::time::Instant::now();
for _ in 0..10000 {
let expr = expr!(1 + x + 2);
let _simplified = expr.simplify();
}
let duration = start.elapsed();
println!("10K hot-path operations took: {:?}", duration);
assert!(
duration.as_millis() < 100,
"Hot path too slow: {:?}",
duration
);
}
#[test]
#[allow(non_snake_case)]
fn test_procedural_symbol_macro() {
let x = symbol!(x);
assert_eq!(x.name(), "x");
assert_eq!(x.commutativity(), Commutativity::Commutative);
let A = symbol!(A; matrix);
assert_eq!(A.name(), "A");
assert_eq!(A.commutativity(), Commutativity::Noncommutative);
let p = symbol!(p; operator);
assert_eq!(p.name(), "p");
assert_eq!(p.commutativity(), Commutativity::Noncommutative);
let i = symbol!(i; quaternion);
assert_eq!(i.name(), "i");
assert_eq!(i.commutativity(), Commutativity::Noncommutative);
let syms = symbols![x, y, z];
assert_eq!(syms.len(), 3);
assert_eq!(syms[0].name(), "x");
assert_eq!(syms[1].name(), "y");
assert_eq!(syms[2].name(), "z");
assert_eq!(syms[0].commutativity(), Commutativity::Commutative);
let mats = symbols![A, B => matrix];
assert_eq!(mats.len(), 2);
assert_eq!(mats[0].name(), "A");
assert_eq!(mats[1].name(), "B");
assert_eq!(mats[0].commutativity(), Commutativity::Noncommutative);
}
#[test]
fn test_procedural_function_macro() {
let gamma_call = function!(gamma);
if let Expression::Function { name, args } = &gamma_call {
assert_eq!(name.as_ref(), "gamma");
assert_eq!(args.len(), 0);
} else {
panic!("Expected Function expression");
}
let x = expr!(x);
let sin_x = function!(sin, x.clone());
if let Expression::Function { name, args } = &sin_x {
assert_eq!(name.as_ref(), "sin");
assert_eq!(args.len(), 1);
} else {
panic!("Expected Function expression");
}
let y = expr!(y);
let log_xy = function!(log, x, y);
if let Expression::Function { name, args } = &log_xy {
assert_eq!(name.as_ref(), "log");
assert_eq!(args.len(), 2);
} else {
panic!("Expected Function expression");
}
}
}