-- It corresponds to model MachRep1 described in document -- Introduction to Discrete-Event Simulation and the SimPy Language -- [http://heather.cs.ucdavis.edu/~matloff/156/PLN/DESimIntro.pdf]. -- SimPy is available on [http://simpy.sourceforge.net/]. -- -- The model description is as follows. -- -- Two machines, which sometimes break down. -- Up time is exponentially distributed with mean 1.0, and repair time is -- exponentially distributed with mean 0.5. There are two repairpersons, -- so the two machines can be repaired simultaneously if they are down -- at the same time. -- -- Output is long-run proportion of up time. Should get value of about -- 0.66. import Control.Monad import Control.Monad.Trans import Simulation.Aivika.Trans import Simulation.Aivika.Branch meanUpTime = 1.0 meanRepairTime = 0.5 specs = Specs { spcStartTime = 0.0, spcStopTime = 1000.0, spcDT = 1.0, spcMethod = RungeKutta4, spcGeneratorType = SimpleGenerator } model :: Simulation (BR IO) (Results (BR IO)) model = do totalUpTime <- newRef 0.0 let machine = do upTime <- liftParameter $ randomExponential meanUpTime -- -- r <- liftSimulation $ newRef 10 -- holdProcess upTime liftEvent $ modifyRef totalUpTime (+ upTime) repairTime <- liftParameter $ randomExponential meanRepairTime holdProcess repairTime machine runProcessInStartTime machine runProcessInStartTime machine let maxLevel = 4 starttime' <- liftParameter starttime stoptime' <- liftParameter stoptime let dt' = (stoptime' - starttime') / fromIntegral maxLevel -- dt' <- liftParameter dt let forecast :: Double -> Event (BR IO) Double forecast i = do level <- liftComp branchLevel if level <= maxLevel then do t <- liftDynamics time x1 <- futureEvent (t + dt') $ forecast (i - 1) x2 <- futureEvent (t + dt') $ forecast (i + 1) let x = (x1 + x2) / 2 x `seq` return x else do t <- liftDynamics time x <- readRef totalUpTime return $ x / (2 * t) f <- runEventInStartTime $ forecast 0 let upTimePropForecasted :: Event (BR IO) Double upTimePropForecasted = return f let upTimeProp = do x <- readRef totalUpTime t <- liftDynamics time return $ x / (2 * t) return $ results [resultSource "upTimeProp" "The long-run proportion of up time (~ 0.66)" upTimeProp, -- resultSource "upTimePropForecasted" "The forecasted long-run proption of up time" upTimePropForecasted] main :: IO () main = runBR $ printSimulationResultsInStopTime printResultSourceInEnglish model specs