ihateintegrals 0.1.2

A computer algebra library for solving integrals.
Documentation
use std::rc::Rc;

use crate::{
    argument::Argument,
    convenience_expressions::{abs, power, sqrt},
    expressions::{
        product::product_of, sum::sum_of, trig_expression::TrigFn, Derivative, Exponent,
        Expression, Fraction, Integer, Negation, TrigExp,
    },
};

use super::DerivationRule;

pub struct DerivativeOfTrig {}

impl DerivationRule for DerivativeOfTrig {
    fn apply(&self, input: Expression) -> Vec<(Expression, Rc<Argument>)> {
        let derivative = match input {
            Expression::Derivative(ref d) => d,
            _ => return vec![],
        };

        let Expression::Trig(ref t) = derivative.exp() else {
            return vec![];
        };

        if t.exp() != derivative.relative_to() {
            return vec![];
        }

        let exp = t.exp();

        let result = match t.operation {
            TrigFn::Sin => TrigExp::of(TrigFn::Cos, exp),
            TrigFn::Cos => Negation::of(TrigExp::of(TrigFn::Sin, exp)),
            TrigFn::Tan => Exponent::of(TrigExp::of(TrigFn::Sec, exp), Integer::of(2)),
            TrigFn::Sec => product_of(&[
                TrigExp::of(TrigFn::Sec, exp.clone()),
                TrigExp::of(TrigFn::Tan, exp.clone()),
            ]),
            TrigFn::Csc => Negation::of(product_of(&[
                TrigExp::of(TrigFn::Csc, exp.clone()),
                TrigExp::of(TrigFn::Cot, exp.clone()),
            ])),
            TrigFn::Cot => Negation::of(Exponent::of(
                TrigExp::of(TrigFn::Csc, exp.clone()),
                Integer::of(2),
            )),
            TrigFn::ArcSin => Fraction::of(
                Derivative::of(exp.clone(), derivative.relative_to()),
                sqrt(sum_of(&[
                    Integer::of(1),
                    Negation::of(Exponent::of(exp.clone(), Integer::of(2))),
                ])),
            ),
            TrigFn::ArcCos => Fraction::of(
                Negation::of(Derivative::of(exp.clone(), derivative.relative_to())),
                sqrt(sum_of(&[
                    Integer::of(1),
                    Negation::of(Exponent::of(exp.clone(), Integer::of(2))),
                ])),
            ),
            TrigFn::ArcTan => Fraction::of(
                Derivative::of(exp.clone(), derivative.relative_to()),
                sum_of(&[Integer::of(1), Exponent::of(exp, Integer::of(2))]),
            ),
            TrigFn::ArcCot => Fraction::of(
                Negation::of(Derivative::of(exp.clone(), derivative.relative_to())),
                sum_of(&[Integer::of(1), Exponent::of(exp.clone(), Integer::of(2))]),
            ),
            TrigFn::ArcSec => Fraction::of(
                Integer::of(1),
                product_of(&[
                    abs(exp.clone()),
                    sqrt(sum_of(&[
                        power(exp.clone(), Integer::of(2)),
                        Negation::of(Integer::of(1)),
                    ])),
                ]),
            ),
            TrigFn::ArcCsc => Negation::of(Fraction::of(
                Integer::of(1),
                product_of(&[
                    abs(exp.clone()),
                    sqrt(sum_of(&[
                        power(exp.clone(), Integer::of(2)),
                        Negation::of(Integer::of(1)),
                    ])),
                ]),
            )),
        };

        vec![(
            result,
            Argument::new(
                String::from("Apply trig derivation rule"),
                vec![input],
                self.name(),
            ),
        )]
    }
    fn name(&self) -> String {
        String::from("DerivativeOfTrig")
    }
}