-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Equation solver and calculator à la metafont
--   
--   An equation solver and calculator in the spirit of Metafont.
--   
--   Like metafont, it can solve linear equations, and evaluate nonlinear
--   expressions. In addition to metafont, it also solves for angles, and
--   makes the solution independend of the order of the equations.
@package mfsolve
@version 0.3.2.0


-- | This module implements an equation solver that solves and evaluates
--   expressions on the fly. It is based on Prof. D.E.Knuth's
--   <i>metafont</i>. The goal of mfsolve is to make the solver useful in
--   an interactive program, by enhancing the bidirectionality of the
--   solver. Like metafont, it can solve linear equations, and evaluate
--   nonlinear expressions. In addition to metafont, it also solves for
--   angles, and makes the solution independend of the order of the
--   equations.
--   
--   The <a>Expr</a> datatype allows for calculations with constants and
--   unknown variables. The <a>Dependencies</a> datatype contains all
--   dependencies and known equations.
--   
--   <h3>Examples:</h3>
--   
--   Let's define some variables. The <a>SimpleVar</a> type is a simple
--   wrapper around <a>String</a> to provide nice output, since the Show
--   instance for <a>String</a> outputs quotation marks.
--   
--   <pre>
--   let [x, y, t, a] = map (makeVariable . SimpleVar) ["x", "y", "t", "a"]
--   </pre>
--   
--   Solve linear equations:
--   
--   <pre>
--   showVars $ flip execSolver noDeps $ do
--     2*x + y === 5
--     x - y   === 1
--   </pre>
--   
--   <pre>
--   x = 2.0
--   y = 1.0
--   </pre>
--   
--   Solve for angle (pi/4):
--   
--   <pre>
--   showVars $ flip execSolver noDeps $ sin(t) === 1/sqrt(2)
--   </pre>
--   
--   <pre>
--   t = 0.7853981633974484
--   </pre>
--   
--   Solve for angle (pi/3) and amplitude:
--   
--   <pre>
--   showVars $ flip execSolver noDeps $ do
--     a*sin(x) === sqrt 3
--     a*cos(x) === 1
--   </pre>
--   
--   <pre>
--   x = 1.0471975511965979
--   a = 2.0
--   </pre>
--   
--   Allow nonlinear expression with unknown variables:
--   
--   <pre>
--   showVars $ flip execSolver noDeps $ do
--     sin(sqrt(x)) === y
--     x === 2
--   </pre>
--   
--   <pre>
--   x = 2.0
--   y = 0.9877659459927355
--   </pre>
--   
--   Find the angle and amplitude when using a rotation matrix:
--   
--   <pre>
--   showVars $ flip execSolver noDeps $ do
--     a*cos t*x - a*sin t*y === 30
--     a*sin t*x + a*cos t*y === 40
--     x === 10
--     y === 10
--   </pre>
--   
--   <pre>
--   x = 10.0
--   y = 10.0
--   t = 0.14189705460416402
--   a = 3.5355339059327373
--   </pre>
module Math.MFSolve

-- | A simplified datatype representing an expression. This can be used to
--   inspect the structure of a <a>Expr</a>, which is hidden.
data SimpleExpr v n
SEBin :: BinaryOp -> (SimpleExpr v n) -> (SimpleExpr v n) -> SimpleExpr v n
SEUn :: UnaryOp -> (SimpleExpr v n) -> SimpleExpr v n
Var :: v -> SimpleExpr v n
Const :: n -> SimpleExpr v n

-- | A mathematical expression of several variables. Several Numeric
--   instances (<a>Num</a>, <a>Floating</a> and <a>Fractional</a>) are
--   provided, so doing calculations over <a>Expr</a> is more convenient.
data Expr v n

-- | A linear expression of several variables. For example: <tt>2*a + 3*b +
--   2</tt> would be represented as <tt>LinExpr 2 [(a, 2), (b, 3)]</tt>.
data LinExpr v n
LinExpr :: n -> [(v, n)] -> LinExpr v n
data UnaryOp

-- | sine
Sin :: UnaryOp

-- | cosine
Cos :: UnaryOp

-- | absolute value
Abs :: UnaryOp

-- | reciprocal (1/x)
Recip :: UnaryOp

-- | sign
Signum :: UnaryOp

-- | natural exponential (e^x)
Exp :: UnaryOp

-- | natural logarithm (log x)
Log :: UnaryOp

-- | hyperbolic cosine
Cosh :: UnaryOp

-- | inverse hyperbolic tangent
Atanh :: UnaryOp

-- | tangent
Tan :: UnaryOp

-- | hyperbolic tangent
Tanh :: UnaryOp

-- | hyperbolic sine
Sinh :: UnaryOp

-- | inverse sine
Asin :: UnaryOp

-- | inverse cosine
Acos :: UnaryOp

-- | inverse hyperbolic sine
Asinh :: UnaryOp

-- | inverse hyperbolic cosine
Acosh :: UnaryOp

-- | inverse tangent
Atan :: UnaryOp
data BinaryOp

-- | Addition
Add :: BinaryOp

-- | Multiplication
Mul :: BinaryOp
newtype SimpleVar
SimpleVar :: String -> SimpleVar

-- | Create an expression from a variable
makeVariable :: Num n => v -> Expr v n

-- | Create an expression from a constant
makeConstant :: n -> Expr v n

-- | Evaluate the expression given a variable substitution.
evalExpr :: (Floating n) => (v -> n) -> SimpleExpr v n -> n

-- | Make a expression from a simple expression.
fromSimple :: (Floating n, Ord n, Ord v) => SimpleExpr v n -> Expr v n

-- | Convert an <a>Expr</a> to a <a>SimpleExpr</a>.
toSimple :: (Num n, Eq n) => Expr v n -> SimpleExpr v n

-- | evaluate a simple expression using the given substitution.
evalSimple :: Floating m => (n -> m) -> (v -> m) -> SimpleExpr v n -> m

-- | The expression contains the given variable.
hasVar :: (Num t, Eq v, Eq t) => v -> Expr v t -> Bool

-- | map a simple expression using the given substitution.
mapSimple :: (Floating m, Floating n) => (n -> m) -> (v -> u) -> SimpleExpr v n -> SimpleExpr u m

-- | map an expression using the given substitution.
mapExpr :: (Floating m, Floating n, Ord u, Ord v, Eq n, Ord m) => (n -> m) -> (v -> u) -> Expr v n -> Expr u m

-- | This hidden datatype represents a system of equations. It contains
--   linear dependencies on variables as well as nonlinear equations. The
--   following terminology is used from <i>metafont</i>:
--   
--   <ul>
--   <li><i>known variable</i>: A variable who's dependency is just a
--   number.</li>
--   <li><i>dependend variable</i>: A variable which depends linearly on
--   other variables.</li>
--   <li><i>independend variable</i>: any other variable.</li>
--   </ul>
--   
--   A <i>dependend</i> variable can only depend on other
--   <i>independend</i> variables. Nonlinear equations will be simplified
--   by substituting and evaluating known variables, or by reducing some
--   trigonometric equations to linear equations.
data Dependencies v n

-- | An error type for <a>===</a>, <a>=&amp;=</a> and <a>addEquation</a>:
data DepError v n

-- | The variable is not defined.
UndefinedVar :: v -> DepError v n

-- | The variable is defined but dependend an other variables.
UnknownVar :: v -> n -> DepError v n

-- | The equation was reduced to the impossible equation `a == 0` for
--   nonzero a, which means the equation is inconsistent with previous
--   equations.
InconsistentEq :: n -> (Expr v n) -> DepError v n

-- | The equation was reduced to the redundant equation `0 == 0`, which
--   means it doesn't add any information.
RedundantEq :: (Expr v n) -> DepError v n

-- | An empty system of equations.
noDeps :: Dependencies v n

-- | <tt>addEquation d e</tt>: Add the equation <tt>e = 0</tt> to the
--   system d.
addEquation :: (Hashable n, Hashable v, RealFrac (Phase n), Ord v, Floating n) => Dependencies v n -> Expr v n -> Either (DepError v n) (Dependencies v n)

-- | Eliminate an variable from the equations. Returns the eliminated
--   equations. Before elimination it performs substitution to minimize the
--   number of eliminated equations.
--   
--   <b>Important</b>: this function is still experimental and mostly
--   untested.
eliminate :: (Hashable n, Show n, Hashable v, RealFrac (Phase n), Ord v, Show v, Floating n) => Dependencies v n -> v -> (Dependencies v n, [Expr v n])

-- | Return the value of the variable, or a list of variables it depends
--   on. Only linear dependencies are shown.
getKnown :: (Eq v, Hashable v) => v -> Dependencies v n -> Either [v] n

-- | Return all known variables.
knownVars :: Dependencies v n -> [(v, n)]

-- | Return True if the variable is known or dependend.
varDefined :: (Eq v, Hashable v) => v -> Dependencies v n -> Bool

-- | Return all nonlinear equations <tt>e_i</tt>, where <tt>e_i = 0</tt>.
nonlinearEqs :: (Ord n, Ord v, Floating n) => Dependencies v n -> [Expr v n]

-- | Return all dependend variables with their dependencies.
dependendVars :: (Eq n) => Dependencies v n -> [(v, LinExpr v n)]

-- | Make the expressions on both sides equal
(===) :: (MonadState (Dependencies v n) m, MonadError (DepError v n) m, Eq v, Hashable v, Hashable n, RealFrac n, Floating n, Ord v) => Expr v n -> Expr v n -> m ()
infixr 1 ===

-- | Make the pairs of expressions on both sides equal. No error is
--   signaled if the equation for one of the sides is <tt>Redundant</tt>
--   for example in (x, 0) == (y, 0).
(=&=) :: (MonadState (Dependencies v n) m, MonadError (DepError v n) m, Eq v, Hashable v, Hashable n, RealFrac n, Floating n, Ord v) => (Expr v n, Expr v n) -> (Expr v n, Expr v n) -> m ()
infixr 1 =&=

-- | Get the dependencies from a state monad. Specialized version of
--   <a>get</a>.
dependencies :: (MonadState (Dependencies v n) m) => m (Dependencies v n)

-- | Return the value of the variable or throw an error.
getValue :: (MonadState (Dependencies v n) m, MonadError (DepError v n) m, Eq v, Hashable v) => v -> m n

-- | Monadic version of <a>getKnown</a>.
getKnownM :: (MonadState (Dependencies v n) m, Hashable v, Eq v) => v -> m (Either [v] n)

-- | Monadic version of <a>varDefined</a>.
varDefinedM :: (MonadState (Dependencies v n) m, Hashable v, Eq v) => v -> m Bool

-- | Monadic version of <a>eliminate</a>.
eliminateM :: (MonadState (Dependencies v n) m, Hashable n, Hashable v, Show n, Show v, RealFrac n, Ord v, Floating n) => v -> m [Expr v n]

-- | Succeed even when trowing a <a>RedundantEq</a> error.
ignore :: MonadError (DepError v n) m => m () -> m ()

-- | A monad for solving equations. Basicly just a state and exception
--   monad over <a>Dependencies</a> and <a>DepError</a>.
type MFSolver v n a = MFSolverT v n Identity a

-- | run the solver.
runSolver :: MFSolver v n a -> Dependencies v n -> Either (DepError v n) (a, Dependencies v n)

-- | Return the result of solving the equations or an error.
evalSolver :: MFSolver v n a -> Dependencies v n -> Either (DepError v n) a

-- | Run the solver and return the dependencies or an error.
execSolver :: MFSolver v n a -> Dependencies v n -> Either (DepError v n) (Dependencies v n)

-- | Return the result of solving the equations, or throw the error as an
--   exception.
unsafeSolve :: (Typeable n, Typeable v, Show n, Show v, Ord n, Num n) => Dependencies v n -> MFSolver v n a -> a

-- | Show all variables and equations. Useful in combination with
--   <a>execSolver</a>.
showVars :: (Show n, Show v, Ord n, Ord v, Floating n) => Either (DepError v n) (Dependencies v n) -> IO ()

-- | A monad transformer for solving equations. Basicly just a state and
--   exception monad transformer over <a>Dependencies</a> and
--   <a>DepError</a>.
data MFSolverT v n m a
runSolverT :: MFSolverT v n m a -> Dependencies v n -> m (Either (DepError v n) (a, Dependencies v n))

-- | Return the result of solving the equations or an error. Monadic
--   version.
evalSolverT :: Functor f => MFSolverT v n f b -> Dependencies v n -> f (Either (DepError v n) b)

-- | Run the solver and return the dependencies or an error. Monadic
--   version.
execSolverT :: Functor m => MFSolverT v n m a -> Dependencies v n -> m (Either (DepError v n) (Dependencies v n))

-- | Return the result of solving the equations, or throw the error as an
--   exception. Monadic version.
unsafeSolveT :: (Num n, Ord n, Show n, Show v, Typeable n, Typeable v, Monad m) => Dependencies v n -> MFSolverT v n m a -> m a
instance Control.Monad.Cont.Class.MonadCont m => Control.Monad.Cont.Class.MonadCont (Math.MFSolve.MFSolverT v n m)
instance Control.Monad.Writer.Class.MonadWriter s m => Control.Monad.Writer.Class.MonadWriter s (Math.MFSolve.MFSolverT v n m)
instance Control.Monad.Reader.Class.MonadReader s m => Control.Monad.Reader.Class.MonadReader s (Math.MFSolve.MFSolverT v n m)
instance GHC.Base.Monad m => Control.Monad.Error.Class.MonadError (Math.MFSolve.DepError v n) (Math.MFSolve.MFSolverT v n m)
instance GHC.Base.Monad m => Control.Monad.State.Class.MonadState (Math.MFSolve.Dependencies v n) (Math.MFSolve.MFSolverT v n m)
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Math.MFSolve.MFSolverT v n m)
instance GHC.Base.Monad m => GHC.Base.Monad (Math.MFSolve.MFSolverT v n m)
instance GHC.Base.Monad m => GHC.Base.Applicative (Math.MFSolve.MFSolverT v n m)
instance GHC.Base.Functor m => GHC.Base.Functor (Math.MFSolve.MFSolverT v n m)
instance GHC.Generics.Generic (Math.MFSolve.Expr v n)
instance GHC.Generics.Generic (Math.MFSolve.NonLinExpr v n)
instance (GHC.Show.Show v, GHC.Show.Show n) => GHC.Show.Show (Math.MFSolve.LinExpr v n)
instance (GHC.Classes.Eq v, GHC.Classes.Eq n) => GHC.Classes.Eq (Math.MFSolve.LinExpr v n)
instance GHC.Generics.Generic (Math.MFSolve.LinExpr v n)
instance GHC.Generics.Generic Math.MFSolve.SimpleVar
instance GHC.Classes.Ord Math.MFSolve.SimpleVar
instance GHC.Classes.Eq Math.MFSolve.SimpleVar
instance GHC.Generics.Generic Math.MFSolve.UnaryOp
instance GHC.Classes.Eq Math.MFSolve.UnaryOp
instance GHC.Classes.Eq Math.MFSolve.BinaryOp
instance (Data.Hashable.Class.Hashable v, Data.Hashable.Class.Hashable n) => Data.Hashable.Class.Hashable (Math.MFSolve.LinExpr v n)
instance (Data.Hashable.Class.Hashable v, Data.Hashable.Class.Hashable n) => Data.Hashable.Class.Hashable (Math.MFSolve.NonLinExpr v n)
instance Data.Hashable.Class.Hashable Math.MFSolve.UnaryOp
instance (Data.Hashable.Class.Hashable v, Data.Hashable.Class.Hashable n) => Data.Hashable.Class.Hashable (Math.MFSolve.Expr v n)
instance Data.Hashable.Class.Hashable Math.MFSolve.SimpleVar
instance GHC.Show.Show Math.MFSolve.SimpleVar
instance (GHC.Classes.Ord n, GHC.Num.Num n, GHC.Show.Show v, GHC.Show.Show n, Data.Typeable.Internal.Typeable v, Data.Typeable.Internal.Typeable n) => GHC.Exception.Exception (Math.MFSolve.DepError v n)
instance (GHC.Classes.Ord n, GHC.Num.Num n, GHC.Classes.Eq n, GHC.Show.Show v, GHC.Show.Show n) => GHC.Show.Show (Math.MFSolve.Expr v n)
instance Control.Monad.Trans.Class.MonadTrans (Math.MFSolve.MFSolverT v n)
instance (GHC.Show.Show v, GHC.Classes.Ord n, GHC.Show.Show n, GHC.Num.Num n, GHC.Classes.Eq n) => GHC.Show.Show (Math.MFSolve.SimpleExpr v n)
instance GHC.Show.Show Math.MFSolve.BinaryOp
instance GHC.Show.Show Math.MFSolve.UnaryOp
instance (GHC.Float.Floating n, GHC.Classes.Ord n, GHC.Classes.Ord v) => GHC.Num.Num (Math.MFSolve.Expr v n)
instance (GHC.Float.Floating n, GHC.Classes.Ord n, GHC.Classes.Ord v) => GHC.Real.Fractional (Math.MFSolve.Expr v n)
instance (GHC.Float.Floating n, GHC.Classes.Ord n, GHC.Classes.Ord v) => GHC.Float.Floating (Math.MFSolve.Expr v n)
instance (GHC.Show.Show n, GHC.Float.Floating n, GHC.Classes.Ord n, GHC.Classes.Ord v, GHC.Show.Show v) => GHC.Show.Show (Math.MFSolve.Dependencies v n)
instance (GHC.Num.Num n, GHC.Classes.Ord n, GHC.Show.Show n, GHC.Show.Show v) => GHC.Show.Show (Math.MFSolve.DepError v n)
