module Simulation.Aivika.Lattice.Internal.Estimate
(
Estimate(..),
EstimateLift(..),
invokeEstimate,
runEstimateInStartTime,
estimateTime,
catchEstimate,
finallyEstimate,
throwEstimate,
traceEstimate) where
import Control.Exception
import Control.Monad
import Control.Monad.Trans
import Control.Monad.Fix
import Control.Applicative
import Debug.Trace (trace)
import Simulation.Aivika.Trans.Exception
import Simulation.Aivika.Trans.Comp
import Simulation.Aivika.Trans.DES
import Simulation.Aivika.Trans.Internal.Types
import Simulation.Aivika.Trans.Parameter
import Simulation.Aivika.Trans.Dynamics
import Simulation.Aivika.Trans.Event
import Simulation.Aivika.Lattice.Internal.LIO
newtype Estimate m a = Estimate (Point m -> m a)
invokeEstimate :: Point m -> Estimate m a -> m a
invokeEstimate p (Estimate m) = m p
instance Monad m => Monad (Estimate m) where
return a = Estimate $ \p -> return a
(Estimate m) >>= k =
Estimate $ \p ->
do a <- m p
let Estimate m' = k a
m' p
instance Functor m => Functor (Estimate m) where
fmap f (Estimate x) = Estimate $ \p -> fmap f $ x p
instance Applicative m => Applicative (Estimate m) where
pure = Estimate . const . pure
(Estimate x) <*> (Estimate y) = Estimate $ \p -> x p <*> y p
instance MonadTrans Estimate where
lift = Estimate . const
instance MonadIO m => MonadIO (Estimate m) where
liftIO = Estimate . const . liftIO
instance MonadFix m => MonadFix (Estimate m) where
mfix f =
Estimate $ \p ->
do { rec { a <- invokeEstimate p (f a) }; return a }
instance Monad m => MonadCompTrans Estimate m where
liftComp = Estimate . const
class EstimateLift t m where
liftEstimate :: Estimate m a -> t m a
instance Monad m => EstimateLift Estimate m where
liftEstimate = id
instance Monad m => ParameterLift Estimate m where
liftParameter (Parameter x) = Estimate $ x . pointRun
catchEstimate :: (MonadException m, Exception e) => Estimate m a -> (e -> Estimate m a) -> Estimate m a
catchEstimate (Estimate m) h =
Estimate $ \p ->
catchComp (m p) $ \e ->
let Estimate m' = h e in m' p
finallyEstimate :: MonadException m => Estimate m a -> Estimate m b -> Estimate m a
finallyEstimate (Estimate m) (Estimate m') =
Estimate $ \p ->
finallyComp (m p) (m' p)
throwEstimate :: (MonadException m, Exception e) => e -> Estimate m a
throwEstimate e =
Estimate $ \p ->
throwComp e
runEstimateInStartTime :: MonadDES m => Estimate m a -> Simulation m a
runEstimateInStartTime (Estimate m) = runEventInStartTime (Event m)
estimateTime :: MonadDES m => Estimate m Double
estimateTime = Estimate $ return . pointTime
traceEstimate :: String -> Estimate LIO a -> Estimate LIO a
traceEstimate message m =
Estimate $ \p ->
LIO $ \ps ->
trace ("t = " ++ show (pointTime p) ++
", lattice time index = " ++ show (lioTimeIndex ps) ++
", lattice member index = " ++ show (lioMemberIndex ps) ++
": " ++ message) $
invokeLIO ps $
invokeEstimate p m