--- /dev/null
+# Simulation sequences\r
+\r
+## Sequence monad\r
+ \r
+::data[Simantics/Sequences/Sequence]\r
+ \r
+We call the sequence *instantious*, if its duration is zero, i.e, the sequence finishes immediately after started.\r
+\r
+A cooking recipe is an example of a sequence in the real world. Its return value could be for example the success \r
+indication of the cooking process.\r
+\r
+ instance Monad Sequence\r
+\r
+In order to build complex sequences from simple primitives, the sequences implement\r
+[Monad](http://en.wikipedia.org/wiki/Monad_%28functional_programming%29) operations and\r
+its laws. These are\r
+\r
+::value[Prelude/return, Prelude/>>=]\r
+ \r
+The sequence `return v` has zero duration, it does not modify the simulator state and returns `v`. The sequence `seqA >>= f` is a sequence that first behaves like `seqA`, and when it has completed and returned a value `resultA`, continues like the sequence `f resultA`. In other words, `(>>=)` concatenates two sequences and the behavior of the latter sequence may depend on the return value of the former sequence. \r
+\r
+::value[Prelude/>>, Prelude/fmap, Prelude/join, Prelude/sequence, Prelude/repeatForever]\r
+ \r
+These operations are derived from the primitive monad operations.\r
+The sequence `seqA >> seqB` behaves first like `seqA` and when it has finished it\r
+continues like `seqB`. The sequence `fmap f seq` maps the result of the sequence `seq` by the function\r
+`f`. The sequence `join seq` first behaves like the sequence `seq` and then like the sequence `seq` returned.\r
+The sequence `sequence seqs` executes every sequence in the container `seqs` sequentially. The container can be for example list or `Maybe`. The sequence `repeatForever seq` repeats the sequence `seq` forever, never returning.\r
+\r
+## Actions\r
+\r
+ effect Action\r
+ \r
+`<Action> a` is an instantious operation happening in the simulator and returning a value of type `a`. It can be a pure reading operation, but may also modify the simulator state. The duration of an action is always zero.\r
+\r
+::value[Simantics/Sequences/time, Simantics/Sequences/getVar, Simantics/Sequences/setVar]\r
+ \r
+::value[Simantics/Sequences/execute]\r
+\r
+Multiple actions happening at the same time may be written either as separate sequences:\r
+\r
+ mdo execute (setVar "SP1#SP_VALUE" 13)\r
+ execute (setVar "SP2#SP_VALUE" 14)\r
+\r
+or as one sequence with more complicated action:\r
+\r
+ execute do\r
+ setVar "SP1#SP_VALUE" 13\r
+ setVar "SP2#SP_VALUE" 14\r
+\r
+## Controlling time\r
+\r
+::value[Simantics/Sequences/waitStep]\r
+\r
+::value[Simantics/Sequences/waitUntil, Simantics/Sequences/wait]\r
+ \r
+::value[Simantics/Sequences/waitCondition]\r
+\r
+## Parallel execution\r
+\r
+::value[Simantics/Sequences/fork, Simantics/Sequences/halt, Simantics/Sequences/stop]\r
+\r
+## Semantics\r
+\r
+Although the simulation sequences support threading, its semantics is deterministic. This is ensured by the following equivalences:\r
+\r
+ halt >> seqA = halt\r
+ stop >> seqA = stop\r
+ fork (execute actionA >> seqA) >> seqB = execute actionA >> fork seqA >> seqB\r
+ fork (waitStep >> seqA) >> execute actionB >> seqB = execute actionB >> fork seqA >> seqB\r
+ fork (waitStep >> seqA) >> waitStep >> seqB = waitStep >> fork seqA >> seqB\r
+ fork halt >> seqB = seqB\r
+ fork seqA >> halt = seqA\r
+ fork stop >> seqB = stop\r
+ fork (waitStep >> seqA) >> stop = stop\r
+\r
+## Using the sequences with Apros\r
+\r
+In order to run the sequence in Apros, function \r
+\r
+::value[Apros/Sequences/runSequence]\r
+\r
+has been defined. It starts automatically starts simulation, if it is not yet running. When all simulation threads are halted or some thread calls `stop` the simulation is stopped. The sequence can also aborted by aborting the SCL-command (red box in the upper right corner of the console).\r
+\r
+ import "Apros/Sequences"\r
+ runSequence mdo\r
+ fork $ repeatForever mdo\r
+ waitCondition (getVar "TA01#TA11_LIQ_LEVEL" >= 3.0)\r
+ execute (setVar "BP01#PU11_SPEED_SET_POINT" 0.0)\r
+ wait 1\r
+ fork $ repeatForever mdo\r
+ waitCondition (getVar "TA01#TA11_LIQ_LEVEL" <= 2.0)\r
+ execute (setVar "BP01#PU11_SPEED_SET_POINT" 100.0)\r
+ wait 1\r
+\r
+## Examples\r
+\r
+Check that pressure of the point stays below a certain value:\r
+\r
+ fork mdo waitCondition (getVar "POINT1#PO11_PRESSURE" > 120.0)\r
+ execute (print "Error! Error!")\r
+ stop\r
+\r
+Check that the valve is closed 10 seconds after the operator presses the button:\r
+\r
+ fork $ repeatForever mdo\r
+ waitCondition (getVar "BUTTON#BINARY_VALUE")\r
+ fork mdo\r
+ wait 10\r
+ valvePos <- execute (getVar "VALVE#VA11_POSITION")\r
+ if valvePos == 0\r
+ then return () // OK\r
+ else mdo\r
+ execute (print "Error! Error!")\r
+ stop\r
+\r