{-# LANGUAGE TypeFamilies, MultiParamTypeClasses, FunctionalDependencies #-}
module Simulation.Aivika.QueueStrategy where
import Control.Monad.Trans
import Data.Maybe
import Simulation.Aivika.Parameter
import Simulation.Aivika.Parameter.Random
import Simulation.Aivika.Simulation
import Simulation.Aivika.Event
import Simulation.Aivika.DoubleLinkedList
import qualified Simulation.Aivika.PriorityQueue as PQ
import qualified Simulation.Aivika.Vector as V
class QueueStrategy s where
data StrategyQueue s :: * -> *
newStrategyQueue :: s
-> Simulation (StrategyQueue s i)
strategyQueueNull :: StrategyQueue s i
-> Event Bool
class QueueStrategy s => DequeueStrategy s where
strategyDequeue :: StrategyQueue s i
-> Event i
class DequeueStrategy s => EnqueueStrategy s where
strategyEnqueue :: StrategyQueue s i
-> i
-> Event ()
class DequeueStrategy s => PriorityQueueStrategy s p | s -> p where
strategyEnqueueWithPriority :: StrategyQueue s i
-> p
-> i
-> Event ()
class DequeueStrategy s => DeletingQueueStrategy s where
strategyQueueDelete :: Eq i
=> StrategyQueue s i
-> i
-> Event Bool
strategyQueueDelete s i = fmap isJust $ strategyQueueDeleteBy s (== i)
strategyQueueDeleteBy :: StrategyQueue s i
-> (i -> Bool)
-> Event (Maybe i)
strategyQueueContains :: Eq i
=> StrategyQueue s i
-> i
-> Event Bool
strategyQueueContains s i = fmap isJust $ strategyQueueContainsBy s (== i)
strategyQueueContainsBy :: StrategyQueue s i
-> (i -> Bool)
-> Event (Maybe i)
data FCFS = FCFS deriving (Eq, Ord, Show)
data LCFS = LCFS deriving (Eq, Ord, Show)
data SIRO = SIRO deriving (Eq, Ord, Show)
data StaticPriorities = StaticPriorities deriving (Eq, Ord, Show)
instance QueueStrategy FCFS where
newtype StrategyQueue FCFS i = FCFSQueue (DoubleLinkedList i)
newStrategyQueue s = fmap FCFSQueue $ liftIO newList
strategyQueueNull (FCFSQueue q) = liftIO $ listNull q
instance DequeueStrategy FCFS where
strategyDequeue (FCFSQueue q) =
liftIO $
do i <- listFirst q
listRemoveFirst q
return i
instance EnqueueStrategy FCFS where
strategyEnqueue (FCFSQueue q) i = liftIO $ listAddLast q i
instance DeletingQueueStrategy FCFS where
strategyQueueDeleteBy (FCFSQueue q) p = liftIO $ listRemoveBy q p
strategyQueueContainsBy (FCFSQueue q) p = liftIO $ listContainsBy q p
instance QueueStrategy LCFS where
newtype StrategyQueue LCFS i = LCFSQueue (DoubleLinkedList i)
newStrategyQueue s = fmap LCFSQueue $ liftIO newList
strategyQueueNull (LCFSQueue q) = liftIO $ listNull q
instance DequeueStrategy LCFS where
strategyDequeue (LCFSQueue q) =
liftIO $
do i <- listFirst q
listRemoveFirst q
return i
instance EnqueueStrategy LCFS where
strategyEnqueue (LCFSQueue q) i = liftIO $ listInsertFirst q i
instance DeletingQueueStrategy LCFS where
strategyQueueDeleteBy (LCFSQueue q) p = liftIO $ listRemoveBy q p
strategyQueueContainsBy (LCFSQueue q) p = liftIO $ listContainsBy q p
instance QueueStrategy StaticPriorities where
newtype StrategyQueue StaticPriorities i = StaticPriorityQueue (PQ.PriorityQueue i)
newStrategyQueue s = fmap StaticPriorityQueue $ liftIO PQ.newQueue
strategyQueueNull (StaticPriorityQueue q) = liftIO $ PQ.queueNull q
instance DequeueStrategy StaticPriorities where
strategyDequeue (StaticPriorityQueue q) =
liftIO $
do (_, i) <- PQ.queueFront q
PQ.dequeue q
return i
instance PriorityQueueStrategy StaticPriorities Double where
strategyEnqueueWithPriority (StaticPriorityQueue q) p i = liftIO $ PQ.enqueue q p i
instance DeletingQueueStrategy StaticPriorities where
strategyQueueDeleteBy (StaticPriorityQueue q) p = liftIO $ PQ.queueDeleteBy q p
strategyQueueContainsBy (StaticPriorityQueue q) p = liftIO $ PQ.queueContainsBy q p
instance QueueStrategy SIRO where
newtype StrategyQueue SIRO i = SIROQueue (V.Vector i)
newStrategyQueue s = fmap SIROQueue $ liftIO V.newVector
strategyQueueNull (SIROQueue q) =
liftIO $
do n <- V.vectorCount q
return (n == 0)
instance DequeueStrategy SIRO where
strategyDequeue (SIROQueue q) =
do n <- liftIO $ V.vectorCount q
i <- liftParameter $ randomUniformInt 0 (n - 1)
x <- liftIO $ V.readVector q i
liftIO $ V.vectorDeleteAt q i
return x
instance EnqueueStrategy SIRO where
strategyEnqueue (SIROQueue q) i = liftIO $ V.appendVector q i
instance DeletingQueueStrategy SIRO where
strategyQueueDeleteBy (SIROQueue q) p = liftIO $ V.vectorDeleteBy q p
strategyQueueContainsBy (SIROQueue q) p = liftIO $ V.vectorContainsBy q p