1extern crate self as mathhook_core;
7
8pub mod algebra;
9pub mod calculus;
10pub mod core;
11pub mod educational;
12pub mod error;
13pub mod formatter;
14pub mod functions;
15pub mod macros;
16pub mod matrices;
17pub mod parser;
18pub mod pattern;
19pub mod serialize;
20pub mod simplify;
21pub mod solvers;
22
23pub use mathhook_macros::{expr, function, symbol, symbols};
27
28pub use core::expression::eval_numeric::{EvalContext, EvalNumeric};
30pub use core::{
31 Commutativity, Expression, MathConstant, Number, NumericMatrix, Symbol, SymbolType,
32};
33
34pub use algebra::{multivariate_gcd, polynomial_div, polynomial_quo, polynomial_rem};
36pub use algebra::{
37 AdvancedPolynomial, AdvancedSimplify, Collect, ComplexOperations, EquationAnalyzer,
38 EquationType, Expand, Factor, PolynomialGcd, RationalSimplify, SmartEquationSolver,
39 ZeroDetection,
40};
41
42pub use calculus::derivatives::Derivative;
44pub use calculus::{
45 BasicDerivatives, BasicIntegrals, ChainRule, ComplexAnalysis, FunctionIntegrals,
46 HigherOrderDerivatives, Integration, IntegrationMethods, LimitDirection, Limits, PowerRule,
47 ProductRule, ResidueCalculus, SeriesExpansion, SeriesType, Summation, SummationMethods,
48};
49
50pub use solvers::{MathSolver, SolverConfig, SolverResult};
52
53pub use pattern::{Matchable, Pattern, PatternMatches, Substitutable};
55
56pub use parser::config::ParserConfig;
58pub use parser::error::ParseError;
59pub use parser::Parser;
60
61pub use error::MathError;
63
64pub use formatter::{LaTeXFormatter, MathLanguage, SimpleFormatter, WolframFormatter};
66
67pub use functions::elementary;
69pub use functions::polynomials;
70pub use functions::special;
71
72pub use simplify::Simplify;
74
75pub mod prelude {
80 pub use crate::macros::*;
81 pub use crate::{expr, function, symbol, symbols};
82
83 pub use crate::{
85 Commutativity, Expression, MathConstant, Number, NumericMatrix, Symbol, SymbolType,
86 };
87
88 pub use crate::{
90 AdvancedPolynomial, AdvancedSimplify, Collect, ComplexOperations, EquationAnalyzer,
91 EquationType, Expand, Factor, PolynomialGcd, RationalSimplify, Simplify,
92 SmartEquationSolver, ZeroDetection,
93 };
94
95 pub use crate::{multivariate_gcd, polynomial_div, polynomial_quo, polynomial_rem};
97
98 pub use crate::Derivative;
100 pub use crate::{
101 BasicDerivatives, BasicIntegrals, ChainRule, ComplexAnalysis, FunctionIntegrals,
102 HigherOrderDerivatives, Integration, IntegrationMethods, LimitDirection, Limits, PowerRule,
103 ProductRule, ResidueCalculus, SeriesExpansion, SeriesType, Summation, SummationMethods,
104 };
105
106 pub use crate::{Matchable, Pattern, PatternMatches, Substitutable};
108
109 pub use crate::educational::{
111 DifficultyLevel, EducationalExt, EducationalOperation, EducationalResult, EnhancedStep,
112 EnhancedStepExplanation, OperationContext, Step, StepByStep, StepByStepExplanation,
113 };
114
115 pub use crate::matrices::{
117 CoreMatrixOps, EigenOperations, Matrix, MatrixDecomposition, MatrixOperations,
118 };
119
120 pub use crate::{MathSolver, SolverConfig, SolverResult};
122
123 pub use crate::{Parser, ParserConfig};
125
126 pub use crate::{MathError, ParseError};
128
129 pub use crate::{LaTeXFormatter, MathLanguage, SimpleFormatter, WolframFormatter};
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136
137 #[test]
138 fn test_expression_memory_optimization() {
139 let expression_size = std::mem::size_of::<Expression>();
140 println!("Clean Expression size: {} bytes", expression_size);
141
142 assert!(
143 expression_size <= 32,
144 "Expression should be ≤ 32 bytes, got {} bytes",
145 expression_size
146 );
147 }
148
149 #[test]
150 fn test_hybrid_api_basic_operations() {
151 let expr = Expression::add(vec![Expression::integer(2), Expression::integer(3)]);
152 let simplified = expr.simplify();
153
154 match simplified {
155 Expression::Number(num) => {
156 if let Number::Integer(i) = num {
157 assert_eq!(i, 5);
158 } else {
159 panic!("Expected integer result");
160 }
161 }
162 _ => panic!("Expected number result"),
163 }
164 }
165
166 #[test]
167 fn test_solver_object_api() {
168 let solver = MathSolver::new();
169
170 let equation = Expression::equation(expr!(x), expr!(42));
171
172 let result = solver.solve(&equation, &symbol!(x));
173
174 match result {
175 SolverResult::Single(solution) => match solution {
176 Expression::Number(num) => {
177 if let Number::Integer(i) = num {
178 assert_eq!(i, 42);
179 } else {
180 panic!("Expected integer solution");
181 }
182 }
183 _ => panic!("Expected number solution"),
184 },
185 _ => panic!("Expected single solution"),
186 }
187 }
188
189 #[test]
190 fn test_hot_path_performance() {
191 let start = std::time::Instant::now();
192
193 for _ in 0..10000 {
194 let expr = expr!(1 + x + 2);
195 let _simplified = expr.simplify();
196 }
197
198 let duration = start.elapsed();
199 println!("10K hot-path operations took: {:?}", duration);
200
201 assert!(
202 duration.as_millis() < 100,
203 "Hot path too slow: {:?}",
204 duration
205 );
206 }
207
208 #[test]
209 #[allow(non_snake_case)]
210 fn test_procedural_symbol_macro() {
211 let x = symbol!(x);
212 assert_eq!(x.name(), "x");
213 assert_eq!(x.commutativity(), Commutativity::Commutative);
214
215 let A = symbol!(A; matrix);
216 assert_eq!(A.name(), "A");
217 assert_eq!(A.commutativity(), Commutativity::Noncommutative);
218
219 let p = symbol!(p; operator);
220 assert_eq!(p.name(), "p");
221 assert_eq!(p.commutativity(), Commutativity::Noncommutative);
222
223 let i = symbol!(i; quaternion);
224 assert_eq!(i.name(), "i");
225 assert_eq!(i.commutativity(), Commutativity::Noncommutative);
226
227 let syms = symbols![x, y, z];
228 assert_eq!(syms.len(), 3);
229 assert_eq!(syms[0].name(), "x");
230 assert_eq!(syms[1].name(), "y");
231 assert_eq!(syms[2].name(), "z");
232 assert_eq!(syms[0].commutativity(), Commutativity::Commutative);
233
234 let mats = symbols![A, B => matrix];
235 assert_eq!(mats.len(), 2);
236 assert_eq!(mats[0].name(), "A");
237 assert_eq!(mats[1].name(), "B");
238 assert_eq!(mats[0].commutativity(), Commutativity::Noncommutative);
239 }
240
241 #[test]
242 fn test_procedural_function_macro() {
243 let gamma_call = function!(gamma);
244 if let Expression::Function { name, args } = &gamma_call {
245 assert_eq!(name.as_ref(), "gamma");
246 assert_eq!(args.len(), 0);
247 } else {
248 panic!("Expected Function expression");
249 }
250
251 let x = expr!(x);
252 let sin_x = function!(sin, x.clone());
253 if let Expression::Function { name, args } = &sin_x {
254 assert_eq!(name.as_ref(), "sin");
255 assert_eq!(args.len(), 1);
256 } else {
257 panic!("Expected Function expression");
258 }
259
260 let y = expr!(y);
261 let log_xy = function!(log, x, y);
262 if let Expression::Function { name, args } = &log_xy {
263 assert_eq!(name.as_ref(), "log");
264 assert_eq!(args.len(), 2);
265 } else {
266 panic!("Expected Function expression");
267 }
268 }
269}