-- |
-- Module: Symtegration.Integration.Exponential
-- Description: Basic integration of exponential and logarithmic functions.
-- Copyright: Copyright 2024 Yoo Chung
-- License: Apache-2.0
-- Maintainer: dev@chungyc.org
--
-- Supports basic integration of exponential and logarithmic functions.
-- This does not support the integration of anything else,
-- even if it is trivial like integrating a constant.
module Symtegration.Integration.Exponential (integrate) where

import Data.Text (Text)
import Symtegration.Symbolic

-- $setup
-- >>> import Symtegration.Symbolic.Haskell

-- | Integrates exponential and logarithmic functions required by the 'Floating' type class.
--
-- >>> toHaskell <$> integrate "x" (exp "x")
-- Just "exp x"
-- >>> toHaskell <$> integrate "x" (log "x")
-- Just "x * log x - x"
integrate :: Text -> Expression -> Maybe Expression
integrate :: Text -> Expression -> Maybe Expression
integrate Text
_ (Number Integer
_) = Maybe Expression
forall a. Maybe a
Nothing
integrate Text
_ (Symbol Text
_) = Maybe Expression
forall a. Maybe a
Nothing
integrate Text
v e :: Expression
e@(Exp' (Symbol Text
s))
  | Text
v Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
s = Expression -> Maybe Expression
forall a. a -> Maybe a
Just Expression
e
  | Bool
otherwise = Maybe Expression
forall a. Maybe a
Nothing
integrate Text
v (Log' e :: Expression
e@(Symbol Text
s))
  | Text
v Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
s = Expression -> Maybe Expression
forall a. a -> Maybe a
Just (Expression -> Maybe Expression) -> Expression -> Maybe Expression
forall a b. (a -> b) -> a -> b
$ (Expression
e Expression -> Expression -> Expression
:*: Expression -> Expression
Log' Expression
e) Expression -> Expression -> Expression
:-: Expression
e
  | Bool
otherwise = Maybe Expression
forall a. Maybe a
Nothing
integrate Text
v e :: Expression
e@(Number Integer
n :**: Symbol Text
s)
  | Text
v Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
s = Expression -> Maybe Expression
forall a. a -> Maybe a
Just (Expression -> Maybe Expression) -> Expression -> Maybe Expression
forall a b. (a -> b) -> a -> b
$ Expression
c Expression -> Expression -> Expression
:*: Expression
e
  | Bool
otherwise = Maybe Expression
forall a. Maybe a
Nothing
  where
    c :: Expression
c = Integer -> Expression
Number Integer
1 Expression -> Expression -> Expression
:/: Expression -> Expression
Log' (Integer -> Expression
Number Integer
n)
integrate Text
v (LogBase' (Number Integer
n) (Symbol Text
s))
  | Text
v Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
s = (Expression -> Expression) -> Maybe Expression -> Maybe Expression
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Expression
x -> Expression
x Expression -> Expression -> Expression
:/: Expression -> Expression
Log' (Integer -> Expression
Number Integer
n)) (Maybe Expression -> Maybe Expression)
-> Maybe Expression -> Maybe Expression
forall a b. (a -> b) -> a -> b
$ Text -> Expression -> Maybe Expression
integrate Text
v (Expression -> Maybe Expression) -> Expression -> Maybe Expression
forall a b. (a -> b) -> a -> b
$ Expression -> Expression
Log' (Text -> Expression
Symbol Text
s)
integrate Text
_ Expression
_ = Maybe Expression
forall a. Maybe a
Nothing