module Simulation.Aivika.Trans.Internal.Simulation
(
Simulation(..),
SimulationLift(..),
invokeSimulation,
runSimulation,
runSimulations,
runSimulationByIndex,
catchSimulation,
finallySimulation,
throwSimulation,
SimulationException(..),
SimulationAbort(..)) where
import Control.Exception
import Control.Monad
import Control.Monad.Trans
import Control.Monad.Fix
import Control.Applicative
import Simulation.Aivika.Trans.Exception
import Simulation.Aivika.Trans.Generator
import Simulation.Aivika.Trans.Comp
import Simulation.Aivika.Trans.DES
import Simulation.Aivika.Trans.Internal.Types
import Simulation.Aivika.Trans.Internal.Specs
import Simulation.Aivika.Trans.Internal.Parameter
import Simulation.Aivika.Simulation (SimulationException, SimulationAbort)
instance Monad m => Monad (Simulation m) where
return a = Simulation $ \r -> return a
(Simulation m) >>= k =
Simulation $ \r ->
do a <- m r
let Simulation m' = k a
m' r
runSimulation :: MonadDES m => Simulation m a -> Specs m -> m a
runSimulation (Simulation m) sc =
do q <- newEventQueue sc
g <- newGenerator $ spcGeneratorType sc
m Run { runSpecs = sc,
runIndex = 1,
runCount = 1,
runEventQueue = q,
runGenerator = g }
runSimulationByIndex :: MonadDES m
=> Simulation m a
-> Specs m
-> Int
-> Int
-> m a
runSimulationByIndex (Simulation m) sc runs index =
do q <- newEventQueue sc
g <- newGenerator $ spcGeneratorType sc
m Run { runSpecs = sc,
runIndex = index,
runCount = runs,
runEventQueue = q,
runGenerator = g }
runSimulations :: MonadDES m => Simulation m a -> Specs m -> Int -> [m a]
runSimulations (Simulation m) sc runs = map f [1 .. runs]
where f i = do q <- newEventQueue sc
g <- newGenerator $ spcGeneratorType sc
m Run { runSpecs = sc,
runIndex = i,
runCount = runs,
runEventQueue = q,
runGenerator = g }
instance Functor m => Functor (Simulation m) where
fmap f (Simulation x) = Simulation $ \r -> fmap f $ x r
instance Applicative m => Applicative (Simulation m) where
pure = Simulation . const . pure
(Simulation x) <*> (Simulation y) = Simulation $ \r -> x r <*> y r
liftMS :: Monad m => (a -> b) -> Simulation m a -> Simulation m b
liftMS f (Simulation x) =
Simulation $ \r -> do { a <- x r; return $ f a }
instance MonadTrans Simulation where
lift = Simulation . const
instance Monad m => MonadCompTrans Simulation m where
liftComp = Simulation . const
instance MonadIO m => MonadIO (Simulation m) where
liftIO = Simulation . const . liftIO
class SimulationLift t m where
liftSimulation :: Simulation m a -> t m a
instance Monad m => SimulationLift Simulation m where
liftSimulation = id
instance Monad m => ParameterLift Simulation m where
liftParameter (Parameter x) = Simulation x
catchSimulation :: (MonadException m, Exception e) => Simulation m a -> (e -> Simulation m a) -> Simulation m a
catchSimulation (Simulation m) h =
Simulation $ \r ->
catchComp (m r) $ \e ->
let Simulation m' = h e in m' r
finallySimulation :: MonadException m => Simulation m a -> Simulation m b -> Simulation m a
finallySimulation (Simulation m) (Simulation m') =
Simulation $ \r ->
finallyComp (m r) (m' r)
throwSimulation :: (MonadException m, Exception e) => e -> Simulation m a
throwSimulation e =
Simulation $ \r ->
throwComp e
instance MonadFix m => MonadFix (Simulation m) where
mfix f =
Simulation $ \r ->
do { rec { a <- invokeSimulation r (f a) }; return a }