mathhook_core/functions/properties/rules.rs
1//! Derivative and Antiderivative Rules
2//!
3//! Defines rule types and structures for automatic differentiation and integration.
4//! These rules enable the Universal Function Intelligence System to compute derivatives
5//! and antiderivatives efficiently using pattern matching and rule-based evaluation.
6
7use crate::core::{Expression, Symbol};
8use std::sync::Arc;
9
10/// Derivative rule for automatic differentiation
11#[derive(Clone)]
12pub struct DerivativeRule {
13 /// Rule type for efficient computation
14 pub rule_type: DerivativeRuleType,
15
16 /// Result expression template (for documentation)
17 pub result_template: String,
18}
19
20/// Types of derivative rules for performance optimization
21pub enum DerivativeRuleType {
22 /// Simple function substitution: d/dx sin(x) = cos(x)
23 ///
24 /// Stores the derivative function name for simple cases where
25 /// the derivative is another elementary function of the same argument.
26 ///
27 /// Examples: sin → cos, exp → exp, sinh → cosh, cosh → sinh
28 ///
29 /// Note: For non-trivial derivatives (like ln → 1/x or sqrt → 1/(2√x)),
30 /// use the Custom variant instead to build the actual expression.
31 SimpleFunctionSubstitution(String),
32
33 /// Custom derivative with expression builder
34 ///
35 /// Stores a closure that constructs the derivative expression
36 /// given the function's argument. Used for complex derivatives like
37 /// arcsin, arctan, sqrt, and composite expressions.
38 ///
39 /// Example: d/dx arcsin(u) = builder(u) → 1/√(1-u²)
40 ///
41 /// The builder takes the argument expression and returns
42 /// the derivative with respect to that argument (without chain rule).
43 /// The chain rule (multiplying by du/dx) is applied externally.
44 Custom {
45 #[allow(clippy::type_complexity)]
46 builder: Arc<dyn Fn(&Expression) -> Expression + Send + Sync>,
47 },
48
49 /// Chain rule application: d/dx sin(u) = cos(u) * du/dx
50 ///
51 /// Legacy variant - prefer Custom for new implementations
52 ChainRule(String),
53
54 /// Product rule: d/dx (uv) = u'v + uv'
55 ProductRule,
56
57 /// Quotient rule: d/dx (u/v) = (u'v - uv')/v²
58 QuotientRule,
59}
60
61impl Clone for DerivativeRuleType {
62 fn clone(&self) -> Self {
63 match self {
64 DerivativeRuleType::SimpleFunctionSubstitution(name) => {
65 DerivativeRuleType::SimpleFunctionSubstitution(name.clone())
66 }
67 DerivativeRuleType::Custom { builder } => DerivativeRuleType::Custom {
68 builder: Arc::clone(builder),
69 },
70 DerivativeRuleType::ChainRule(name) => DerivativeRuleType::ChainRule(name.clone()),
71 DerivativeRuleType::ProductRule => DerivativeRuleType::ProductRule,
72 DerivativeRuleType::QuotientRule => DerivativeRuleType::QuotientRule,
73 }
74 }
75}
76
77impl std::fmt::Debug for DerivativeRuleType {
78 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79 match self {
80 DerivativeRuleType::SimpleFunctionSubstitution(name) => f
81 .debug_struct("SimpleFunctionSubstitution")
82 .field("function", name)
83 .finish(),
84 DerivativeRuleType::Custom { .. } => f
85 .debug_struct("Custom")
86 .field("builder", &"<closure>")
87 .finish(),
88 DerivativeRuleType::ChainRule(name) => {
89 f.debug_struct("ChainRule").field("function", name).finish()
90 }
91 DerivativeRuleType::ProductRule => f.debug_struct("ProductRule").finish(),
92 DerivativeRuleType::QuotientRule => f.debug_struct("QuotientRule").finish(),
93 }
94 }
95}
96
97impl std::fmt::Debug for DerivativeRule {
98 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99 f.debug_struct("DerivativeRule")
100 .field("rule_type", &self.rule_type)
101 .field("result_template", &self.result_template)
102 .finish()
103 }
104}
105
106/// Antiderivative rule for automatic integration
107///
108/// Stores the antiderivative formula for a function, analogous to DerivativeRule.
109/// Supports simple antiderivatives, substitution patterns, and special techniques.
110///
111/// # Examples
112///
113/// ```rust
114/// use mathhook_core::functions::properties::{AntiderivativeRule, AntiderivativeRuleType, ConstantOfIntegration};
115/// use mathhook_core::expr;
116///
117/// let sin_antiderivative = AntiderivativeRule {
118/// rule_type: AntiderivativeRuleType::Simple {
119/// antiderivative_fn: "cos".to_string(),
120/// coefficient: expr!(-1),
121/// },
122/// result_template: "-cos(x) + C".to_string(),
123/// constant_handling: ConstantOfIntegration::AddConstant,
124/// };
125/// ```
126#[derive(Debug, Clone)]
127pub struct AntiderivativeRule {
128 /// Rule type for efficient computation
129 pub rule_type: AntiderivativeRuleType,
130
131 /// Result expression template (for documentation and validation)
132 /// Example: "∫sin(x)dx = -cos(x) + C"
133 pub result_template: String,
134
135 /// Constant of integration behavior
136 pub constant_handling: ConstantOfIntegration,
137}
138
139/// Types of antiderivative rules for performance optimization
140///
141/// Each variant represents a different integration technique or pattern,
142/// enabling the registry to efficiently compute integrals based on function properties.
143pub enum AntiderivativeRuleType {
144 /// Simple substitution: ∫sin(x)dx = -cos(x) + C
145 ///
146 /// Contains the antiderivative function name and multiplicative coefficient.
147 /// This is the most common case for elementary functions.
148 Simple {
149 /// Name of the antiderivative function
150 antiderivative_fn: String,
151
152 /// Multiplicative coefficient (e.g., -1 for sin → -cos)
153 coefficient: Expression,
154 },
155
156 /// Custom antiderivative with expression builder
157 ///
158 /// Stores a closure that constructs the antiderivative expression
159 /// given the integration variable. Used for complex expressions like
160 /// tan, cot, sec, csc, ln, log, arcsin, arccos, arctan, tanh, sqrt.
161 ///
162 /// Example: ∫tan(x)dx = builder(x) → -ln|cos(x)|
163 Custom {
164 #[allow(clippy::type_complexity)]
165 builder: Arc<dyn Fn(Symbol) -> Expression + Send + Sync>,
166 },
167
168 /// Linear substitution: ∫f(ax)dx = (1/a)F(ax) + C
169 ///
170 /// Used for patterns like ∫sin(3x)dx = -(1/3)cos(3x) + C
171 /// where the inner function is a linear transformation.
172 LinearSubstitution {
173 coefficient: Expression,
174 inner_rule: Box<AntiderivativeRule>,
175 },
176
177 /// Trigonometric substitution patterns
178 ///
179 /// Used for integrals like ∫1/√(1-x²)dx = arcsin(x) + C
180 /// where a trigonometric substitution simplifies the integral.
181 TrigSubstitution { substitution_type: String },
182
183 /// Partial fraction decomposition (for rational functions)
184 ///
185 /// Indicates that the integral requires partial fraction decomposition
186 /// before integration can proceed.
187 PartialFractions { decomposition: Vec<Expression> },
188}
189
190impl Clone for AntiderivativeRuleType {
191 fn clone(&self) -> Self {
192 match self {
193 AntiderivativeRuleType::Simple {
194 antiderivative_fn,
195 coefficient,
196 } => AntiderivativeRuleType::Simple {
197 antiderivative_fn: antiderivative_fn.clone(),
198 coefficient: coefficient.clone(),
199 },
200 AntiderivativeRuleType::Custom { builder } => AntiderivativeRuleType::Custom {
201 builder: Arc::clone(builder),
202 },
203 AntiderivativeRuleType::LinearSubstitution {
204 coefficient,
205 inner_rule,
206 } => AntiderivativeRuleType::LinearSubstitution {
207 coefficient: coefficient.clone(),
208 inner_rule: inner_rule.clone(),
209 },
210 AntiderivativeRuleType::TrigSubstitution { substitution_type } => {
211 AntiderivativeRuleType::TrigSubstitution {
212 substitution_type: substitution_type.clone(),
213 }
214 }
215 AntiderivativeRuleType::PartialFractions { decomposition } => {
216 AntiderivativeRuleType::PartialFractions {
217 decomposition: decomposition.clone(),
218 }
219 }
220 }
221 }
222}
223
224impl std::fmt::Debug for AntiderivativeRuleType {
225 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
226 match self {
227 AntiderivativeRuleType::Simple {
228 antiderivative_fn,
229 coefficient,
230 } => f
231 .debug_struct("Simple")
232 .field("antiderivative_fn", antiderivative_fn)
233 .field("coefficient", coefficient)
234 .finish(),
235 AntiderivativeRuleType::Custom { .. } => f
236 .debug_struct("Custom")
237 .field("builder", &"<closure>")
238 .finish(),
239 AntiderivativeRuleType::LinearSubstitution {
240 coefficient,
241 inner_rule,
242 } => f
243 .debug_struct("LinearSubstitution")
244 .field("coefficient", coefficient)
245 .field("inner_rule", inner_rule)
246 .finish(),
247 AntiderivativeRuleType::TrigSubstitution { substitution_type } => f
248 .debug_struct("TrigSubstitution")
249 .field("substitution_type", substitution_type)
250 .finish(),
251 AntiderivativeRuleType::PartialFractions { decomposition } => f
252 .debug_struct("PartialFractions")
253 .field("decomposition", decomposition)
254 .finish(),
255 }
256 }
257}
258
259/// Constant of integration handling
260///
261/// Specifies how the constant of integration should be handled
262/// in the antiderivative result.
263#[derive(Debug, Clone, Copy, PartialEq)]
264pub enum ConstantOfIntegration {
265 /// Automatically add +C to result
266 AddConstant,
267
268 /// Definite integral (no constant)
269 DefiniteIntegral,
270
271 /// User will handle constant explicitly
272 UserHandled,
273}
274
275/// Recurrence relation for symbolic computation
276#[derive(Debug, Clone)]
277pub struct RecurrenceRule {
278 /// Recurrence relation name
279 pub name: String,
280
281 /// Relation template (e.g., "f_{n+1} = a*f_n + b*f_{n-1}")
282 pub relation: String,
283
284 /// Coefficients for computation
285 pub coefficients: Vec<Expression>,
286}
287
288/// Three-term recurrence for orthogonal polynomials
289#[derive(Debug, Clone)]
290pub struct ThreeTermRecurrence {
291 /// Forward coefficient: α_n in P_{n+1} = (α_n x + β_n)P_n - γ_n P_{n-1}
292 pub alpha_coeff: Expression,
293
294 /// Linear coefficient: β_n
295 pub beta_coeff: Expression,
296
297 /// Backward coefficient: γ_n
298 pub gamma_coeff: Expression,
299
300 /// Initial conditions: P_0, P_1
301 pub initial_conditions: (Expression, Expression),
302}
303
304/// Mathematical identity for symbolic computation
305#[derive(Debug, Clone)]
306pub struct MathIdentity {
307 /// Identity name for reference
308 pub name: String,
309
310 /// Left side of identity
311 pub lhs: Expression,
312
313 /// Right side of identity
314 pub rhs: Expression,
315
316 /// Conditions for identity validity
317 pub conditions: Vec<String>,
318}
319
320/// Special value for exact computation
321#[derive(Debug, Clone)]
322pub struct SpecialValue {
323 /// Input value (e.g., "0", "π/2", "1")
324 pub input: String,
325
326 /// Exact output value
327 pub output: Expression,
328
329 /// LaTeX representation for educational display
330 pub latex_explanation: String,
331}
332
333/// Domain and range information
334#[derive(Debug, Clone)]
335pub struct DomainRangeData {
336 /// Function domain
337 pub domain: Domain,
338
339 /// Function range
340 pub range: Range,
341
342 /// Singularities (if any)
343 pub singularities: Vec<Expression>,
344}
345
346/// Mathematical domain
347#[derive(Debug, Clone, PartialEq)]
348pub enum Domain {
349 Real,
350 Complex,
351 Integer,
352 PositiveInteger,
353 NonNegativeInteger,
354 Interval(Expression, Expression),
355 Union(Vec<Domain>),
356}
357
358/// Mathematical range
359#[derive(Debug, Clone)]
360pub enum Range {
361 Real,
362 Integer,
363 PositiveInteger,
364 NonNegativeInteger,
365 Boolean,
366 Bounded(Expression, Expression),
367 Unbounded,
368}
369
370/// Evaluation method for computational efficiency
371#[derive(Debug, Clone, Copy, PartialEq)]
372pub enum EvaluationMethod {
373 /// Direct formula evaluation
374 Direct,
375
376 /// Recurrence relation (most efficient for polynomials)
377 Recurrence,
378
379 /// Horner's method for polynomial evaluation
380 Horner,
381
382 /// Series expansion
383 Series,
384}