-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Equation solver and calculator à la metafont -- @package mfsolve @version 0.3.0 -- | This module implements an equation solver that solves and evaluates -- expressions on the fly. It is based on Prof. D.E.Knuth's -- metafont. 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 Expr datatype allows for calculations with constants and -- unknown variables. The Dependencies datatype contains all -- dependencies and known equations. -- --

Examples:

-- -- Let's define some variables. The SimpleVar type is a simple -- wrapper around String to provide nice output, since the Show -- instance for String outputs quotation marks. -- --
--   let [x, y, t, a] = map (makeVariable . SimpleVar) ["x", "y", "t", "a"]
--   
-- -- Solve linear equations: -- --
--   showVars $ flip execSolver noDeps $ do
--     2*x + y === 5
--     x - y   === 1
--   
-- --
--   x = 2.0
--   y = 1.0
--   
-- -- Solve for angle (pi/4): -- --
--   showVars $ flip execSolver noDeps $ sin(t) === 1/sqrt(2)
--   
-- --
--   t = 0.7853981633974484
--   
-- -- Solve for angle (pi/3) and amplitude: -- --
--   showVars $ flip execSolver noDeps $ do
--     a*sin(x) === sqrt 3
--     a*cos(x) === 1
--   
-- --
--   x = 1.0471975511965979
--   a = 2.0
--   
-- -- Allow nonlinear expression with unknown variables: -- --
--   showVars $ flip execSolver noDeps $ do
--     sin(sqrt(x)) === y
--     x === 2
--   
-- --
--   x = 2.0
--   y = 0.9877659459927355
--   
-- -- Find the angle and amplitude when using a rotation matrix: -- --
--   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
--   
-- --
--   x = 10.0
--   y = 10.0
--   t = 0.14189705460416402
--   a = 3.5355339059327373
--   
module Math.MFSolve -- | A simplified datatype representing an expression. This can be used to -- inspect the structure of a Expr, 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 (Num, Floating and Fractional) are -- provided, so doing calculations over Expr is more convenient. data Expr v n -- | A linear expression of several variables. For example: 2*a + 3*b + -- 2 would be represented as LinExpr 2 [(a, 2), (b, 3)]. data LinExpr v n LinExpr :: n -> [(v, n)] -> LinExpr v n data UnaryOp Sin :: UnaryOp Abs :: UnaryOp Recip :: UnaryOp Signum :: UnaryOp Exp :: UnaryOp Log :: UnaryOp Cos :: UnaryOp Cosh :: UnaryOp Atanh :: UnaryOp Tan :: UnaryOp Sinh :: UnaryOp Asin :: UnaryOp Acos :: UnaryOp Asinh :: UnaryOp Acosh :: UnaryOp Atan :: UnaryOp data BinaryOp Add :: BinaryOp 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 Expr to a SimpleExpr. 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 -- | 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 metafont: -- -- -- -- A dependend variable can only depend on other -- independend 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 ===, =&= and addEquation: 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 -> DepError v n -- | The equation was reduced to the redundant equation `0 == 0`, which -- means it doesn't add any information. RedundantEq :: DepError v n -- | An empty system of equations. noDeps :: Dependencies v n -- | addEquation d e: Add the equation e = 0 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. -- -- Important: 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 e_i, where e_i = 0. 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 () -- | Make the pairs of expressions on both sides equal. No error is -- signaled if the equation for one of the sides is Redundant -- 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 () -- | Get the dependencies from a state monad. Specialized version of -- get. 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 getKnown. getKnownM :: (MonadState (Dependencies v n) m, Hashable v, Eq v) => v -> m (Either [v] n) -- | Monadic version of varDefined. varDefinedM :: (MonadState (Dependencies v n) m, Hashable v, Eq v) => v -> m Bool -- | Monadic version of eliminate. 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 RedundantEq error. ignore :: MonadError (DepError v n) m => m () -> m () -- | A monad for solving equations. Basicly just a state and exception -- monad over Dependencies and DepError. 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) => Dependencies v n -> MFSolver v n a -> a -- | Show all variables and equations. Useful in combination with -- execSolver. 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 Dependencies and -- DepError. 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 :: (Show n, Show v, Typeable n, Typeable v, Monad m) => Dependencies v n -> MFSolverT v n m a -> m a instance Typeable DepError instance Eq BinaryOp instance Eq UnaryOp instance Generic UnaryOp instance Eq SimpleVar instance Ord SimpleVar instance Generic SimpleVar instance Generic (LinExpr v n) instance (Eq v, Eq n) => Eq (LinExpr v n) instance (Show v, Show n) => Show (LinExpr v n) instance Generic (NonLinExpr v n) instance Generic (Expr v n) instance Functor m => Functor (MFSolverT v n m) instance (Monad m, Functor m) => Applicative (MFSolverT v n m) instance Monad m => Monad (MFSolverT v n m) instance MonadIO m => MonadIO (MFSolverT v n m) instance Monad m => MonadState (Dependencies v n) (MFSolverT v n m) instance Monad m => MonadError (DepError v n) (MFSolverT v n m) instance MonadReader s m => MonadReader s (MFSolverT v n m) instance MonadWriter s m => MonadWriter s (MFSolverT v n m) instance MonadCont m => MonadCont (MFSolverT v n m) instance Datatype D1UnaryOp instance Constructor C1_0UnaryOp instance Constructor C1_1UnaryOp instance Constructor C1_2UnaryOp instance Constructor C1_3UnaryOp instance Constructor C1_4UnaryOp instance Constructor C1_5UnaryOp instance Constructor C1_6UnaryOp instance Constructor C1_7UnaryOp instance Constructor C1_8UnaryOp instance Constructor C1_9UnaryOp instance Constructor C1_10UnaryOp instance Constructor C1_11UnaryOp instance Constructor C1_12UnaryOp instance Constructor C1_13UnaryOp instance Constructor C1_14UnaryOp instance Constructor C1_15UnaryOp instance Datatype D1SimpleVar instance Constructor C1_0SimpleVar instance Datatype D1LinExpr instance Constructor C1_0LinExpr instance Datatype D1NonLinExpr instance Constructor C1_0NonLinExpr instance Constructor C1_1NonLinExpr instance Constructor C1_2NonLinExpr instance Datatype D1Expr instance Constructor C1_0Expr instance (Show n, Show v) => Show (DepError v n) instance (Show n, Floating n, Ord n, Ord v, Show v) => Show (Dependencies v n) instance (Floating n, Ord n, Ord v) => Floating (Expr v n) instance (Floating n, Ord n, Ord v) => Fractional (Expr v n) instance (Floating n, Ord n, Ord v) => Num (Expr v n) instance Show UnaryOp instance Show BinaryOp instance (Show v, Ord n, Show n, Num n, Eq n) => Show (SimpleExpr v n) instance MonadTrans (MFSolverT v n) instance (Ord n, Num n, Eq n, Show v, Show n) => Show (Expr v n) instance (Show v, Show n, Typeable v, Typeable n) => Exception (DepError v n) instance Show SimpleVar instance Hashable SimpleVar instance (Hashable v, Hashable n) => Hashable (Expr v n) instance Hashable UnaryOp instance (Hashable v, Hashable n) => Hashable (NonLinExpr v n) instance (Hashable v, Hashable n) => Hashable (LinExpr v n)