use crate::core::{Expression, Symbol};
use std::sync::Arc;
#[derive(Clone)]
pub struct DerivativeRule {
pub rule_type: DerivativeRuleType,
pub result_template: String,
}
pub enum DerivativeRuleType {
SimpleFunctionSubstitution(String),
Custom {
#[allow(clippy::type_complexity)]
builder: Arc<dyn Fn(&Expression) -> Expression + Send + Sync>,
},
ChainRule(String),
ProductRule,
QuotientRule,
}
impl Clone for DerivativeRuleType {
fn clone(&self) -> Self {
match self {
DerivativeRuleType::SimpleFunctionSubstitution(name) => {
DerivativeRuleType::SimpleFunctionSubstitution(name.clone())
}
DerivativeRuleType::Custom { builder } => DerivativeRuleType::Custom {
builder: Arc::clone(builder),
},
DerivativeRuleType::ChainRule(name) => DerivativeRuleType::ChainRule(name.clone()),
DerivativeRuleType::ProductRule => DerivativeRuleType::ProductRule,
DerivativeRuleType::QuotientRule => DerivativeRuleType::QuotientRule,
}
}
}
impl std::fmt::Debug for DerivativeRuleType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
DerivativeRuleType::SimpleFunctionSubstitution(name) => f
.debug_struct("SimpleFunctionSubstitution")
.field("function", name)
.finish(),
DerivativeRuleType::Custom { .. } => f
.debug_struct("Custom")
.field("builder", &"<closure>")
.finish(),
DerivativeRuleType::ChainRule(name) => {
f.debug_struct("ChainRule").field("function", name).finish()
}
DerivativeRuleType::ProductRule => f.debug_struct("ProductRule").finish(),
DerivativeRuleType::QuotientRule => f.debug_struct("QuotientRule").finish(),
}
}
}
impl std::fmt::Debug for DerivativeRule {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("DerivativeRule")
.field("rule_type", &self.rule_type)
.field("result_template", &self.result_template)
.finish()
}
}
#[derive(Debug, Clone)]
pub struct AntiderivativeRule {
pub rule_type: AntiderivativeRuleType,
pub result_template: String,
pub constant_handling: ConstantOfIntegration,
}
pub enum AntiderivativeRuleType {
Simple {
antiderivative_fn: String,
coefficient: Expression,
},
Custom {
#[allow(clippy::type_complexity)]
builder: Arc<dyn Fn(Symbol) -> Expression + Send + Sync>,
},
LinearSubstitution {
coefficient: Expression,
inner_rule: Box<AntiderivativeRule>,
},
TrigSubstitution { substitution_type: String },
PartialFractions { decomposition: Vec<Expression> },
}
impl Clone for AntiderivativeRuleType {
fn clone(&self) -> Self {
match self {
AntiderivativeRuleType::Simple {
antiderivative_fn,
coefficient,
} => AntiderivativeRuleType::Simple {
antiderivative_fn: antiderivative_fn.clone(),
coefficient: coefficient.clone(),
},
AntiderivativeRuleType::Custom { builder } => AntiderivativeRuleType::Custom {
builder: Arc::clone(builder),
},
AntiderivativeRuleType::LinearSubstitution {
coefficient,
inner_rule,
} => AntiderivativeRuleType::LinearSubstitution {
coefficient: coefficient.clone(),
inner_rule: inner_rule.clone(),
},
AntiderivativeRuleType::TrigSubstitution { substitution_type } => {
AntiderivativeRuleType::TrigSubstitution {
substitution_type: substitution_type.clone(),
}
}
AntiderivativeRuleType::PartialFractions { decomposition } => {
AntiderivativeRuleType::PartialFractions {
decomposition: decomposition.clone(),
}
}
}
}
}
impl std::fmt::Debug for AntiderivativeRuleType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
AntiderivativeRuleType::Simple {
antiderivative_fn,
coefficient,
} => f
.debug_struct("Simple")
.field("antiderivative_fn", antiderivative_fn)
.field("coefficient", coefficient)
.finish(),
AntiderivativeRuleType::Custom { .. } => f
.debug_struct("Custom")
.field("builder", &"<closure>")
.finish(),
AntiderivativeRuleType::LinearSubstitution {
coefficient,
inner_rule,
} => f
.debug_struct("LinearSubstitution")
.field("coefficient", coefficient)
.field("inner_rule", inner_rule)
.finish(),
AntiderivativeRuleType::TrigSubstitution { substitution_type } => f
.debug_struct("TrigSubstitution")
.field("substitution_type", substitution_type)
.finish(),
AntiderivativeRuleType::PartialFractions { decomposition } => f
.debug_struct("PartialFractions")
.field("decomposition", decomposition)
.finish(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ConstantOfIntegration {
AddConstant,
DefiniteIntegral,
UserHandled,
}
#[derive(Debug, Clone)]
pub struct RecurrenceRule {
pub name: String,
pub relation: String,
pub coefficients: Vec<Expression>,
}
#[derive(Debug, Clone)]
pub struct ThreeTermRecurrence {
pub alpha_coeff: Expression,
pub beta_coeff: Expression,
pub gamma_coeff: Expression,
pub initial_conditions: (Expression, Expression),
}
#[derive(Debug, Clone)]
pub struct MathIdentity {
pub name: String,
pub lhs: Expression,
pub rhs: Expression,
pub conditions: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct SpecialValue {
pub input: String,
pub output: Expression,
pub latex_explanation: String,
}
#[derive(Debug, Clone)]
pub struct DomainRangeData {
pub domain: Domain,
pub range: Range,
pub singularities: Vec<Expression>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Domain {
Real,
Complex,
Integer,
PositiveInteger,
NonNegativeInteger,
Interval(Expression, Expression),
Union(Vec<Domain>),
}
#[derive(Debug, Clone)]
pub enum Range {
Real,
Integer,
PositiveInteger,
NonNegativeInteger,
Boolean,
Bounded(Expression, Expression),
Unbounded,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum EvaluationMethod {
Direct,
Recurrence,
Horner,
Series,
}