-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Process-Based Discrete Event Simulation library
--
-- Hasim is a library for process-based Discrete Event Simulation in
-- Haskell.
@package hasim
@version 0.1.2
-- | This module defines common types used everywhere in Hasim.
module Control.Hasim.Types
-- | The type that represents a time.
--
-- The type that represents a process identifier.
type Time = Double
type Id = Int
-- | This module takes care of defining processes and their actions.
module Control.Hasim.Process
-- | A Proc st pkt is a process that potentially accepts packets
-- of type pkt while maintaining state st.
data Proc pkt st
Proc :: IORef [(Acceptor pkt st, Maybe Runnable)] -> IORef (Maybe Runnable) -> IORef (Maybe Runnable) -> Id -> String -> IORef st -> Proc pkt st
-- | The list of acceptors with the continuations after the WithAcceptor.
acceptor :: Proc pkt st -> IORef [(Acceptor pkt st, Maybe Runnable)]
-- | The current wakeup function, if any.
wakeup :: Proc pkt st -> IORef (Maybe Runnable)
-- | The starting action. Loses its relevance after startup of the
-- simulation.
action :: Proc pkt st -> IORef (Maybe Runnable)
-- | The identifier of this process. Must be unique or hell will ensue.
-- Guaranteed to be unique by the creator of the process.
identifier :: Proc pkt st -> Id
-- | The name of the process. Determined by the user, may be any string.
-- Used for displaying information to the user.
name :: Proc pkt st -> String
-- | The state of the process.
currentState :: Proc pkt st -> IORef st
-- | An acceptor of a pkt is an AcceptResult, which is
-- either * Refuse if the packet is to be delivered at a later
-- time, or never, of course * Parallel act if a current
-- computation should not be suspended, but the state should be changed.
-- * Interrupt act if the current computation should be
-- suspended.
type Acceptor pkt st = pkt -> AcceptResult pkt st
-- | Existential type for a Proc. A Process is a Proc
-- pkt for some pkt.
data Process
Process :: (Proc pkt st) -> Process
-- | GADT for the primitive actions. These are the primitives Hasim
-- supports.
--
-- A PrimAction pkt st a is a primitive action where *
-- pkt is the packet type the associated Proc supports. *
-- st is the state of the associated Proc. * a
-- is the return type of the PrimAction. (this is why we need a GADT; the
-- return type varies for each primitive action).
--
-- (Unfortunately, the documentation for each constructor is not
-- available in the generated output due to a glitch in Haddock. You can
-- use the source, which is documented.)
data PrimAction :: * -> * -> * -> *
Ret :: a -> PrimAction pkt st a
Wait :: Time -> PrimAction pkt st ()
Send :: snd -> Proc snd st2 -> Time -> PrimAction pkt st Bool
Unwatch :: Proc rcv st2 -> PrimAction pkt st ()
WithAcceptor :: Acceptor pkt st -> Action pkt st () -> PrimAction pkt st ()
PopAcceptor :: PrimAction pkt st ()
PerformIO :: IO a -> PrimAction pkt st a
ObserveTime :: PrimAction pkt st Time
GetState :: PrimAction pkt st st
PutState :: st -> PrimAction pkt st ()
WaitForever :: PrimAction pkt st ()
-- | The Action GADT. This is a GADT with three parameters; an
-- Action pkt st a is a action where * pkt denotes the packet
-- type of incoming packets * st denotes the state that can be modified
-- and inspected * a denotes the result value of the Action
data Action :: * -> * -> * -> *
Prim :: PrimAction pkt st a -> Action pkt st a
-- | Existential type for the PrimAction type.
data Atom
Atom :: (PrimAction pkt st a) -> Atom
-- | A Runnable is an action that can be run. A Runnable has
-- three parameters: * The first is the process to which this
-- Runnable belongs. * The second is a primitive action to be run.
-- * The third is Maybe a continuation.
data Runnable
Run :: (Proc pkt st) -> (PrimAction pkt st a) -> (Maybe (a -> Runnable)) -> Runnable
-- | Finds the Process (existential type) belonging to a
-- Runnable.
runnable2process :: Runnable -> Process
-- | Converts a process with an action to a Runnable.
toRunnable :: Proc pkt st -> Action pkt st () -> Runnable
-- | The type of result of the Acceptor
data AcceptResult pkt st
Refuse :: AcceptResult pkt st
Parallel :: (st -> st) -> AcceptResult pkt st
Interrupt :: (Action pkt st ()) -> AcceptResult pkt st
instance MonadState st (Action pkt st)
instance MonadIO (Action pkt st)
instance Monad (Action pkt st)
instance Show (PrimAction pkt st a)
instance Ord Process
instance Eq Process
instance Show Process
instance Ord (Proc pkt st)
instance Eq (Proc pkt st)
instance Show (Proc pkt st)
-- | This module defines the Simulation monad, with functions to create
-- processes and set actions.
module Control.Hasim.Simulation
-- | Data type representing a simulation.
data Simulation
-- | The simulation monad called SimMonad. In this monad you can
-- define a simulation to be run.
type SimMonad a = StateT SimState IO a
unSim :: Simulation -> [Process]
-- | Make an anonymous process.
mkAnonProcess :: SimMonad (Proc pkt ())
-- | Make a process with a name. This name will be used in logging and
-- error messages
mkProcess :: String -> st -> SimMonad (Proc pkt st)
-- | Set the action of the process.
setAction :: Proc pkt st -> Action pkt st () -> SimMonad ()
-- | Create a simulation from a SimMonad (a simulation definition). If the
-- simulation is invalid, error will be called.
createSimulation :: SimMonad () -> IO Simulation
-- | This module defines a DES, which stands for Discrete Event
-- Set. There are functions for creating and inserting events.
--
-- For each process, an Event may be scheduled. This event
-- consists of a Time and a Runnable. There can be at most
-- one Event scheduled for each Process.
module Control.Hasim.DES
-- | Event. An event consists of a Time and a Runnable
data Event
-- | The Time at which the event takes place.
eTime :: Event -> Time
-- | The Runnable that should be run at this time
eRunnable :: Event -> Runnable
-- | The process of an Event
eProcess :: Event -> Process
-- | Discrete Event Set. A discrete event set is a data structure that
-- supports the operations update and removeNext.
data DES
-- | Create a new DES. For each Process, an Event is
-- scheduled at time 0 and with Runnable the associated
-- Runnable of the Process.
initDES :: [Process] -> IO DES
-- | An empty discrete event set.
emptyDES :: DES
-- | Is the Discrete Event Set empty?
isEmpty :: DES -> Bool
-- | Get an event with lowest time that will take place next. Returns a
-- tuple (evt, des) where evt is the next Event
-- and des is the new DES where this event is removed.
--
-- Calls error if the DES is empty.
removeNext :: DES -> (Event, DES)
-- | Schedule an event in a discrete event set. Note that an old event of
-- the same process is removed from the discrete event set.
update :: Time -> Runnable -> DES -> DES
instance Show DES
instance Show Event
-- | This module defines a WatchMap, a data structure that keeps
-- track of which processes watch which other processes.
module Control.Hasim.WatchMap
-- | A watch map. This data structure represents a relation on processes.
data WatchMap
-- | An empty WatchMap.
emptyWM :: WatchMap
-- | Find all p1 such that (p1, p2) is in the relation.
watchers :: WatchMap -> Process -> [Process]
-- | Add the tuple (p1, p2) to the relation.
register :: Process -> Process -> WatchMap -> WatchMap
-- | Remove the tuple (p1, p2) from the relation, if it existed.
unregister :: Process -> Process -> WatchMap -> WatchMap
-- | This module takes care of actually running a simulation.
module Control.Hasim.SimRun
-- | Run the simulation.
runSimulation :: Simulation -> IO ()
-- | Convenience functions and shadowing of API internals. Likely to be a
-- more stable interface then Control.Hasim.Process.
module Control.Hasim.Action
-- | Get the current time. The result will be nonnegative.
getTime :: Action pkt st Time
-- | Wait for a nonnegative time period.
wait :: Time -> Action pkt st ()
-- | Wait forever. This can be useful in case you want to block, waiting
-- for incoming packets.
waitForever :: Action pkt st ()
-- | Send a packet to a process, with a timeout time interval. Returns True
-- iff the packet was accepted.
send :: pkt -> Proc pkt st -> Time -> Action pkt' st' Bool
-- | Send a packet. Return True iff the packet was accepted immediately. Do
-- not wait in case the packet was not accepted.
trySend :: pkt -> Proc pkt st -> Action pkt' st' Bool
-- | Send a packet. Wait as long as necessary to deliver the packet.
sendBlock :: pkt -> Proc pkt st -> Action pkt' st' ()
-- | Execute an action with an Acceptor function
withAcceptor :: Acceptor pkt st -> Action pkt st () -> Action pkt st ()
-- | Execute an action without interruptions from incoming packets.
withoutInterruptions :: Action pkt st () -> Action pkt st ()
-- | Receive a packet. Block until the first packet comes in.
receive :: Action pkt st pkt
-- | Receive a packet, non-blocking.
poll :: Action pkt st (Maybe pkt)
-- | This module imports all relevant functions from Control.Hasim.* hiding
-- implementation details.
module Control.Hasim
-- | The type that represents a time.
--
-- The type that represents a process identifier.
type Time = Double
type Id = Int
-- | Data type representing a simulation.
data Simulation
-- | The simulation monad called SimMonad. In this monad you can
-- define a simulation to be run.
type SimMonad a = StateT SimState IO a
-- | Make an anonymous process.
mkAnonProcess :: SimMonad (Proc pkt ())
-- | Make a process with a name. This name will be used in logging and
-- error messages
mkProcess :: String -> st -> SimMonad (Proc pkt st)
-- | Set the action of the process.
setAction :: Proc pkt st -> Action pkt st () -> SimMonad ()
-- | Create a simulation from a SimMonad (a simulation definition). If the
-- simulation is invalid, error will be called.
createSimulation :: SimMonad () -> IO Simulation
-- | A Proc st pkt is a process that potentially accepts packets
-- of type pkt while maintaining state st.
data Proc pkt st
-- | An acceptor of a pkt is an AcceptResult, which is
-- either * Refuse if the packet is to be delivered at a later
-- time, or never, of course * Parallel act if a current
-- computation should not be suspended, but the state should be changed.
-- * Interrupt act if the current computation should be
-- suspended.
type Acceptor pkt st = pkt -> AcceptResult pkt st
-- | Existential type for a Proc. A Process is a Proc
-- pkt for some pkt.
data Process
-- | The Action GADT. This is a GADT with three parameters; an
-- Action pkt st a is a action where * pkt denotes the packet
-- type of incoming packets * st denotes the state that can be modified
-- and inspected * a denotes the result value of the Action
data Action :: * -> * -> * -> *
-- | The type of result of the Acceptor
data AcceptResult pkt st
Refuse :: AcceptResult pkt st
Parallel :: (st -> st) -> AcceptResult pkt st
Interrupt :: (Action pkt st ()) -> AcceptResult pkt st
-- | Run the simulation.
runSimulation :: Simulation -> IO ()