]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.tutorial/scl/Tutorial/3.01 Simulation sequences.md
Import org.simantics.scl.tutorial from incubator SVN repo
[simantics/platform.git] / bundles / org.simantics.scl.tutorial / scl / Tutorial / 3.01 Simulation sequences.md
1 # Simulation sequences\r
2 \r
3 ## Sequence monad\r
4     \r
5 ::data[Simantics/Sequences/Sequence]\r
6     \r
7 We call the sequence *instantious*, if its duration is zero, i.e, the sequence finishes immediately after started.\r
8 \r
9 A cooking recipe is an example of a sequence in the real world. Its return value could be for example the success \r
10 indication of the cooking process.\r
11 \r
12     instance Monad Sequence\r
13 \r
14 In order to build complex sequences from simple primitives, the sequences implement\r
15 [Monad](http://en.wikipedia.org/wiki/Monad_%28functional_programming%29) operations and\r
16 its laws. These are\r
17 \r
18 ::value[Prelude/return, Prelude/>>=]\r
19     \r
20 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
21 \r
22 ::value[Prelude/>>, Prelude/fmap, Prelude/join, Prelude/sequence, Prelude/repeatForever]\r
23     \r
24 These operations are derived from the primitive monad operations.\r
25 The sequence `seqA >> seqB` behaves first like `seqA` and when it has finished it\r
26 continues like `seqB`. The sequence `fmap f seq` maps the result of the sequence `seq` by the function\r
27 `f`. The sequence `join seq` first behaves like the sequence `seq` and then like the sequence `seq` returned.\r
28 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
29 \r
30 ## Actions\r
31 \r
32     effect Action\r
33     \r
34 `<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
35 \r
36 ::value[Simantics/Sequences/time, Simantics/Sequences/getVar, Simantics/Sequences/setVar]\r
37     \r
38 ::value[Simantics/Sequences/execute]\r
39 \r
40 Multiple actions happening at the same time may be written either as separate sequences:\r
41 \r
42     mdo execute (setVar "SP1#SP_VALUE" 13)\r
43         execute (setVar "SP2#SP_VALUE" 14)\r
44 \r
45 or as one sequence with more complicated action:\r
46 \r
47     execute do\r
48         setVar "SP1#SP_VALUE" 13\r
49         setVar "SP2#SP_VALUE" 14\r
50 \r
51 ## Controlling time\r
52 \r
53 ::value[Simantics/Sequences/waitStep]\r
54 \r
55 ::value[Simantics/Sequences/waitUntil, Simantics/Sequences/wait]\r
56     \r
57 ::value[Simantics/Sequences/waitCondition]\r
58 \r
59 ## Parallel execution\r
60 \r
61 ::value[Simantics/Sequences/fork, Simantics/Sequences/halt, Simantics/Sequences/stop]\r
62 \r
63 ## Semantics\r
64 \r
65 Although the simulation sequences support threading, its semantics is deterministic. This is ensured by the following equivalences:\r
66 \r
67     halt >> seqA                                       = halt\r
68     stop >> seqA                                       = stop\r
69     fork (execute actionA >> seqA) >> seqB             = execute actionA >> fork seqA >> seqB\r
70     fork (waitStep >> seqA) >> execute actionB >> seqB = execute actionB >> fork seqA >> seqB\r
71     fork (waitStep >> seqA) >> waitStep >> seqB        = waitStep >> fork seqA >> seqB\r
72     fork halt >> seqB                                  = seqB\r
73     fork seqA >> halt                                  = seqA\r
74     fork stop >> seqB                                  = stop\r
75     fork (waitStep >> seqA) >> stop                    = stop\r
76 \r
77 ## Using the sequences with Apros\r
78 \r
79 In order to run the sequence in Apros, function \r
80 \r
81 ::value[Apros/Sequences/runSequence]\r
82 \r
83 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
84 \r
85     import "Apros/Sequences"\r
86     runSequence mdo\r
87         fork $ repeatForever mdo\r
88             waitCondition (getVar "TA01#TA11_LIQ_LEVEL" >= 3.0)\r
89             execute (setVar "BP01#PU11_SPEED_SET_POINT" 0.0)\r
90             wait 1\r
91         fork $ repeatForever mdo\r
92             waitCondition (getVar "TA01#TA11_LIQ_LEVEL" <= 2.0)\r
93             execute (setVar "BP01#PU11_SPEED_SET_POINT" 100.0)\r
94             wait 1\r
95 \r
96 ## Examples\r
97 \r
98 Check that pressure of the point stays below a certain value:\r
99 \r
100     fork mdo waitCondition (getVar "POINT1#PO11_PRESSURE" > 120.0)\r
101              execute (print "Error! Error!")\r
102              stop\r
103 \r
104 Check that the valve is closed 10 seconds after the operator presses the button:\r
105 \r
106     fork $ repeatForever mdo\r
107         waitCondition (getVar "BUTTON#BINARY_VALUE")\r
108         fork mdo\r
109             wait 10\r
110             valvePos <- execute (getVar "VALVE#VA11_POSITION")\r
111             if valvePos == 0\r
112             then return () // OK\r
113             else mdo\r
114                 execute (print "Error! Error!")\r
115                 stop\r
116 \r