Révision | d6d4ac508aa513458776610d9de2708fef2cea7d (tree) |
---|---|
l'heure | 2022-06-06 19:29:23 |
Auteur | Albert Mietus < albert AT mietus DOT nl > |
Commiter | Albert Mietus < albert AT mietus DOT nl > |
ASIS: Busy with syntax for FSMs
@@ -9,7 +9,7 @@ | ||
9 | 9 | |
10 | 10 | .. post:: 2022/05/7 |
11 | 11 | :category: Castle, Usage |
12 | - :tags: Castle, grammar | |
12 | + :tags: Castle, Grammar | |
13 | 13 | |
14 | 14 | In Castle you can define a *grammar* directly in your code. The compiler will *translate* them into functions, using |
15 | 15 | the build-in (PEG) **compiler-compiler** -- at least that was it called back in the days of *YACC*. |
@@ -20,7 +20,6 @@ | ||
20 | 20 | FSMs, an intro |
21 | 21 | ************** |
22 | 22 | |
23 | - | |
24 | 23 | .. include:: FSM-sidebar-code.irst |
25 | 24 | |
26 | 25 | The well known `State pattern`_ is basically an FSM_. It has a *finit* (**!**) number of ``states``, ``inputs`` (often |
@@ -10,16 +10,109 @@ | ||
10 | 10 | :category: Castle, Design |
11 | 11 | :tags: Castle, FSM |
12 | 12 | |
13 | - As described in `FSMs-are-needed` *Finit State Machines* are great and needed -- even tough no (main) programming | |
13 | + As described in :ref:`FSMs-are-needed` *Finit State Machines* are great and needed -- even tough no (main) programming | |
14 | 14 | language has syntax support for it. But there are other (computer) language that (more-or-less) support the |
15 | 15 | corresponding `State pattern`_. |
16 | 16 | |BR| |
17 | - By example plantUML_ --very populair by mature developers-- has a syntax to draw them | |
17 | + By example plantUML_ --very populair by mature developers-- has a syntax to draw them. | |
18 | 18 | |
19 | - What can we learn for them? That is the topic of this post, before we define the Castle syntax | |
19 | + What can we learn from them? That is the topic of this post, before we define the Castle syntax. | |
20 | + | |
21 | +Goal: Short & Maintainable | |
22 | +************************** | |
23 | + | |
24 | +Before we can define the (Castle) syntax for FSM_\s, we should know where we are aiming for. We need to support “all” | |
25 | +kinds of FSM, as required by :need:`U_FSM_Syntax` and refined by :need:`U_FSM_extensions`. E.g. the syntax should | |
26 | +allow non-determinism. And like all parts of Castle maintainability and preventing mistakes is important. | |
27 | +|BR| | |
28 | +For a FSM this means **short**: avoid boilerplate-code. | |
29 | + | |
30 | +The FSM_\`s mathematical model is simple: a set of `states` (‘:math:`S`’), the input `events` (‘:math:`E`’), | |
31 | +the transaction `rules` (‘:math:`R`’), a `start-state` (‘:math:`S0`’), and the `final-states` -- which are not needed | |
32 | +for a SW-FSM [#final-action]_. Usually, a set of `actions` (‘:math:`A`’) is required too. Where this set is implicitly | |
33 | +defined: the actions are listed inside the rules. | |
34 | +|BR| | |
35 | +Each `rule` is relation :math:`R := S * E -> S, A`; this “table” is typically the biggest part of an FSM. | |
36 | + | |
37 | +So, to make a FSM-code compact, we have to focus on the rules. | |
38 | +|BR| | |
39 | +It’s tempting to regard this rule-set as a *matrix*: with (‘:math:`S`’) and (‘:math:`E`’) on the axes and the | |
40 | +next-states [#non-determinism]_ (and actions) inside each cell. Nevertheless this matrix is huge and probably sparse: | |
41 | +most cells are empty, as the combination does not occur. | |
42 | + | |
43 | +We can describe such a sparse-matrix by listing the cell-value with the coordinates. This boils-down to listing the | |
44 | +rules, one by one. | |
45 | +|BR| | |
46 | +The disadvantage of this that many states and/or events are listed many times. As we will see below, some languages | |
47 | +solve this by factor-out `states` and/or `events`. | |
20 | 48 | |
21 | 49 | |
22 | -************** | |
50 | + | |
51 | + | |
52 | + | |
53 | + | |
54 | + | |
55 | + | |
56 | +.. hint:: Concurrency is not needed | |
57 | + | |
58 | + FSM’s can be huge in code but do not need a lot of computer-power. For every *step* --one input--, one state-variable | |
59 | + has to be updated. And the action has to be triggered. That action can be “big”, the FSM itself not. | |
60 | + Therefore, the syntax of the FSM doesn't need special attention to make the FSM concurent. | |
61 | + | |
62 | + | |
63 | +XXXXXX | |
64 | +******** | |
65 | + | |
66 | +plantUML: State diagram: | |
67 | + - https://en.wikipedia.org/wiki/PlantUML | |
68 | + - https://plantuml.com/state-diagram | |
69 | + | |
70 | +DOT/graphviz | |
71 | + - https://en.wikipedia.org/wiki/DOT_(graph_description_language) | |
72 | + - https://www.graphviz.org | |
73 | + | |
74 | +State Chart XML (SCXML): State Machine Notation for Control Abstraction | |
75 | + - https://www.w3.org/TR/scxml/ | |
76 | + | |
77 | +Regel | |
78 | + - https://en.wikipedia.org/wiki/Ragel | |
79 | + - http://www.colm.net/open-source/ragel/ | |
80 | + | |
81 | +Dezyne (of Verum) | |
82 | + - https://verum.com/discover-dezyne/ | |
83 | + - https://dezyne.org/dezyne/manual/dezyne/html_node/A-Simple-State-Machine.html | |
84 | + | |
85 | +Frame | |
86 | + - https://modeling-languages.com/designing-hierarchical-state-machines-using-frame-notation/ | |
87 | + | |
88 | +Thompson's construction (Use a RegExp to construct a NFA) | |
89 | + - https://en.wikipedia.org/wiki/Thompson%27s_construction | |
90 | + | |
91 | +SMC (State Machine Compiler) | |
92 | + - http://smc.sourceforge.net | |
93 | + - http://smc.sourceforge.net/slides/SMC_Tutorial.pdf | |
94 | + - UncleBobVideo version: https://github.com/unclebob/CC_SMC | |
95 | + | |
96 | + | |
97 | + | |
98 | + | |
99 | + | |
100 | + | |
101 | + | |
102 | + | |
103 | + | |
104 | +------- | |
105 | + | |
106 | +.. rubric:: Footnotes | |
107 | + | |
108 | +.. [#final-action] | |
109 | + The final-states are used by mathematics to verify/accept an input. Whereas a SW-FSM is typically used to control a | |
110 | + system; and run *forever*. When a “final state” is needed in a SW-FSM, typical a “final-action” is used. | |
111 | + | |
112 | +.. [#non-determinism] | |
113 | + Remember, we have to support non-determinism! Each cell in the matrix can have multiple “next states” (and | |
114 | + corresponding actions). | |
115 | + | |
23 | 116 | |
24 | 117 | |
25 | 118 |
@@ -12,3 +12,28 @@ | ||
12 | 12 | * |
13 | 13 | */index |
14 | 14 | |
15 | + | |
16 | +.. note:: In case you are wondering: *“Are FSMs and Grammars related, or the same?”* | |
17 | + | |
18 | + The are related, but not equal. As discovered by `Chomsky <https://en.wikipedia.org/wiki/Noam_Chomsky>`__ there is a | |
19 | + `hierarchy <https://en.wikipedia.org/wiki/Chomsky_hierarchy>`__ of languages (or actually grammars). As Chomsky was | |
20 | + studying all kind of languages, include natural “human” language, his perception differs from our interpretation. | |
21 | + |BR| | |
22 | + When we (SW/Engineers) speak about grammars, we typically refer to “Context free grammars” (`CFG | |
23 | + <https://en.wikipedia.org/wiki/Context-free_grammar>`__) -- Chomsky classify them as “Type-2”. | |
24 | + | |
25 | + A non-deterministic Push~Down machine (`PDA <https://en.wikipedia.org/wiki/Pushdown_automaton>`__) is needed to | |
26 | + recognise a “Type-2” (CFG) Grammar. (Which is a simple version of a stack-machine, which is lot more restricted then a Turing Machine). | |
27 | + |BR| | |
28 | + And as a FSM is one of the most restricted machines that exist --it can recognise only “Type-3” `Regular grammar | |
29 | + <https://en.wikipedia.org/wiki/Regular_grammar>`__-- a FSM can’t be used to recognise a (CFG) grammar. | |
30 | + | |
31 | + .. seealso:: | |
32 | + | |
33 | + .. postlist:: | |
34 | + :category: Castle | |
35 | + :tags: FSM | |
36 | + | |
37 | + .. postlist:: | |
38 | + :category: Castle | |
39 | + :tags: Grammar |
@@ -8,7 +8,7 @@ | ||
8 | 8 | |
9 | 9 | .. post:: 2022/05/14 |
10 | 10 | :category: Castle, DesignStudy |
11 | - :tags: Castle, grammar, PEG | |
11 | + :tags: Castle, Grammar, PEG | |
12 | 12 | |
13 | 13 | In :ref:`Castle-CompilerCompiler` we have seen that we can define a grammar within a Castle-program. And we have |
14 | 14 | argued that each grammars-rule can be considered as a function. |
@@ -8,7 +8,7 @@ | ||
8 | 8 | |
9 | 9 | .. post:: 2022/05/21 |
10 | 10 | :category: Castle, DesignStudy |
11 | - :tags: Castle, grammar | |
11 | + :tags: Castle, Grammar | |
12 | 12 | |
13 | 13 | In :ref:`grammmar-code` we have mentioned that many compiler-compilers reuse the Yacc invention “actions”. And we |
14 | 14 | hinted already that Castle prefers an alternative. |
@@ -0,0 +1,68 @@ | ||
1 | +======================= | |
2 | +Castle FSM syntax tries | |
3 | +======================= | |
4 | + | |
5 | +.. note:: Based on some experiments we select “a” language to highlight the examples. | |
6 | + Its just try&error; there is no relation with that language, Castle or a FSM! | |
7 | + | |
8 | +Try 1 | |
9 | +===== | |
10 | + | |
11 | +.. code:: ReasonML | |
12 | + | |
13 | + FSM AB { | |
14 | + state A, B, C; | |
15 | + | |
16 | + A + event_1 -> state_B, action_I; | |
17 | + A + event_2 -> state_C, action_II; | |
18 | + B + event_1 -> state_D, action_III; | |
19 | + Z1 + event_1 -> state_Z2; // No action | |
20 | + Z1 + event_1 -> ,action_only; // Empty state: do not change | |
21 | + Z1 + event_1 -> action_only; // No new state | |
22 | + // Note: In the last line Castle knows it only an action, as “action_only” is not a state! | |
23 | + // Potentially it conflict with the “redundancy rule” | |
24 | + Z1 + event_1 -> None, action_only; // None-state: do not change | |
25 | + } | |
26 | + | |
27 | +Variant a | |
28 | +--------- | |
29 | +Actions with ``(`` `parameters-list` ``)``. **Question**: Do we know those parameters here. Or are the default? | |
30 | + | |
31 | +.. code:: ReasonML | |
32 | + | |
33 | + FSM AB { | |
34 | + state A, B, C; | |
35 | + | |
36 | + A + event_1 -> state_B, action_I(p1,p2, p3); | |
37 | + A + event_2 -> state_C, action_II(); | |
38 | + B + event_1 -> state_D, action_III(); | |
39 | + Z1 + event_1 -> state_Z2; // No action | |
40 | + Z1 + event_1 -> ,action_only(); // Empty state: do not change | |
41 | + Z1 + event_1 -> action_only(); // No new state | |
42 | + // Note: In the last line Castle knows it only an action, as “action_only” is not a state! | |
43 | + // Potentially it conflict with the “redundancy rule” | |
44 | + Z1 + event_1 -> None, action_only(); // None-state: do not change | |
45 | + | |
46 | + } | |
47 | + | |
48 | + | |
49 | +Variant b | |
50 | +--------- | |
51 | +No FSM/State prequel nor block | |
52 | + | |
53 | +.. code:: ReasonML | |
54 | + | |
55 | + state A, B, C; | |
56 | + | |
57 | + A + event_1 -> state_B, action_I; | |
58 | + A + event_2 -> state_C, action_II; | |
59 | + B + event_1 -> state_D, action_III; | |
60 | + Z1 + event_1 -> state_Z2; // No action | |
61 | + Z1 + event_1 -> ,action_only; // Empty state: do not change | |
62 | + Z1 + event_1 -> action_only; // No new state | |
63 | + // Note: In the last line Castle knows it only an action, as “action_only” is not a state! | |
64 | + // Potentially it conflict with the “redundancy rule” | |
65 | + Z1 + event_1 -> None, action_only; // None-state: do not change | |
66 | + | |
67 | + | |
68 | + |
@@ -49,3 +49,6 @@ | ||
49 | 49 | @BRANCH=$${BRANCH:-`hg branch`} ;\ |
50 | 50 | curl -X POST -d "branches=$${BRANCH}" -d "token=${TOKEN}" ${HOOK} |
51 | 51 | @echo |
52 | + | |
53 | +wc: | |
54 | + wc -lw `find CCastle/ -iname \*rst`|sort -r |