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}