{-# LANGUAGE FlexibleInstances #-} -- | -- Module : Simulation.Aivika.Results.Transform -- Copyright : Copyright (c) 2009-2017, David Sorokin -- License : BSD3 -- Maintainer : David Sorokin -- Stability : experimental -- Tested with: GHC 8.0.1 -- -- The module defines useful result transformations that can -- be used in simulation experiments. -- module Simulation.Aivika.Results.Transform (-- * Basic Class Type ResultTransformer(..), -- * Sampling Statistics SamplingStats(..), samplingStatsCount, samplingStatsMin, samplingStatsMax, samplingStatsMean, samplingStatsMean2, samplingStatsVariance, samplingStatsDeviation, -- * Time-dependent Statistics TimingStats(..), timingStatsCount, timingStatsMin, timingStatsMax, timingStatsMean, timingStatsVariance, timingStatsDeviation, timingStatsMinTime, timingStatsMaxTime, timingStatsStartTime, timingStatsLastTime, timingStatsSum, timingStatsSum2, -- * Sampling-based Counter SamplingCounter(..), samplingCounterValue, samplingCounterStats, -- * Time-dependent Counter TimingCounter(..), timingCounterValue, timingCounterStats, -- * Queue Queue(..), enqueueStrategy, enqueueStoringStrategy, dequeueStrategy, queueNull, queueFull, queueMaxCount, queueCount, queueCountStats, enqueueCount, enqueueLostCount, enqueueStoreCount, dequeueCount, dequeueExtractCount, queueLoadFactor, enqueueRate, enqueueStoreRate, dequeueRate, dequeueExtractRate, queueWaitTime, queueTotalWaitTime, enqueueWaitTime, dequeueWaitTime, queueRate, -- * Arrival Timer ArrivalTimer(..), arrivalProcessingTime, -- * Server Server(..), serverInitState, serverState, serverTotalInputWaitTime, serverTotalProcessingTime, serverTotalOutputWaitTime, serverTotalPreemptionTime, serverInputWaitTime, serverProcessingTime, serverOutputWaitTime, serverPreemptionTime, serverInputWaitFactor, serverProcessingFactor, serverOutputWaitFactor, serverPreemptionFactor, -- * Activity Activity(..), activityInitState, activityState, activityTotalUtilisationTime, activityTotalIdleTime, activityTotalPreemptionTime, activityUtilisationTime, activityIdleTime, activityPreemptionTime, activityUtilisationFactor, activityIdleFactor, activityPreemptionFactor, -- * Resource Resource(..), resourceCount, resourceCountStats, resourceUtilisationCount, resourceUtilisationCountStats, resourceQueueCount, resourceQueueCountStats, resourceTotalWaitTime, resourceWaitTime, -- * Operation Operation(..), operationTotalUtilisationTime, operationTotalPreemptionTime, operationUtilisationTime, operationPreemptionTime, operationUtilisationFactor, operationPreemptionFactor) where import Control.Arrow import Simulation.Aivika.Results import Simulation.Aivika.Results.Locale -- | Something that can transform the results. class ResultTransformer a where -- | Return the result transform. tr :: a -> ResultTransform -- | Represents a statistics based upon observations. newtype SamplingStats = SamplingStats ResultTransform instance ResultTransformer SamplingStats where tr (SamplingStats a) = a -- | The total number of samples. samplingStatsCount :: SamplingStats -> ResultTransform samplingStatsCount (SamplingStats a) = a >>> expandResults >>> resultById SamplingStatsCountId -- | The minimum value among the samples. samplingStatsMin :: SamplingStats -> ResultTransform samplingStatsMin (SamplingStats a) = a >>> expandResults >>> resultById SamplingStatsMinId -- | The maximum value among the samples. samplingStatsMax :: SamplingStats -> ResultTransform samplingStatsMax (SamplingStats a) = a >>> expandResults >>> resultById SamplingStatsMaxId -- | The average value. samplingStatsMean :: SamplingStats -> ResultTransform samplingStatsMean (SamplingStats a) = a >>> expandResults >>> resultById SamplingStatsMeanId -- | The average square value. samplingStatsMean2 :: SamplingStats -> ResultTransform samplingStatsMean2 (SamplingStats a) = a >>> expandResults >>> resultById SamplingStatsMean2Id -- | Return tha variance. samplingStatsVariance :: SamplingStats -> ResultTransform samplingStatsVariance (SamplingStats a) = a >>> expandResults >>> resultById SamplingStatsVarianceId -- | Return the deviation. samplingStatsDeviation :: SamplingStats -> ResultTransform samplingStatsDeviation (SamplingStats a) = a >>> expandResults >>> resultById SamplingStatsDeviationId -- | A counter for which the statistics is collected too. newtype SamplingCounter = SamplingCounter ResultTransform instance ResultTransformer SamplingCounter where tr (SamplingCounter a) = a -- | The counter value. samplingCounterValue :: SamplingCounter -> ResultTransform samplingCounterValue (SamplingCounter a) = a >>> resultById SamplingCounterValueId -- | The counter statistics. samplingCounterStats :: SamplingCounter -> SamplingStats samplingCounterStats (SamplingCounter a) = SamplingStats (a >>> resultById SamplingCounterStatsId) -- | The time-dependent statistics. newtype TimingStats = TimingStats ResultTransform instance ResultTransformer TimingStats where tr (TimingStats a) = a -- | Return the number of samples. timingStatsCount :: TimingStats -> ResultTransform timingStatsCount (TimingStats a) = a >>> expandResults >>> resultById TimingStatsCountId -- | Return the minimum value. timingStatsMin :: TimingStats -> ResultTransform timingStatsMin (TimingStats a) = a >>> expandResults >>> resultById TimingStatsMinId -- | Return the maximum value. timingStatsMax :: TimingStats -> ResultTransform timingStatsMax (TimingStats a) = a >>> expandResults >>> resultById TimingStatsMaxId -- | Return the average value. timingStatsMean :: TimingStats -> ResultTransform timingStatsMean (TimingStats a) = a >>> expandResults >>> resultById TimingStatsMeanId -- | Return the variance. timingStatsVariance :: TimingStats -> ResultTransform timingStatsVariance (TimingStats a) = a >>> expandResults >>> resultById TimingStatsVarianceId -- | Return the deviation. timingStatsDeviation :: TimingStats -> ResultTransform timingStatsDeviation (TimingStats a) = a >>> expandResults >>> resultById TimingStatsDeviationId -- | Return the time at which the minimum is attained. timingStatsMinTime :: TimingStats -> ResultTransform timingStatsMinTime (TimingStats a) = a >>> expandResults >>> resultById TimingStatsMinTimeId -- | Return the time at which the maximum is attained. timingStatsMaxTime :: TimingStats -> ResultTransform timingStatsMaxTime (TimingStats a) = a >>> expandResults >>> resultById TimingStatsMaxTimeId -- | Return the start time of sampling. timingStatsStartTime :: TimingStats -> ResultTransform timingStatsStartTime (TimingStats a) = a >>> expandResults >>> resultById TimingStatsStartTimeId -- | Return the last time of sampling. timingStatsLastTime :: TimingStats -> ResultTransform timingStatsLastTime (TimingStats a) = a >>> expandResults >>> resultById TimingStatsLastTimeId -- | Return the sum of values. timingStatsSum :: TimingStats -> ResultTransform timingStatsSum (TimingStats a) = a >>> expandResults >>> resultById TimingStatsSumId -- | Return the sum of square values. timingStatsSum2 :: TimingStats -> ResultTransform timingStatsSum2 (TimingStats a) = a >>> expandResults >>> resultById TimingStatsSum2Id -- | A time-dependent counter that collects the statistics too. newtype TimingCounter = TimingCounter ResultTransform instance ResultTransformer TimingCounter where tr (TimingCounter a) = a -- | The counter value. timingCounterValue :: TimingCounter -> ResultTransform timingCounterValue (TimingCounter a) = a >>> resultById TimingCounterValueId -- | The counter statistics. timingCounterStats :: TimingCounter -> TimingStats timingCounterStats (TimingCounter a) = TimingStats (a >>> resultById TimingCounterStatsId) -- | Represents either finite or infinite queue. newtype Queue = Queue ResultTransform instance ResultTransformer Queue where tr (Queue a) = a -- | The strategy applied to the enqueueing (input) processes when the finite queue is full. enqueueStrategy :: Queue -> ResultTransform enqueueStrategy (Queue a) = a >>> resultById EnqueueStrategyId -- | The strategy applied when storing (in memory) items in the queue. enqueueStoringStrategy :: Queue -> ResultTransform enqueueStoringStrategy (Queue a) = a >>> resultById EnqueueStoringStrategyId -- | The strategy applied to the dequeueing (output) processes when the queue is empty. dequeueStrategy :: Queue -> ResultTransform dequeueStrategy (Queue a) = a >>> resultById DequeueStrategyId -- | Test whether the queue is empty. queueNull :: Queue -> ResultTransform queueNull (Queue a) = a >>> resultById QueueNullId -- | Test whether the finite queue is full. queueFull :: Queue -> ResultTransform queueFull (Queue a) = a >>> resultById QueueFullId -- | The finite queue capacity. queueMaxCount :: Queue -> ResultTransform queueMaxCount (Queue a) = a >>> resultById QueueMaxCountId -- | Return the current queue size. queueCount :: Queue -> ResultTransform queueCount (Queue a) = a >>> resultById QueueCountId -- | Return the queue size statistics. queueCountStats :: Queue -> TimingStats queueCountStats (Queue a) = TimingStats (a >>> resultById QueueCountStatsId) -- | Return the total number of input items that were enqueued in the finite queue. enqueueCount :: Queue -> ResultTransform enqueueCount (Queue a) = a >>> resultById EnqueueCountId -- | Return the number of lost items for the finite queue. enqueueLostCount :: Queue -> ResultTransform enqueueLostCount (Queue a) = a >>> resultById EnqueueLostCountId -- | Return the total number of input items that were stored. enqueueStoreCount :: Queue -> ResultTransform enqueueStoreCount (Queue a) = a >>> resultById EnqueueStoreCountId -- | Return the total number of requests for dequeueing the items, not taking -- into account the failed attempts to dequeue immediately without suspension. dequeueCount :: Queue -> ResultTransform dequeueCount (Queue a) = a >>> resultById DequeueCountId -- | Return the total number of output items that were actually dequeued. dequeueExtractCount :: Queue -> ResultTransform dequeueExtractCount (Queue a) = a >>> resultById DequeueExtractCountId -- | Return the load factor: the finite queue size divided by its capacity. queueLoadFactor :: Queue -> ResultTransform queueLoadFactor (Queue a) = a >>> resultById QueueLoadFactorId -- | Return the rate of the input items that were enqueued in the finite queue: -- how many items per time. enqueueRate :: Queue -> ResultTransform enqueueRate (Queue a) = a >>> resultById EnqueueRateId -- | Return the rate of the items that were stored: how many items per time. enqueueStoreRate :: Queue -> ResultTransform enqueueStoreRate (Queue a) = a >>> resultById EnqueueStoreRateId -- | Return the rate of the requests for dequeueing the items: how many -- requests per time. It does not include the failed attempts to dequeue -- immediately without suspension. dequeueRate :: Queue -> ResultTransform dequeueRate (Queue a) = a >>> resultById DequeueRateId -- | Return the rate of the output items that were dequeued: how many items per time. dequeueExtractRate :: Queue -> ResultTransform dequeueExtractRate (Queue a) = a >>> resultById DequeueExtractRateId -- | Return the wait time from the time at which the item was stored in -- the queue to the time at which it was dequeued. queueWaitTime :: Queue -> SamplingStats queueWaitTime (Queue a) = SamplingStats (a >>> resultById QueueWaitTimeId) -- | Return the total wait time for the finite queue from the time at which -- the enqueueing operation was initiated to the time at which the item was dequeued. queueTotalWaitTime :: Queue -> SamplingStats queueTotalWaitTime (Queue a) = SamplingStats (a >>> resultById QueueTotalWaitTimeId) -- | Return the wait time from the time at which the item was stored in -- the queue to the time at which it was dequeued. enqueueWaitTime :: Queue -> SamplingStats enqueueWaitTime (Queue a) = SamplingStats (a >>> resultById EnqueueWaitTimeId) -- | Return the dequeue wait time from the time at which the item was requested -- for dequeueing to the time at which it was actually dequeued. dequeueWaitTime :: Queue -> SamplingStats dequeueWaitTime (Queue a) = SamplingStats (a >>> resultById DequeueWaitTimeId) -- | Return a long-term average queue rate calculated as the average queue size -- divided by the average wait time. queueRate :: Queue -> ResultTransform queueRate (Queue a) = a >>> resultById QueueRateId -- | Accumulates the statistics about that how long the arrived events are processed. newtype ArrivalTimer = ArrivalTimer ResultTransform instance ResultTransformer ArrivalTimer where tr (ArrivalTimer a) = a -- | Return the statistics about that how long the arrived events were processed. arrivalProcessingTime :: ArrivalTimer -> SamplingStats arrivalProcessingTime (ArrivalTimer a) = SamplingStats (a >>> resultById ArrivalProcessingTimeId) -- | It models the server that prodives a service. newtype Server = Server ResultTransform instance ResultTransformer Server where tr (Server a) = a -- | The initial state of the server. serverInitState :: Server -> ResultTransform serverInitState (Server a) = a >>> resultById ServerInitStateId -- | Return the current state of the server. serverState :: Server -> ResultTransform serverState (Server a) = a >>> resultById ServerStateId -- | Return the counted total time when the server was locked while -- awaiting the input. serverTotalInputWaitTime :: Server -> ResultTransform serverTotalInputWaitTime (Server a) = a >>> resultById ServerTotalInputWaitTimeId -- | Return the counted total time spent by the server while -- processing the tasks. serverTotalProcessingTime :: Server -> ResultTransform serverTotalProcessingTime (Server a) = a >>> resultById ServerTotalProcessingTimeId -- | Return the counted total time when the server was locked while -- trying to deliver the output. serverTotalOutputWaitTime :: Server -> ResultTransform serverTotalOutputWaitTime (Server a) = a >>> resultById ServerTotalOutputWaitTimeId -- | Return the counted total time spent by the server while it was -- preempted waiting for the further proceeding. serverTotalPreemptionTime :: Server -> ResultTransform serverTotalPreemptionTime (Server a) = a >>> resultById ServerTotalPreemptionTimeId -- | Return the statistics of the time when the server was locked -- while awaiting the input. serverInputWaitTime :: Server -> SamplingStats serverInputWaitTime (Server a) = SamplingStats (a >>> resultById ServerInputWaitTimeId) -- | Return the statistics of the time spent by the server while -- processing the tasks. serverProcessingTime :: Server -> SamplingStats serverProcessingTime (Server a) = SamplingStats (a >>> resultById ServerProcessingTimeId) -- | Return the statistics of the time when the server was locked -- while trying to deliver the output. serverOutputWaitTime :: Server -> SamplingStats serverOutputWaitTime (Server a) = SamplingStats (a >>> resultById ServerOutputWaitTimeId) -- | Return the statistics of the time spent by the server while -- it was preempted waiting for the further proceeding. serverPreemptionTime :: Server -> SamplingStats serverPreemptionTime (Server a) = SamplingStats (a >>> resultById ServerPreemptionTimeId) -- | It returns the factor changing from 0 to 1, which estimates -- how often the server was awaiting for the next input task. serverInputWaitFactor :: Server -> ResultTransform serverInputWaitFactor (Server a) = a >>> resultById ServerInputWaitFactorId -- | It returns the factor changing from 0 to 1, which estimates -- how often the server was busy with direct processing its tasks. serverProcessingFactor :: Server -> ResultTransform serverProcessingFactor (Server a) = a >>> resultById ServerProcessingFactorId -- | It returns the factor changing from 0 to 1, which estimates -- how often the server was locked trying to deliver the output -- after the task is finished. serverOutputWaitFactor :: Server -> ResultTransform serverOutputWaitFactor (Server a) = a >>> resultById ServerOutputWaitFactorId -- | It returns the factor changing from 0 to 1, which estimates -- how often the server was preempted waiting for the further proceeding. serverPreemptionFactor :: Server -> ResultTransform serverPreemptionFactor (Server a) = a >>> resultById ServerPreemptionFactorId -- | It models an activity that can be utilised. newtype Activity = Activity ResultTransform instance ResultTransformer Activity where tr (Activity a) = a -- | The initial state of the activity. activityInitState :: Activity -> ResultTransform activityInitState (Activity a) = a >>> resultById ActivityInitStateId -- | Return the current state of the activity. activityState :: Activity -> ResultTransform activityState (Activity a) = a >>> resultById ActivityStateId -- | Return the counted total time when the activity was utilised. activityTotalUtilisationTime :: Activity -> ResultTransform activityTotalUtilisationTime (Activity a) = a >>> resultById ActivityTotalUtilisationTimeId -- | Return the counted total time when the activity was idle. activityTotalIdleTime :: Activity -> ResultTransform activityTotalIdleTime (Activity a) = a >>> resultById ActivityTotalIdleTimeId -- | Return the counted total time when the activity was preemted -- waiting for the further proceeding. activityTotalPreemptionTime :: Activity -> ResultTransform activityTotalPreemptionTime (Activity a) = a >>> resultById ActivityTotalPreemptionTimeId -- | Return the statistics for the time when the activity was utilised. activityUtilisationTime :: Activity -> SamplingStats activityUtilisationTime (Activity a) = SamplingStats (a >>> resultById ActivityUtilisationTimeId) -- | Return the statistics for the time when the activity was idle. activityIdleTime :: Activity -> SamplingStats activityIdleTime (Activity a) = SamplingStats (a >>> resultById ActivityIdleTimeId) -- | Return the statistics for the time when the activity was preempted -- waiting for the further proceeding. activityPreemptionTime :: Activity -> SamplingStats activityPreemptionTime (Activity a) = SamplingStats (a >>> resultById ActivityPreemptionTimeId) -- | It returns the factor changing from 0 to 1, which estimates how often -- the activity was utilised. activityUtilisationFactor :: Activity -> ResultTransform activityUtilisationFactor (Activity a) = a >>> resultById ActivityUtilisationFactorId -- | It returns the factor changing from 0 to 1, which estimates how often -- the activity was idle. activityIdleFactor :: Activity -> ResultTransform activityIdleFactor (Activity a) = a >>> resultById ActivityIdleFactorId -- | It returns the factor changing from 0 to 1, which estimates how often -- the activity was preempted waiting for the further proceeding. activityPreemptionFactor :: Activity -> ResultTransform activityPreemptionFactor (Activity a) = a >>> resultById ActivityPreemptionFactorId -- | The resource which can be acquired and then released. newtype Resource = Resource ResultTransform instance ResultTransformer Resource where tr (Resource a) = a -- | Return the current available count of the resource. resourceCount :: Resource -> ResultTransform resourceCount (Resource a) = a >>> resultById ResourceCountId -- | Return the statistics for the available count of the resource. resourceCountStats :: Resource -> TimingStats resourceCountStats (Resource a) = TimingStats (a >>> resultById ResourceCountStatsId) -- | Return the current utilisation count of the resource. resourceUtilisationCount :: Resource -> ResultTransform resourceUtilisationCount (Resource a) = a >>> resultById ResourceUtilisationCountId -- | Return the statistics for the utilisation count of the resource. resourceUtilisationCountStats :: Resource -> TimingStats resourceUtilisationCountStats (Resource a) = TimingStats (a >>> resultById ResourceUtilisationCountStatsId) -- | Return the current queue length of the resource. resourceQueueCount :: Resource -> ResultTransform resourceQueueCount (Resource a) = a >>> resultById ResourceQueueCountId -- | Return the statistics for the queue length of the resource. resourceQueueCountStats :: Resource -> TimingStats resourceQueueCountStats (Resource a) = TimingStats (a >>> resultById ResourceQueueCountStatsId) -- | Return the total wait time of the resource. resourceTotalWaitTime :: Resource -> ResultTransform resourceTotalWaitTime (Resource a) = a >>> resultById ResourceTotalWaitTimeId -- | Return the statistics for the wait time of the resource. resourceWaitTime :: Resource -> SamplingStats resourceWaitTime (Resource a) = SamplingStats (a >>> resultById ResourceWaitTimeId) -- | It models an opreation which actvity can be utilised. newtype Operation = Operation ResultTransform instance ResultTransformer Operation where tr (Operation a) = a -- | Return the counted total time when the operation activity was utilised. operationTotalUtilisationTime :: Operation -> ResultTransform operationTotalUtilisationTime (Operation a) = a >>> resultById OperationTotalUtilisationTimeId -- | Return the counted total time when the operation activity was preemted -- waiting for the further proceeding. operationTotalPreemptionTime :: Operation -> ResultTransform operationTotalPreemptionTime (Operation a) = a >>> resultById OperationTotalPreemptionTimeId -- | Return the statistics for the time when the operation activity was utilised. operationUtilisationTime :: Operation -> SamplingStats operationUtilisationTime (Operation a) = SamplingStats (a >>> resultById OperationUtilisationTimeId) -- | Return the statistics for the time when the operation activity was preempted -- waiting for the further proceeding. operationPreemptionTime :: Operation -> SamplingStats operationPreemptionTime (Operation a) = SamplingStats (a >>> resultById OperationPreemptionTimeId) -- | It returns the factor changing from 0 to 1, which estimates how often -- the operation activity was utilised. operationUtilisationFactor :: Operation -> ResultTransform operationUtilisationFactor (Operation a) = a >>> resultById OperationUtilisationFactorId -- | It returns the factor changing from 0 to 1, which estimates how often -- the operation activity was preempted waiting for the further proceeding. operationPreemptionFactor :: Operation -> ResultTransform operationPreemptionFactor (Operation a) = a >>> resultById OperationPreemptionFactorId