thales/
lib.rs

1//! # Thales - Computer Algebra System
2//!
3//! A comprehensive Computer Algebra System (CAS) library for symbolic mathematics,
4//! equation solving, calculus, and numerical methods. Named after
5//! [Thales of Miletus](https://en.wikipedia.org/wiki/Thales_of_Miletus),
6//! the first mathematician in the Greek tradition.
7//!
8//! ## Overview
9//!
10//! Thales provides:
11//! - **Symbolic equation solving** - Linear, quadratic, polynomial, transcendental, and systems
12//! - **Calculus** - Differentiation, integration, limits, Taylor series, first and second-order ODEs
13//! - **Numerical methods** - Newton-Raphson, bisection, Brent's method, Levenberg-Marquardt
14//! - **Coordinate systems** - 2D/3D transformations, complex numbers, De Moivre's theorem
15//! - **Units & dimensions** - Dimensional analysis and unit conversion
16//! - **Step-by-step solutions** - Resolution paths for educational applications
17//! - **iOS/macOS support** - FFI bindings via swift-bridge
18//!
19//! ## Key Features
20//!
21//! - Zero-cost abstractions with compile-time guarantees
22//! - Memory-safe implementation (no unsafe code except FFI boundary)
23//! - 970+ tests including property-based tests with proptest
24//! - Optimized for mobile targets (iOS)
25//! - Clear separation between symbolic and numerical methods
26//!
27//! # Quick Start
28//!
29//! ## Example 1: Coordinate Transformations
30//!
31//! Convert between Cartesian and polar coordinate systems:
32//!
33//! ```rust
34//! use thales::{Cartesian2D, Polar};
35//!
36//! // 2D Cartesian to Polar
37//! let cartesian = Cartesian2D::new(3.0, 4.0);
38//! let polar = cartesian.to_polar();
39//! assert!((polar.r - 5.0).abs() < 1e-10);
40//! assert!((polar.theta - 0.927295218).abs() < 1e-6);
41//!
42//! // Polar to Cartesian round-trip
43//! let back = polar.to_cartesian();
44//! assert!((back.x - 3.0).abs() < 1e-10);
45//! assert!((back.y - 4.0).abs() < 1e-10);
46//! ```
47//!
48//! ## Example 2: 3D Coordinate Transformations
49//!
50//! Convert between Cartesian and spherical coordinates:
51//!
52//! ```rust
53//! use thales::{Cartesian3D, Spherical};
54//!
55//! // Cartesian to Spherical
56//! let cart3d = Cartesian3D::new(1.0, 1.0, 1.0);
57//! let spherical = cart3d.to_spherical();
58//! assert!((spherical.r - 1.732050808).abs() < 1e-6);
59//!
60//! // Spherical to Cartesian round-trip
61//! let back = spherical.to_cartesian();
62//! assert!((back.x - 1.0).abs() < 1e-10);
63//! assert!((back.y - 1.0).abs() < 1e-10);
64//! assert!((back.z - 1.0).abs() < 1e-10);
65//! ```
66//!
67//! ## Example 3: Complex Number Operations
68//!
69//! Work with complex numbers and polar form:
70//!
71//! ```rust
72//! use thales::ComplexOps;
73//! use num_complex::Complex64;
74//!
75//! // De Moivre's theorem: (r∠θ)^n = r^n∠(nθ)
76//! let z = Complex64::new(1.0, 1.0);
77//! let result = ComplexOps::de_moivre(z, 2.0);
78//!
79//! // Complex conjugate (using num_complex methods)
80//! let conj = z.conj();
81//! assert_eq!(conj.re, z.re);
82//! assert_eq!(conj.im, -z.im);
83//!
84//! // Modulus (magnitude) of complex number
85//! let modulus = z.norm();
86//! assert!((modulus - 1.4142135623730951).abs() < 1e-10);
87//! ```
88//!
89//! ## Example 4: Expression and Variable Basics
90//!
91//! Build mathematical expressions using the AST:
92//!
93//! ```rust
94//! use thales::{Expression, Variable, BinaryOp};
95//!
96//! // Create expression: 2*x + 5
97//! let x = Variable::new("x");
98//! let two_x = Expression::Binary(
99//!     BinaryOp::Mul,
100//!     Box::new(Expression::Integer(2)),
101//!     Box::new(Expression::Variable(x.clone()))
102//! );
103//! let expr = Expression::Binary(
104//!     BinaryOp::Add,
105//!     Box::new(two_x),
106//!     Box::new(Expression::Integer(5))
107//! );
108//!
109//! // Check variable containment
110//! assert!(expr.contains_variable("x"));
111//! assert!(!expr.contains_variable("y"));
112//! ```
113//!
114//! ## User Guides
115//!
116//! For detailed tutorials and workflows, see the [`guides`] module:
117//!
118//! - [`guides::solving_equations`] - Linear, quadratic, polynomial, and systems
119//! - [`guides::calculus_operations`] - Derivatives, integrals, limits, ODEs
120//! - [`guides::series_expansions`] - Taylor, Maclaurin, Laurent, asymptotic
121//! - [`guides::coordinate_systems`] - 2D/3D transforms, complex numbers
122//! - [`guides::numerical_methods`] - Root-finding when symbolic fails
123//! - [`guides::working_with_units`] - Dimensional analysis
124//! - [`guides::error_handling`] - Working with [`ThalesError`]
125//!
126//! ## Feature Summary
127//!
128//! | Category | Features |
129//! |----------|----------|
130//! | **Parsing** | Expression parser, equation parser, LaTeX input/output |
131//! | **Solving** | Linear, quadratic, polynomial, transcendental, multi-equation systems |
132//! | **Calculus** | Differentiation, integration (by parts, substitution), limits, L'Hôpital |
133//! | **ODEs** | First-order (separable, linear), second-order (constant coefficient) |
134//! | **Series** | Taylor, Maclaurin, Laurent, asymptotic expansions, Big-O |
135//! | **Special** | Gamma, beta, error functions with derivation steps |
136//! | **Numerical** | Newton-Raphson, bisection, Brent's, secant, Levenberg-Marquardt |
137//! | **Transforms** | Cartesian ↔ Polar ↔ Spherical ↔ Cylindrical, complex operations |
138//! | **Units** | SI base/derived units, dimensional analysis, conversions |
139//! | **FFI** | Swift bindings via swift-bridge, iOS device + simulator |
140//!
141//! # Architecture Overview
142//!
143//! The library follows a modular design with clear separation of concerns:
144//!
145//! ```text
146//! ┌─────────────────────────────────────────────────────────┐
147//! │                    Public API Layer                     │
148//! │  (parse_equation, SmartSolver, Cartesian2D, etc.)      │
149//! └─────────────────────────────────────────────────────────┘
150//!                            │
151//!           ┌────────────────┼────────────────┐
152//!           ▼                ▼                ▼
153//!    ┌──────────┐     ┌──────────┐    ┌──────────┐
154//!    │  Parser  │     │  Solver  │    │Transform │
155//!    │ (chumsky)│     │ (symbolic)│    │(nalgebra)│
156//!    └──────────┘     └──────────┘    └──────────┘
157//!           │                │                │
158//!           └────────────────┼────────────────┘
159//!                            ▼
160//!                     ┌──────────┐
161//!                     │   AST    │
162//!                     │(equation,│
163//!                     │  expr,   │
164//!                     │variable) │
165//!                     └──────────┘
166//!                            │
167//!           ┌────────────────┼────────────────┐
168//!           ▼                ▼                ▼
169//!    ┌──────────┐     ┌──────────┐    ┌──────────┐
170//!    │Numerical │     │Resolution│    │Dimensions│
171//!    │ (argmin) │     │   Path   │    │  (units) │
172//!    └──────────┘     └──────────┘    └──────────┘
173//!                            │
174//!                            ▼
175//!                     ┌──────────┐
176//!                     │   FFI    │
177//!                     │  (Swift) │
178//!                     └──────────┘
179//! ```
180//!
181//! ## Module Responsibilities
182//!
183//! - [`ast`]: Core data structures for mathematical expressions, equations, variables,
184//!   operators, and functions. All other modules build upon these types.
185//!
186//! - [`parser`]: String → AST conversion using the chumsky parser combinator library.
187//!   Handles operator precedence, function calls, and complex number literals.
188//!
189//! - [`solver`]: Symbolic equation solving using algebraic manipulation. Includes
190//!   specialized solvers for linear, quadratic, polynomial, and transcendental equations.
191//!   The [`SmartSolver`] automatically dispatches to the appropriate solver.
192//!
193//! - [`numerical`]: Numerical root-finding methods for equations that cannot be solved
194//!   symbolically. Integrates with symbolic differentiation from the AST module.
195//!
196//! - [`resolution_path`]: Records the step-by-step solution process for educational
197//!   applications. Each transformation is recorded with its operation type.
198//!
199//! - [`dimensions`]: Dimensional analysis and unit conversion. Ensures physical
200//!   equations maintain dimensional consistency.
201//!
202//! - [`transforms`]: Coordinate system conversions (Cartesian, Polar, Spherical,
203//!   Cylindrical) and complex number operations. Built on nalgebra for linear algebra.
204//!
205//! - `ffi`: Foreign function interface for Swift via swift-bridge. Provides
206//!   C-compatible bindings for iOS/macOS integration. Enabled with the `ffi` feature flag.
207//!
208//! # Safety Guarantees
209//!
210//! This library adheres to strict memory safety principles:
211//!
212//! - **No unsafe code in core logic**: All mathematical operations, parsing, solving,
213//!   and transformations use only safe Rust.
214//!
215//! - **FFI boundary isolation**: The only `unsafe` code appears in the `ffi` module
216//!   for C interoperability, which is:
217//!   - Isolated behind the `ffi` feature flag
218//!   - Managed by the swift-bridge library
219//!   - Validated at the FFI boundary with explicit error handling
220//!
221//! - **Ownership guarantees**: The Rust type system prevents:
222//!   - Use-after-free bugs
223//!   - Data races in concurrent access
224//!   - Null pointer dereferences
225//!   - Buffer overflows
226//!
227//! - **Integer overflow protection**: All arithmetic operations use checked or saturating
228//!   semantics where appropriate.
229//!
230//! - **Thread safety**: All public types are `Send + Sync` where semantically appropriate,
231//!   with compile-time verification.
232//!
233//! # Performance Characteristics
234//!
235//! ## Time Complexity Guarantees
236//!
237//! | Operation | Complexity | Notes |
238//! |-----------|-----------|-------|
239//! | Parse expression | O(n) | Linear in input string length |
240//! | Variable lookup | O(1) | HashMap-based symbol table |
241//! | Coordinate transform | O(1) | Fixed number of trig operations |
242//! | Linear solve | O(1) | Constant number of operations |
243//! | Quadratic solve | O(1) | Discriminant calculation + sqrt |
244//! | Polynomial solve (degree d) | O(d²) | Companion matrix method |
245//! | Numerical solve (Newton) | O(k) | k iterations to convergence |
246//!
247//! ## Space Complexity
248//!
249//! - **AST storage**: O(n) where n is the number of expression nodes
250//! - **Resolution path**: O(k) where k is the number of solution steps
251//! - **Parser stack**: O(d) where d is maximum nesting depth
252//!
253//! ## Optimization Features
254//!
255//! Build configuration in release mode enables:
256//!
257//! - **Link-Time Optimization (LTO)**: Cross-module inlining and dead code elimination
258//! - **Single codegen unit**: Maximum optimization at cost of compile time
259//! - **opt-level=3**: Aggressive compiler optimizations
260//! - **Zero-cost abstractions**: Generic functions specialized at compile time
261//! - **SIMD auto-vectorization**: Compiler-generated vectorized code where applicable
262//!
263//! ```toml
264//! [profile.release]
265//! opt-level = 3
266//! lto = true
267//! codegen-units = 1
268//! ```
269//!
270//! Benchmark your performance-critical paths with:
271//!
272//! ```bash
273//! cargo bench
274//! ```
275//!
276//! # Platform Support
277//!
278//! ## Tier 1: Fully Supported
279//!
280//! - **iOS Devices** (`aarch64-apple-ios`): Native ARM64 execution on iPhone/iPad
281//! - **iOS Simulator on ARM** (`aarch64-apple-ios-sim`): M1/M2/M3 Mac simulator
282//! - **iOS Simulator on Intel** (`x86_64-apple-ios`): Intel Mac simulator
283//!
284//! Build for all iOS targets:
285//!
286//! ```bash
287//! # Add targets (one-time setup)
288//! rustup target add aarch64-apple-ios
289//! rustup target add aarch64-apple-ios-sim
290//! rustup target add x86_64-apple-ios
291//!
292//! # Build for device
293//! cargo build --release --target aarch64-apple-ios
294//!
295//! # Build for simulator (ARM)
296//! cargo build --release --target aarch64-apple-ios-sim
297//!
298//! # Build universal library with lipo
299//! lipo -create \
300//!   target/aarch64-apple-ios-sim/release/libthales.a \
301//!   target/x86_64-apple-ios/release/libthales.a \
302//!   -output libthales_universal.a
303//! ```
304//!
305//! ## Tier 2: Standard Rust Targets
306//!
307//! The library uses only stable Rust features and should compile on any tier 1 Rust platform:
308//! - Linux (x86_64, aarch64)
309//! - macOS (x86_64, aarch64)
310//! - Windows (x86_64)
311//!
312//! ## FFI Integration
313//!
314//! Enable Swift bindings with the `ffi` feature:
315//!
316//! ```bash
317//! cargo build --release --features ffi --target aarch64-apple-ios
318//! ```
319//!
320//! This generates Swift bridge code and C headers for Xcode integration.
321//!
322//! ## Version History
323//!
324//! **Current: v0.3.0** - Advanced Calculus & API Stabilization
325//!
326//! - Second-order ODEs with characteristic equation method
327//! - Nonlinear system solver (Newton-Raphson for systems)
328//! - Taylor, Maclaurin, Laurent series expansions
329//! - Asymptotic expansions with Big-O notation
330//! - Special functions (gamma, beta, erf, erfc)
331//! - Small angle approximations with error bounds
332//! - Unified [`ThalesError`] type
333//! - 970+ tests including property-based tests
334//!
335//! See [CHANGELOG.md](https://github.com/ChrisGVE/thales/blob/main/CHANGELOG.md)
336//! for complete version history.
337//!
338//! ## Module Reference
339//!
340//! | Module | Description |
341//! |--------|-------------|
342//! | [`ast`] | Abstract syntax tree types for expressions and equations |
343//! | [`parser`] | String → AST conversion with chumsky |
344//! | [`solver`] | Symbolic equation solving |
345//! | [`equation_system`] | Multi-equation system solver |
346//! | [`numerical`] | Numerical root-finding methods |
347//! | [`integration`] | Symbolic integration |
348//! | [`limits`] | Limit evaluation with L'Hôpital's rule |
349//! | [`ode`] | First and second-order ODE solving |
350//! | [`series`] | Taylor, Laurent, asymptotic series |
351//! | [`special`] | Gamma, beta, error functions |
352//! | [`approximations`] | Small angle and scaled approximations |
353//! | [`transforms`] | Coordinate system conversions |
354//! | [`dimensions`] | Units and dimensional analysis |
355//! | [`pattern`] | Rule-based expression rewriting |
356//! | [`latex`] | LaTeX parsing and generation |
357//! | [`resolution_path`] | Step-by-step solution tracking |
358//! | [`guides`] | User tutorials and workflows |
359//!
360//! ## Running Tests
361//!
362//! ```bash
363//! cargo test              # All tests
364//! cargo test --doc        # Documentation examples only
365//! cargo test --release    # Optimized build
366//! ```
367
368#![warn(missing_docs)]
369#![warn(clippy::all)]
370#![warn(clippy::pedantic)]
371#![allow(clippy::missing_errors_doc)]
372#![allow(clippy::missing_panics_doc)]
373
374// Public module exports
375pub mod approximations;
376pub mod ast;
377pub mod dimensions;
378pub mod equation_system;
379pub mod inequality;
380pub mod integration;
381pub mod latex;
382pub mod limits;
383pub mod matrix;
384pub mod numerical;
385pub mod ode;
386pub mod optimization;
387pub mod parser;
388pub mod partial_fractions;
389pub mod pattern;
390pub mod precision;
391pub mod resolution_path;
392pub mod series;
393pub mod solver;
394pub mod special;
395pub mod transforms;
396pub mod trigonometric;
397
398// User guides for common workflows
399pub mod guides;
400
401// FFI module (conditionally compiled for FFI builds)
402#[cfg(feature = "ffi")]
403pub mod ffi;
404
405// Re-export commonly used types at crate root for convenience
406pub use approximations::{
407    apply_small_angle_approx, compute_approximation_error, generate_approximation_step,
408    is_approximation_valid, optimize_pythagorean, select_exp_scaling, ApproxResult, ApproxType,
409    ScaledExpForm,
410};
411pub use ast::{BinaryOp, Equation, Expression, Function, UnaryOp, Variable};
412pub use dimensions::{Dimension, Quantity, Unit, UnitRegistry};
413pub use equation_system::{
414    broyden_system,
415    fixed_point_system,
416    newton_raphson_system,
417    residual_norm,
418    solve_linear_system_lu,
419    validate_jacobian,
420    BroydenSolver,
421    Constraint,
422    ConvergenceBehavior,
423    ConvergenceDiagnostics,
424    DependencyGraph,
425    EquationSystem,
426    EquationType,
427    FixedPointSolver,
428    IntegralInfo,
429    MultiEquationSolution,
430    MultiEquationSolver,
431    NamedEquation,
432    NewtonRaphsonSolver,
433    // Nonlinear system solver
434    NonlinearSystem,
435    NonlinearSystemConfig,
436    NonlinearSystemSolver,
437    NonlinearSystemSolverError,
438    NonlinearSystemSolverResult,
439    ODEInfo,
440    SmartNonlinearSystemSolver,
441    SolutionStrategy,
442    SolutionValue,
443    SolveMethod,
444    SolveStep,
445    SolverConfig,
446    StepResult,
447    SystemContext,
448    SystemError,
449    SystemOperation,
450    SystemResolutionPath,
451    SystemStep,
452};
453pub use inequality::{
454    solve_inequality, solve_system, Bound, Inequality, InequalityError, IntervalSolution,
455};
456pub use integration::{
457    definite_integral, definite_integral_with_fallback, definite_integral_with_steps,
458    improper_integral_to_infinity, integrate, integrate_by_parts, integrate_by_parts_with_steps,
459    integrate_by_substitution, integrate_with_substitution, numerical_integrate,
460    tabular_integration, IntegrationError,
461};
462pub use latex::{parse_latex, parse_latex_equation};
463pub use matrix::{BracketStyle, MatrixError, MatrixExpr};
464pub use numerical::{NumericalConfig, NumericalSolution, SmartNumericalSolver};
465pub use ode::{
466    solve_characteristic_equation, solve_ivp, solve_linear, solve_second_order_homogeneous,
467    solve_second_order_ivp, solve_separable, CharacteristicRoots, FirstOrderODE, ODEError,
468    ODESolution, RootType, SecondOrderODE, SecondOrderSolution,
469};
470pub use optimization::{
471    analyze_expression, find_multiplicative_chains, optimize_computation_order, to_manual_steps,
472    track_precision, ComputationStep, ManualStep, MultiplicativeChain, OperationConfig,
473    OperationType, PrecisionReport, StepOperand,
474};
475pub use parser::{parse_equation, parse_expression};
476pub use partial_fractions::{
477    decompose, is_polynomial, is_rational_function, DecomposeError, PartialFractionResult,
478    PartialFractionTerm,
479};
480pub use precision::{EvalContext, EvalError, PrecisionMode, RoundingMode, Value};
481pub use resolution_path::{
482    Operation, OperationCounts, PathStatistics, ResolutionPath, ResolutionPathBuilder,
483    ResolutionStep, Verbosity,
484};
485pub use series::{
486    arctan_series,
487    asymptotic,
488    binomial_series,
489    // Series arithmetic (composition and reversion)
490    compose_series,
491    compute_nth_derivative,
492    cos_series,
493    evaluate_at,
494    exp_series,
495    factorial,
496    factorial_expr,
497    find_singularities,
498    laurent,
499    limit_via_asymptotic,
500    ln_1_plus_x_series,
501    maclaurin,
502    pole_order,
503    residue,
504    reversion,
505    sin_series,
506    taylor,
507    // Asymptotic expansions
508    AsymptoticDirection,
509    AsymptoticSeries,
510    AsymptoticTerm,
511    BigO,
512    // Laurent series support
513    LaurentSeries,
514    RemainderTerm,
515    Series,
516    SeriesError,
517    SeriesResult,
518    SeriesTerm,
519    Singularity,
520    SingularityType,
521};
522pub use solver::{LinearSystem, SmartSolver, Solution, Solver, SystemSolution, SystemSolver};
523pub use special::{beta, erf, erfc, gamma, SpecialFunctionError, SpecialFunctionResult};
524pub use transforms::{
525    Cartesian2D, Cartesian3D, ComplexOps, Cylindrical, Polar, Spherical, Transform2D,
526};
527pub use trigonometric::{
528    all_trig_rules, double_angle_rules, inverse_rules, parity_rules, product_to_sum_rules,
529    pythagorean_rules, quotient_rules, simplify_double_angle, simplify_pythagorean,
530    simplify_quotient, simplify_trig, simplify_trig_step, simplify_trig_with_steps,
531    special_value_rules,
532};
533
534/// Library version information.
535pub const VERSION: &str = env!("CARGO_PKG_VERSION");
536
537/// Library name.
538pub const NAME: &str = env!("CARGO_PKG_NAME");
539
540/// Get library version string.
541pub fn version() -> &'static str {
542    VERSION
543}
544
545/// Check if library is compiled with FFI support.
546pub fn has_ffi_support() -> bool {
547    cfg!(feature = "ffi")
548}
549
550/// Unified error type for the thales library.
551///
552/// This enum provides a single error type that encompasses all possible errors
553/// that can occur within the library. It wraps error types from individual modules,
554/// allowing for consistent error handling across the entire library.
555///
556/// # Design
557///
558/// The `#[non_exhaustive]` attribute allows future versions to add new error variants
559/// without breaking existing code. Users should always include a wildcard match arm
560/// when matching on this type.
561///
562/// # Examples
563///
564/// ```rust
565/// use thales::{ThalesError, parse_expression};
566///
567/// match parse_expression("2 + x") {
568///     Ok(expr) => println!("Parsed: {:?}", expr),
569///     Err(errors) => {
570///         // parse_expression returns Vec<ParseError>, not ThalesError
571///         println!("Parse errors: {:?}", errors);
572///     }
573/// }
574/// ```
575///
576/// Future usage with unified error handling:
577///
578/// ```rust,ignore
579/// use thales::ThalesError;
580///
581/// fn process() -> Result<(), ThalesError> {
582///     // Future API will return ThalesError
583///     Ok(())
584/// }
585/// ```
586#[derive(Debug)]
587#[non_exhaustive]
588pub enum ThalesError {
589    /// Error from the parser module.
590    Parse(parser::ParseError),
591    /// Error from the solver module.
592    Solver(solver::SolverError),
593    /// Error from the series module.
594    Series(series::SeriesError),
595    /// Error from the matrix module.
596    Matrix(matrix::MatrixError),
597    /// Error from the integration module.
598    Integration(integration::IntegrationError),
599    /// Error from the numerical module.
600    Numerical(numerical::NumericalError),
601    /// Error from the limits module.
602    Limits(limits::LimitError),
603    /// Error from the ODE module.
604    ODE(ode::ODEError),
605    /// Error from the special functions module.
606    SpecialFunction(special::SpecialFunctionError),
607    /// Error from the inequality module.
608    Inequality(inequality::InequalityError),
609    /// Error from the precision module.
610    Evaluation(precision::EvalError),
611    /// Error from the partial fractions module.
612    PartialFractions(partial_fractions::DecomposeError),
613    /// Error from the LaTeX parser module.
614    LaTeXParse(latex::LaTeXParseError),
615    /// Error from the equation system module.
616    System(equation_system::SystemError),
617    /// Error from the nonlinear system solver.
618    NonlinearSystem(equation_system::NonlinearSystemSolverError),
619}
620
621impl std::fmt::Display for ThalesError {
622    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
623        match self {
624            ThalesError::Parse(e) => write!(f, "Parse error: {}", e),
625            ThalesError::Solver(e) => write!(f, "Solver error: {:?}", e),
626            ThalesError::Series(e) => write!(f, "Series error: {}", e),
627            ThalesError::Matrix(e) => write!(f, "Matrix error: {}", e),
628            ThalesError::Integration(e) => write!(f, "Integration error: {}", e),
629            ThalesError::Numerical(e) => write!(f, "Numerical error: {:?}", e),
630            ThalesError::Limits(e) => write!(f, "Limits error: {}", e),
631            ThalesError::ODE(e) => write!(f, "ODE error: {}", e),
632            ThalesError::SpecialFunction(e) => write!(f, "Special function error: {}", e),
633            ThalesError::Inequality(e) => write!(f, "Inequality error: {}", e),
634            ThalesError::Evaluation(e) => write!(f, "Evaluation error: {}", e),
635            ThalesError::PartialFractions(e) => write!(f, "Partial fractions error: {}", e),
636            ThalesError::LaTeXParse(e) => write!(f, "LaTeX parse error: {}", e),
637            ThalesError::System(e) => write!(f, "System error: {:?}", e),
638            ThalesError::NonlinearSystem(e) => write!(f, "Nonlinear system error: {:?}", e),
639        }
640    }
641}
642
643impl std::error::Error for ThalesError {
644    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
645        match self {
646            ThalesError::Parse(e) => Some(e),
647            ThalesError::Series(e) => Some(e),
648            ThalesError::Matrix(e) => Some(e),
649            ThalesError::Integration(e) => Some(e),
650            ThalesError::Limits(e) => Some(e),
651            ThalesError::ODE(e) => Some(e),
652            ThalesError::SpecialFunction(e) => Some(e),
653            ThalesError::Inequality(e) => Some(e),
654            ThalesError::Evaluation(e) => Some(e),
655            ThalesError::PartialFractions(e) => Some(e),
656            ThalesError::LaTeXParse(e) => Some(e),
657            // These error types don't implement std::error::Error
658            ThalesError::Solver(_) => None,
659            ThalesError::Numerical(_) => None,
660            ThalesError::System(_) => None,
661            ThalesError::NonlinearSystem(_) => None,
662        }
663    }
664}
665
666// Implement From conversions for each error type
667impl From<parser::ParseError> for ThalesError {
668    fn from(e: parser::ParseError) -> Self {
669        ThalesError::Parse(e)
670    }
671}
672
673impl From<solver::SolverError> for ThalesError {
674    fn from(e: solver::SolverError) -> Self {
675        ThalesError::Solver(e)
676    }
677}
678
679impl From<series::SeriesError> for ThalesError {
680    fn from(e: series::SeriesError) -> Self {
681        ThalesError::Series(e)
682    }
683}
684
685impl From<matrix::MatrixError> for ThalesError {
686    fn from(e: matrix::MatrixError) -> Self {
687        ThalesError::Matrix(e)
688    }
689}
690
691impl From<integration::IntegrationError> for ThalesError {
692    fn from(e: integration::IntegrationError) -> Self {
693        ThalesError::Integration(e)
694    }
695}
696
697impl From<numerical::NumericalError> for ThalesError {
698    fn from(e: numerical::NumericalError) -> Self {
699        ThalesError::Numerical(e)
700    }
701}
702
703impl From<limits::LimitError> for ThalesError {
704    fn from(e: limits::LimitError) -> Self {
705        ThalesError::Limits(e)
706    }
707}
708
709impl From<ode::ODEError> for ThalesError {
710    fn from(e: ode::ODEError) -> Self {
711        ThalesError::ODE(e)
712    }
713}
714
715impl From<special::SpecialFunctionError> for ThalesError {
716    fn from(e: special::SpecialFunctionError) -> Self {
717        ThalesError::SpecialFunction(e)
718    }
719}
720
721impl From<inequality::InequalityError> for ThalesError {
722    fn from(e: inequality::InequalityError) -> Self {
723        ThalesError::Inequality(e)
724    }
725}
726
727impl From<precision::EvalError> for ThalesError {
728    fn from(e: precision::EvalError) -> Self {
729        ThalesError::Evaluation(e)
730    }
731}
732
733impl From<partial_fractions::DecomposeError> for ThalesError {
734    fn from(e: partial_fractions::DecomposeError) -> Self {
735        ThalesError::PartialFractions(e)
736    }
737}
738
739impl From<latex::LaTeXParseError> for ThalesError {
740    fn from(e: latex::LaTeXParseError) -> Self {
741        ThalesError::LaTeXParse(e)
742    }
743}
744
745impl From<equation_system::SystemError> for ThalesError {
746    fn from(e: equation_system::SystemError) -> Self {
747        ThalesError::System(e)
748    }
749}
750
751impl From<equation_system::NonlinearSystemSolverError> for ThalesError {
752    fn from(e: equation_system::NonlinearSystemSolverError) -> Self {
753        ThalesError::NonlinearSystem(e)
754    }
755}
756
757// TODO: Add prelude module with commonly used imports
758// TODO: Add error types module with unified error handling
759// TODO: Add traits module with common trait definitions
760// TODO: Add macro module for expression DSL
761// TODO: Add serde support for serialization
762// TODO: Add wasm support for web usage
763// TODO: Add Python bindings via PyO3
764// TODO: Add comprehensive integration tests
765// TODO: Add performance benchmarks
766// TODO: Add documentation examples that compile and run
767
768#[cfg(test)]
769mod tests {
770    use super::*;
771
772    #[test]
773    fn test_thales_error_from_parse_error() {
774        let parse_err = parser::ParseError::UnexpectedCharacter { pos: 0, found: 'x' };
775        let thales_err: ThalesError = parse_err.clone().into();
776
777        match thales_err {
778            ThalesError::Parse(e) => assert_eq!(e, parse_err),
779            _ => panic!("Expected ThalesError::Parse"),
780        }
781    }
782
783    #[test]
784    fn test_thales_error_from_solver_error() {
785        let solver_err = solver::SolverError::NoSolution;
786        let thales_err: ThalesError = solver_err.clone().into();
787
788        match thales_err {
789            ThalesError::Solver(e) => assert_eq!(e, solver_err),
790            _ => panic!("Expected ThalesError::Solver"),
791        }
792    }
793
794    #[test]
795    fn test_thales_error_from_numerical_error() {
796        let num_err = numerical::NumericalError::NoConvergence;
797        let thales_err: ThalesError = num_err.clone().into();
798
799        match thales_err {
800            ThalesError::Numerical(e) => assert_eq!(e, num_err),
801            _ => panic!("Expected ThalesError::Numerical"),
802        }
803    }
804
805    #[test]
806    fn test_thales_error_display() {
807        let solver_err = solver::SolverError::NoSolution;
808        let thales_err: ThalesError = solver_err.into();
809        let display_str = format!("{}", thales_err);
810
811        assert!(display_str.contains("Solver error"));
812        assert!(display_str.contains("NoSolution"));
813    }
814
815    #[test]
816    fn test_thales_error_source() {
817        use std::error::Error;
818
819        let parse_err = parser::ParseError::UnexpectedCharacter { pos: 5, found: '!' };
820        let thales_err: ThalesError = parse_err.into();
821
822        assert!(thales_err.source().is_some());
823    }
824
825    #[test]
826    fn test_thales_error_from_integration_error() {
827        let int_err = integration::IntegrationError::DivisionByZero;
828        let thales_err: ThalesError = int_err.clone().into();
829
830        match thales_err {
831            ThalesError::Integration(e) => assert_eq!(e, int_err),
832            _ => panic!("Expected ThalesError::Integration"),
833        }
834    }
835
836    #[test]
837    fn test_thales_error_from_matrix_error() {
838        let matrix_err = matrix::MatrixError::EmptyMatrix;
839        let thales_err: ThalesError = matrix_err.clone().into();
840
841        match thales_err {
842            ThalesError::Matrix(e) => assert_eq!(e, matrix_err),
843            _ => panic!("Expected ThalesError::Matrix"),
844        }
845    }
846}