mathhook_core/calculus/
integrals.rs

1//! Integration operations and methods
2//!
3//! Implements symbolic integration including basic antiderivatives,
4//! integration by parts, substitution, trigonometric integrals,
5//! and definite integrals. Utilizes the existing Expression::Calculus
6//! infrastructure and Expression::function support.
7
8mod basic;
9pub mod by_parts;
10// mod definite;
11pub mod educational;
12mod function_integrals;
13pub mod numerical;
14pub mod rational;
15pub mod risch;
16pub mod strategy;
17pub mod substitution;
18pub mod table;
19pub mod trigonometric;
20
21pub use basic::BasicIntegrals;
22pub use by_parts::IntegrationByParts;
23// pub use definite::DefiniteIntegrals;
24pub use educational::{
25    explain_constant_rule, explain_definite_integral, explain_integration_by_parts,
26    explain_power_rule, explain_sum_rule, explain_u_substitution,
27};
28pub use function_integrals::FunctionIntegrals;
29pub use numerical::{
30    AdaptiveSimpson, GaussianQuadrature, IntegrationConfig, IntegrationResult, NumericalIntegrator,
31    RombergIntegration,
32};
33pub use rational::{integrate_rational, is_rational_function};
34pub use substitution::try_substitution;
35pub use trigonometric::try_trigonometric_integration;
36
37use crate::core::{Expression, Symbol};
38use strategy::integrate_with_strategy;
39
40/// Trait for integration operations
41/// Added `depth` parameter to prevent infinite recursion in integration by parts.
42/// The `depth` parameter tracks recursion depth and enables maximum depth limiting.
43///
44/// Default depth is 0 (top-level call). Internal implementations increment this
45/// to prevent stack overflow in cases where simplification fails.
46pub trait Integration {
47    /// Compute indefinite integral with recursion depth tracking
48    ///
49    /// # Arguments
50    ///
51    /// * `variable` - The variable to integrate with respect to
52    /// * `depth` - Current recursion depth (default: 0)
53    ///
54    /// # Examples
55    ///
56    /// ```rust
57    /// use mathhook_core::calculus::integrals::IntegrationMethods;
58    /// use mathhook_core::Expression;
59    /// use mathhook_core::calculus::integrals::Integration;
60    /// use mathhook_core::symbol;
61    ///
62    /// let x = symbol!(x);
63    /// let expr = Expression::pow(Expression::symbol(x.clone()), Expression::integer(2));
64    /// let result = expr.integrate(x, 0);
65    /// ```
66    fn integrate(&self, variable: Symbol, depth: usize) -> Expression;
67
68    /// Compute definite integral
69    ///
70    /// # Examples
71    ///
72    /// ```rust
73    /// use mathhook_core::Expression;
74    /// use mathhook_core::symbol;
75    /// use mathhook_core::calculus::integrals::Integration;
76    ///
77    /// let x = symbol!(x);
78    /// let expr = Expression::symbol(x.clone());
79    /// let lower = Expression::integer(0);
80    /// let upper = Expression::integer(1);
81    /// let result = expr.definite_integrate(x, lower, upper);
82    /// ```
83    fn definite_integrate(
84        &self,
85        variable: Symbol,
86        lower: Expression,
87        upper: Expression,
88    ) -> Expression;
89}
90
91impl Integration for Expression {
92    fn integrate(&self, variable: Symbol, depth: usize) -> Expression {
93        // Delegate to strategy dispatcher which orchestrates all integration techniques
94        integrate_with_strategy(self, variable, depth)
95    }
96
97    fn definite_integrate(
98        &self,
99        variable: Symbol,
100        lower: Expression,
101        upper: Expression,
102    ) -> Expression {
103        // Use core Expression::definite_integral constructor
104        Expression::definite_integral(self.clone(), variable, lower, upper)
105    }
106}
107
108/// Integration methods collection
109pub struct IntegrationMethods;
110
111impl IntegrationMethods {
112    /// Attempt integration by parts
113    ///
114    /// Uses the IntegrationByParts module to attempt integration by parts.
115    /// Falls back to symbolic representation if unable to integrate.
116    ///
117    /// # Examples
118    ///
119    /// ```rust
120    /// use mathhook_core::Expression;
121    /// use mathhook_core::symbol;
122    /// use mathhook_core::calculus::integrals::IntegrationMethods;
123    ///
124    /// let x = symbol!(x);
125    /// let expr = Expression::mul(vec![
126    ///     Expression::symbol(x.clone()),
127    ///     Expression::function("exp", vec![Expression::symbol(x.clone())])
128    /// ]);
129    /// let result = IntegrationMethods::by_parts(&expr, x);
130    /// ```
131    pub fn by_parts(expr: &Expression, variable: Symbol) -> Expression {
132        IntegrationByParts::integrate(expr, variable.clone(), 0)
133            .unwrap_or_else(|| Expression::integral(expr.clone(), variable))
134    }
135
136    /// Attempt integration by substitution
137    ///
138    /// Uses u-substitution to integrate composite functions f(g(x)) where
139    /// the derivative g'(x) appears in the integrand.
140    ///
141    /// # Examples
142    ///
143    /// ```rust
144    /// use mathhook_core::{Expression, Symbol};
145    /// use mathhook_core::symbol;
146    /// use mathhook_core::calculus::integrals::IntegrationMethods;
147    ///
148    /// let x = symbol!(x);
149    /// let expr = Expression::function("sin", vec![
150    ///     Expression::pow(Expression::symbol(x.clone()), Expression::integer(2))
151    /// ]);
152    /// let result = IntegrationMethods::substitution(&expr, x);
153    /// ```
154    pub fn substitution(expr: &Expression, variable: Symbol) -> Expression {
155        try_substitution(expr, &variable, 0)
156            .unwrap_or_else(|| Expression::integral(expr.clone(), variable))
157    }
158}