Franck Pommereau

initial import

Showing 79 changed files with 1295 additions and 0 deletions
1 +all: chap1 chap2
2 +
3 +chap1: chap1.pdf chap1-anim.gif
4 +
5 +chap2: chap2.pdf
6 + python3 chap2-anim.py
7 + mv chap2*.gif chap2/
8 +
9 +%.pdf: %.tex
10 + latexmk -pdf $<
11 + latexmk -pdf -c $<
12 + mkdir -p $(*F)
13 + convert -background white -alpha remove -density 600 $@ $(*F)/fig-%03d.png
14 +
15 +%.gif: %.py %.tex
16 + python3 $<
1 +from t2g import *
2 +
3 +markings = {0: dict(a=3, b=0, c=0, d=0),
4 + 1: dict(a=1, b=1, c=0, d=0),
5 + 2: dict(a=1, b=0, c=1, d=0),
6 + 3: dict(a=1, b=0, c=0, d=2),
7 + 4: dict(a=2, b=0, c=0, d=1),
8 + 5: dict(a=0, b=1, c=0, d=1),
9 + 6: dict(a=0, b=0, c=1, d=1),
10 + 7: dict(a=0, b=0, c=0, d=3)}
11 +
12 +state = {"a": 0, "b": 0, "c": 0, "d": 0}
13 +
14 +trans = {(0,1): "t",
15 + (1,2): "u",
16 + (2,3): "v",
17 + (3,4): "w",
18 + (4,0): "w",
19 + (4,5): "t",
20 + (5,6): "u",
21 + (6,7): "v",
22 + (7,3): "w",
23 + (6,2): "w",
24 + (5,1): "w"}
25 +
26 +active = dict((t, "") for t in "tuvw")
27 +active.update((s, "") for s in range(8))
28 +active.update((f, "") for f in trans)
29 +
30 +load("chap1-anim.tex")
31 +src = 0
32 +
33 +for dst in [1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 3, 4, 5, 1, 2, 3, 4, 5, 6, 2, 3, 4, 0] :
34 + state = markings[src]
35 + active[src] = "active"
36 + frame(.8)
37 + active[src,dst] = active[trans[src,dst]] = "active"
38 + frame(.8)
39 + active[src] = active[src,dst] = active[trans[src,dst]] = ""
40 + src = dst
41 +
42 +gif("chap1-anim.gif")
1 +\documentclass[multi={tikzpicture},crop=true,border=5pt]{standalone}
2 +
3 +\usepackage{tikz}
4 +\usetikzlibrary{shapes,arrows,arrows.meta,petri}
5 +\tikzset{
6 + >=latex,
7 + every place/.style={minimum size=6mm},
8 + every transition/.style={minimum size=6mm},
9 + token distance=6pt,
10 +}
11 +
12 +\tikzstyle{trans}=[transition]
13 +
14 +\tikzstyle{state}=[draw=blue!50!gray!50!white,
15 + fill=blue!70!gray!10!white,
16 + line width=2pt,
17 + cloud,cloud puffs=8,
18 + inner sep=-1pt]
19 +
20 +\tikzstyle{fire}=[arrows={-Straight Barb[scale=.6]},
21 + shorten >=-2pt, shorten <=-1pt,
22 + draw=blue!50!gray!50!white,
23 + line width=2pt,
24 + fill opacity=0,
25 + text opacity=1,
26 + line cap=round,
27 + rounded corners]
28 +
29 +\tikzstyle{active}=[draw=green!50!gray!50!white,
30 + fill=green!70!gray!10!white]
31 +
32 +\def\matrix #1#2#3#4{%
33 + $\begin{array}{c@{\hspace{5pt}}c}
34 + #1 & #2 \\
35 + #3 & #4
36 + \end{array}$}
37 +
38 +\begin{document}
39 +
40 +%%FRAME
41 +
42 +\begin{tikzpicture}
43 + \begin{scope}[yshift=45mm,xshift=28mm,scale=1.2]
44 + \node[place,tokens={{ state["a"] }}] (a) at (0,0) {};
45 + \node[left] at (a.west) {$a$};
46 + \node[trans,{{ active["t"] }}] (t) at (1,0) {$t$};
47 + \draw[->] (a) -- node[above]{2} (t);
48 + \node[place,tokens={{ state["b"] }}] (b) at (2,0) {};
49 + \node[right] at (b.east) {$b$};
50 + \draw[->] (t) -- (b);
51 + \node[trans,{{ active["u"] }}] (u) at (2,-1) {$u$};
52 + \draw[->] (b) -- (u);
53 + \node[place,tokens={{ state["c"] }}] (c) at (2,-2) {};
54 + \node[right] at (c.east) {$c$};
55 + \draw[->] (u) -- (c);
56 + \node[trans,{{ active["v"] }}] (v) at (1,-2) {$v$};
57 + \draw[->] (c) -- (v);
58 + \node[place,tokens={{ state["d"] }}] (d) at (0,-2) {};
59 + \node[left] at (d.west) {$d$};
60 + \draw[->] (v) -- node[above]{2} (d);
61 + \node[trans,{{ active["w"] }}] (w) at (0,-1) {$w$};
62 + \draw[->] (d) -- (w);
63 + \draw[->] (w) -- (a);
64 + \end{scope}
65 + \begin{scope}[scale=2]
66 + \node[state,{{ active[0] }}] (0) at (0,0) {\matrix 3000};
67 + \node[state,{{ active[1] }}] (1) at (1,0) {\matrix 1100};
68 + \draw[fire,{{ active[0,1] }}] (0) -- node[above] {$t$} (1);
69 + \node[state,{{ active[2] }}] (2) at (2,0) {\matrix 1001};
70 + \draw[fire,{{ active[1,2] }}] (1) -- node[above] {$u$} (2);
71 + \node[state,{{ active[3] }}] (3) at (3,0) {\matrix 1020};
72 + \draw[fire,{{ active[2,3] }}] (2) -- node[above] {$v$} (3);
73 + \node[state,{{ active[4] }}] (4) at (4,0) {\matrix 2010};
74 + \draw[fire,{{ active[3,4] }}] (3) -- node[above] {$w$} (4);
75 + \draw[fire,{{ active[4,0] }}] (4) |- node[near end,above] {$w$} +(-1,.5) -| (0);
76 + \node[state,{{ active[5] }}] (5) at (1,-1) {\matrix 0110};
77 + \draw[fire,{{ active[4,5] }}] (4) |- node[pos=.05,right] {$t$} +(-1,-1.5) -| (5);
78 + \draw[fire,{{ active[5,1] }}] (5) -- node[left] {$w$} (1);
79 + \node[state,{{ active[6] }}] (6) at (2,-1) {\matrix 0011};
80 + \draw[fire,{{ active[5,6] }}] (5) -- node[above] {$u$} (6);
81 + \draw[fire,{{ active[6,2] }}] (6) -- node[left] {$w$} (2);
82 + \node[state,{{ active[7] }}] (7) at (3,-1) {\matrix 0030};
83 + \draw[fire,{{ active[7,3] }}] (7) -- node[left] {$w$} (3);
84 + \draw[fire,{{ active[6,7] }}] (6) -- node[above] {$v$} (7);
85 + \end{scope}
86 +\end{tikzpicture}
87 +
88 +%%/FRAME
89 +
90 +\end{document}
1 +\documentclass[multi={tikzpicture},crop=true,border=5pt]{standalone}
2 +
3 +\usepackage{tikz}
4 +\usetikzlibrary{shapes,arrows,arrows.meta,petri}
5 +\tikzset{
6 + >=latex,
7 + every place/.style={minimum size=6mm},
8 + every transition/.style={minimum size=6mm},
9 + token distance=6pt,
10 +}
11 +
12 +\tikzstyle{trans}=[transition]
13 +
14 +\tikzstyle{state}=[draw=blue!50!gray!50!white,
15 + fill=blue!70!gray!10!white,
16 + line width=2pt,
17 + cloud,cloud puffs=8,
18 + inner sep=-1pt]
19 +
20 +\tikzstyle{fire}=[arrows={-Straight Barb[scale=.6]},
21 + shorten >=-2pt, shorten <=-1pt,
22 + draw=blue!50!gray!50!white,
23 + line width=2pt,
24 + line cap=round,
25 + rounded corners]
26 +
27 +\def\matrix #1#2#3#4{%
28 + $\begin{array}{c@{\hspace{5pt}}c}
29 + #1 & #2 \\
30 + #3 & #4
31 + \end{array}$}
32 +
33 +\begin{document}
34 +
35 +% Les réseaux de Petri
36 +
37 +% Chapitre 1. Quoi ?
38 +% Où l'on apprend ce que sont les réseaux de Petri.
39 +
40 +%%%
41 +
42 +% Ceci est une place.
43 +
44 +\begin{tikzpicture}
45 + \node[place] (p) at (0,0) {};
46 +\end{tikzpicture}
47 +
48 +% Une place peut contenir des jetons (ici 3).
49 +
50 +\begin{tikzpicture}
51 + \node[place,tokens=3] (p) at (0,0) {};
52 +\end{tikzpicture}
53 +
54 +% Ceci est une transition.
55 +
56 +% Une transition ne peut pas contenir de jetons, non non.
57 +
58 +\begin{tikzpicture}
59 + \node[trans] (t) at (0,0) {};
60 +\end{tikzpicture}
61 +
62 +% Ceci est un arc.
63 +
64 +\begin{tikzpicture}
65 + \draw[->] (0,0) -- (1,0);
66 +\end{tikzpicture}
67 +
68 +% Un arc peut être décoré par un nombre entier (valant au moins 1).
69 +
70 +% Quand on ne met pas de nombre, c'est qu'il vaut 1.
71 +
72 +\begin{tikzpicture}
73 + \draw[->] (0,0) -- node[above]{2} (1,0);
74 +\end{tikzpicture}
75 +
76 +% Un arc relie une place à une transition, ou l'inverse.
77 +
78 +\begin{tikzpicture}[xscale=1.2]
79 + \node[place,tokens=3] (p) at (0,0) {};
80 + \node[trans] (t) at (1,0) {};
81 + \draw[->] (p) -- node[above]{2} (t);
82 + \node[trans] (u) at (0,-1) {};
83 + \node[place] (q) at (1,-1) {};
84 + \draw[->] (u) -- (q);
85 +\end{tikzpicture}
86 +
87 +% Mais un arc ne relie jamais deux places ou deux transitions.
88 +% Jamais, jamais.
89 +
90 +\begin{tikzpicture}[xscale=1.2]
91 + \node[place,tokens=3] (p) at (0,0) {};
92 + \node[place] (q) at (1,0) {};
93 + \draw[->] (p) -- node[above]{2} (q);
94 + \node[trans] (t) at (0,-1) {};
95 + \node[trans] (u) at (1,-1) {};
96 + \draw[->] (t) -- (u);
97 + \node[forbidden sign,line width=5pt,draw=red,inner sep=6mm] at (.5,-.5) {};
98 +\end{tikzpicture}
99 +
100 +% Ceci est un réseau de Petri que nous appellerons Carl.
101 +
102 +% Carl a une transition, deux places (l'une a trois jetons, l'autre
103 +% zéro), et deux arcs.
104 +
105 +\begin{tikzpicture}[xscale=1.2]
106 + \node[place,tokens=3] (p) at (0,0) {};
107 + \node[trans] (t) at (1,0) {};
108 + \draw[->] (p) -- node[above]{2} (t);
109 + \node[place] (q) at (2,0) {};
110 + \draw[->] (t) -- (q);
111 +\end{tikzpicture}
112 +
113 +% Les transitions consomment et produisent des jetons dans les places,
114 +% selon ce qu'indiquent les arcs.
115 +
116 +% La transition de Carl peut consommer deux jetons dans la place de
117 +% gauche et en produire un dans celle de droite (le 1 n'est pas
118 +% indiqué puisque c'est 1 justement).
119 +
120 +% Si elle le fait, on dit qu'on tire la transition.
121 +
122 +%%%
123 +
124 +% Ici, Carl a tiré sa transition. Deux jetons ont disparu de la place
125 +% de gauche, et un a été ajouté dans celle de droite. Comme indiqué
126 +% par les arcs.
127 +
128 +\begin{tikzpicture}[xscale=1.2]
129 + \node[place,tokens=1] (p) at (0,0) {};
130 + \node[trans] (t) at (1,0) {};
131 + \draw[->] (p) -- node[above]{2} (t);
132 + \node[place,tokens=1] (q) at (2,0) {};
133 + \draw[->] (t) -- (q);
134 +\end{tikzpicture}
135 +
136 +% Maintenant, Carl ne peut plus tirer sa transition, car elle ne peut
137 +% pas consommer deux jetons dans la place de gauche qui n'en contient
138 +% qu'un. Donc Carl est bloqué. (Pauvre Carl.)
139 +
140 +%%%
141 +
142 +% Voici un autre réseau de Petri, appelons le Adam. Comme il a
143 +% beaucoup de places et de transitions, on leur donne des noms: a, b,
144 +% c, d pour les places, et t, u, v, w pour les transitions.
145 +
146 +\begin{tikzpicture}[scale=1.2]
147 + \node[place,tokens=3] (a) at (0,0) {};
148 + \node[left] at (a.west) {$a$};
149 + \node[trans] (t) at (1,0) {$t$};
150 + \draw[->] (a) -- node[above]{2} (t);
151 + \node[place] (b) at (2,0) {};
152 + \node[right] at (b.east) {$b$};
153 + \draw[->] (t) -- (b);
154 + \node[trans] (u) at (2,-1) {$u$};
155 + \draw[->] (b) -- (u);
156 + \node[place] (c) at (2,-2) {};
157 + \node[right] at (c.east) {$c$};
158 + \draw[->] (u) -- (c);
159 + \node[trans] (v) at (1,-2) {$v$};
160 + \draw[->] (c) -- (v);
161 + \node[place] (d) at (0,-2) {};
162 + \node[left] at (d.west) {$d$};
163 + \draw[->] (v) -- node[above]{2} (d);
164 + \node[trans] (w) at (0,-1) {$w$};
165 + \draw[->] (d) -- (w);
166 + \draw[->] (w) -- (a);
167 +\end{tikzpicture}
168 +
169 +% Adam a trois jetons dans sa place a, et aucun ailleurs. On appelle
170 +% ça son marquage, c'est-à-dire le nombre de jetons dans chaque place.
171 +
172 +% On peut le dessiner dans un petit nuage bleu.
173 +
174 +\begin{tikzpicture}[scale=1.2]
175 + \node[state] (s) at (1,-1) {\matrix 3000};
176 + \node[place,tokens=3] (a) at (0,0) {};
177 + \node[left] at (a.west) {$a$};
178 + \node[trans] (t) at (1,0) {$t$};
179 + \draw[->] (a) -- node[above]{2} (t);
180 + \node[place] (b) at (2,0) {};
181 + \node[right] at (b.east) {$b$};
182 + \draw[->] (t) -- (b);
183 + \node[trans] (u) at (2,-1) {$u$};
184 + \draw[->] (b) -- (u);
185 + \node[place] (c) at (2,-2) {};
186 + \node[right] at (c.east) {$c$};
187 + \draw[->] (u) -- (c);
188 + \node[trans] (v) at (1,-2) {$v$};
189 + \draw[->] (c) -- (v);
190 + \node[place] (d) at (0,-2) {};
191 + \node[left] at (d.west) {$d$};
192 + \draw[->] (v) -- node[above]{2} (d);
193 + \node[trans] (w) at (0,-1) {$w$};
194 + \draw[->] (d) -- (w);
195 + \draw[->] (w) -- (a);
196 + \draw[|->,yellow,very thick,shorten >=-10pt] (a) -- (s.north west);
197 + \draw[|->,yellow,very thick,shorten >=-10pt] (b) -- (s.north east);
198 + \draw[|->,yellow,very thick,shorten >=-10pt] (c) -- (s.south east);
199 + \draw[|->,yellow,very thick,shorten >=-10pt] (d) -- (s.south west);
200 +\end{tikzpicture}
201 +
202 +% Adam peut tirer sa transition t, ce qui enlèvera deux jetons dans a
203 +% et en ajoutera un dans b. On obtient alors ce marquage.
204 +
205 +\begin{tikzpicture}
206 + \node[state] {\matrix 1100};
207 +\end{tikzpicture}
208 +
209 +% On peut représenter cette évolution entre deux marquages par un
210 +% graphe.
211 +
212 +\begin{tikzpicture}[scale=2]
213 + \node[state] (0) at (0,0) {\matrix 3000};
214 + \node[state] (1) at (1,0) {\matrix 1100};
215 + \draw[fire] (0) -- node[above] {$t$} (1);
216 +\end{tikzpicture}
217 +
218 +% Et on peut prolonger ce graphe en tirant u, v, puis w.
219 +
220 +\begin{tikzpicture}[scale=2]
221 + \node[state] (0) at (0,0) {\matrix 3000};
222 + \node[state] (1) at (1,0) {\matrix 1100};
223 + \draw[fire] (0) -- node[above] {$t$} (1);
224 + \node[state] (2) at (2,0) {\matrix 1001};
225 + \draw[fire] (1) -- node[above] {$u$} (2);
226 + \node[state] (3) at (3,0) {\matrix 1020};
227 + \draw[fire] (2) -- node[above] {$v$} (3);
228 + \node[state] (4) at (4,0) {\matrix 2010};
229 + \draw[fire] (3) -- node[above] {$w$} (4);
230 +\end{tikzpicture}
231 +
232 +% À partir du dernier marquage atteint, on peut encore tirer w, et on
233 +% retrouve alors le marquage départ.
234 +
235 +\begin{tikzpicture}[scale=2]
236 + \node[state] (0) at (0,0) {\matrix 3000};
237 + \node[state] (1) at (1,0) {\matrix 1100};
238 + \draw[fire] (0) -- node[above] {$t$} (1);
239 + \node[state] (2) at (2,0) {\matrix 1001};
240 + \draw[fire] (1) -- node[above] {$u$} (2);
241 + \node[state] (3) at (3,0) {\matrix 1020};
242 + \draw[fire] (2) -- node[above] {$v$} (3);
243 + \node[state] (4) at (4,0) {\matrix 2010};
244 + \draw[fire] (3) -- node[above] {$w$} (4);
245 + \draw[fire] (4) |- node[near end,above] {$w$} +(-1,.5) -| (0);
246 +\end{tikzpicture}
247 +
248 +% Mais, hop hop hop, pas si vite... Au lieu de tirer w, on aurait
249 +% aussi pu tirer t puisqu'il y a deux jetons dans a. Du coup, on
250 +% obtient un branchement dans notre graphe.
251 +
252 +\begin{tikzpicture}[scale=2]
253 + \node[state] (0) at (0,0) {\matrix 3000};
254 + \node[state] (1) at (1,0) {\matrix 1100};
255 + \draw[fire] (0) -- node[above] {$t$} (1);
256 + \node[state] (2) at (2,0) {\matrix 1001};
257 + \draw[fire] (1) -- node[above] {$u$} (2);
258 + \node[state] (3) at (3,0) {\matrix 1020};
259 + \draw[fire] (2) -- node[above] {$v$} (3);
260 + \node[state] (4) at (4,0) {\matrix 2010};
261 + \draw[fire] (3) -- node[above] {$w$} (4);
262 + \draw[fire] (4) |- node[near end,above] {$w$} +(-1,.5) -| (0);
263 + \node[state] (5) at (1,-1) {\matrix 0110};
264 + \draw[fire] (4) |- node[pos=.05,right] {$t$} +(-1,-1.5) -| (5);
265 +\end{tikzpicture}
266 +
267 +% On continue : à partir de chaque marquage, on tire toutes les
268 +% transitions possibles. Et on obtient ce qu'on appelle le graphe de
269 +% marquages.
270 +
271 +\begin{tikzpicture}[scale=2]
272 + \node[state] (0) at (0,0) {\matrix 3000};
273 + \node[state] (1) at (1,0) {\matrix 1100};
274 + \draw[fire] (0) -- node[above] {$t$} (1);
275 + \node[state] (2) at (2,0) {\matrix 1001};
276 + \draw[fire] (1) -- node[above] {$u$} (2);
277 + \node[state] (3) at (3,0) {\matrix 1020};
278 + \draw[fire] (2) -- node[above] {$v$} (3);
279 + \node[state] (4) at (4,0) {\matrix 2010};
280 + \draw[fire] (3) -- node[above] {$w$} (4);
281 + \draw[fire] (4) |- node[near end,above] {$w$} +(-1,.5) -| (0);
282 + \node[state] (5) at (1,-1) {\matrix 0110};
283 + \draw[fire] (4) |- node[pos=.05,right] {$t$} +(-1,-1.5) -| (5);
284 + \draw[fire] (5) -- node[left] {$w$} (1);
285 + \node[state] (6) at (2,-1) {\matrix 0011};
286 + \draw[fire] (5) -- node[above] {$u$} (6);
287 + \draw[fire] (6) -- node[left] {$w$} (2);
288 + \node[state] (7) at (3,-1) {\matrix 0030};
289 + \draw[fire] (7) -- node[left] {$w$} (3);
290 + \draw[fire] (6) -- node[above] {$v$} (7);
291 +\end{tikzpicture}
292 +
293 +% Revoyons cette action au ralenti...
294 +
295 +% On remarque qu'Adam, contrairement à Carl, n'a aucun blocage.
296 +% (C'est un réseau épanoui.)
297 +
298 +%%%
299 +
300 +% Notre chapitre 1 est maintenant terminé.
301 +
302 +% À bientôt pour le chapitre 2: pourquoi ?
303 +
304 +\end{document}
1 +from t2g import *
2 +
3 +#######################
4 +
5 +load("chap2-gates.tex")
6 +
7 +state = {"low": 0, "high": 1}
8 +active = {"down": "", "up": ""}
9 +
10 +frame(.8)
11 +active["down"] = "active"
12 +frame(.8)
13 +active["down"] = ""
14 +state = {"low": 1, "high": 0}
15 +frame(.8)
16 +active["up"] = "active"
17 +frame(.8)
18 +
19 +gif("chap2-gates.gif")
20 +
21 +#######################
22 +
23 +load("chap2-track.tex")
24 +
25 +state = {"far": 1, "before": 0, "inside": 0}
26 +active = {"enter": "", "exit": "", "approach": ""}
27 +
28 +frame(.8)
29 +active["approach"] = "active"
30 +frame(.8)
31 +active["approach"] = ""
32 +state = {"far": 0, "before": 1, "inside": 0}
33 +frame(.8)
34 +active["enter"] = "active"
35 +frame(.8)
36 +active["enter"] = ""
37 +state = {"far": 0, "before": 0, "inside": 1}
38 +frame(.8)
39 +active["exit"] = "active"
40 +frame(.8)
41 +
42 +gif("chap2-track.gif")
43 +
44 +#######################
45 +
46 +load("chap2-draft.tex")
47 +
48 +state = {"far": 1, "before": 0, "inside": 0, "low": 0, "high": 1, "godown": 0, "goup": 0}
49 +active = {"enter": "", "exit": "", "approach": "", "down": "", "up": ""}
50 +
51 +frame(.8)
52 +active["approach"] = "active"
53 +frame(.8)
54 +active["approach"] = ""
55 +state = {"far": 0, "before": 1, "inside": 0, "low": 0, "high": 1, "godown": 1, "goup": 0}
56 +frame(.8)
57 +active["down"] = "active"
58 +frame(.8)
59 +active["down"] = ""
60 +state = {"far": 0, "before": 1, "inside": 0, "low": 1, "high": 0, "godown": 0, "goup": 0}
61 +frame(.8)
62 +active["enter"] = "active"
63 +frame(.8)
64 +active["enter"] = ""
65 +state = {"far": 0, "before": 0, "inside": 1, "low": 1, "high": 0, "godown": 0, "goup": 0}
66 +frame(.8)
67 +active["exit"] = "active"
68 +frame(.8)
69 +active["exit"] = ""
70 +state = {"far": 1, "before": 0, "inside": 0, "low": 1, "high": 0, "godown": 0, "goup": 1}
71 +frame(.8)
72 +active["up"] = "active"
73 +frame(.8)
74 +
75 +gif("chap2-draft.gif")
76 +
77 +#######################
78 +
79 +load("chap2-test.tex")
80 +
81 +state = {"far": 1, "before": 0, "inside": 0, "low": 0, "high": 1, "godown": 0, "goup": 0}
82 +active = {"enter": "", "exit": "", "approach": "", "down": "", "up": "",
83 + 0: "active"}
84 +active.update((s, "") for s in range(1,5))
85 +
86 +frame(.8)
87 +active["approach"] = "active"
88 +frame(.8)
89 +active["approach"] = active[0] = ""
90 +active[1] = "active"
91 +state = {"far": 0, "before": 1, "inside": 0, "low": 0, "high": 1, "godown": 1, "goup": 0}
92 +frame(.8)
93 +active["down"] = "active"
94 +frame(.8)
95 +active["down"] = active[1] = ""
96 +active[2] = "active"
97 +state = {"far": 0, "before": 1, "inside": 0, "low": 1, "high": 0, "godown": 0, "goup": 0}
98 +frame(.8)
99 +active["enter"] = "active"
100 +frame(.8)
101 +active["enter"] = active[2] = ""
102 +active[3] = "active"
103 +state = {"far": 0, "before": 0, "inside": 1, "low": 1, "high": 0, "godown": 0, "goup": 0}
104 +frame(.8)
105 +active["exit"] = "active"
106 +frame(.8)
107 +active["exit"] = active[3] = ""
108 +active[4] = "active"
109 +state = {"far": 1, "before": 0, "inside": 0, "low": 1, "high": 0, "godown": 0, "goup": 1}
110 +frame(.8)
111 +active["up"] = "active"
112 +frame(.8)
113 +
114 +gif("chap2-test.gif", dpi=450)
1 +\documentclass[multi={tikzpicture},crop=true,border=5pt]{standalone}
2 +
3 +\usepackage[utf8]{inputenc}
4 +
5 +\usepackage{verbatim}
6 +\usepackage{tikz}
7 +\usetikzlibrary{shapes,arrows,arrows.meta,petri}
8 +\tikzset{
9 + >=latex,
10 + every place/.style={minimum size=6mm},
11 + every transition/.style={minimum size=6mm},
12 + token distance=6pt,
13 +}
14 +
15 +\tikzstyle{trans}=[transition]
16 +
17 +\tikzstyle{arc}=[->,rounded corners]
18 +
19 +\tikzstyle{state}=[draw=blue!50!gray!50!white,
20 + fill=blue!70!gray!10!white,
21 + line width=2pt,
22 + cloud,cloud puffs=8,
23 + inner sep=-1pt]
24 +
25 +\tikzstyle{fire}=[arrows={-Straight Barb[scale=.6]},
26 + shorten >=-2pt, shorten <=-1pt,
27 + draw=blue!50!gray!50!white,
28 + line width=2pt,
29 + line cap=round,
30 + rounded corners]
31 +
32 +\tikzstyle{active}=[draw=green!50!gray!50!white,
33 + fill=green!70!gray!10!white]
34 +
35 +\begin{document}
36 +
37 +%%FRAME
38 +
39 +\begin{tikzpicture}[scale=1.2]
40 + \node[trans,{{ active["approach"] }}] (approach) at (0,0) {};
41 + \node[rotate=45] at (approach) {\tiny\textsf{approche}};
42 + \node[place,tokens={{ state["before"] }}] (before) at (1,0) {};
43 + \node[below] at (before.south) {\tiny\textsf{avant}};
44 + \node[trans,{{ active["enter"] }}] (enter) at (2,0) {};
45 + \node[rotate=45] at (enter) {\tiny\textsf{entre}};
46 + \node[place,tokens={{ state["inside"] }}] (inside) at (3,0) {};
47 + \node[below] at (inside.south) {\tiny\textsf{dedans}};
48 + \node[trans,{{ active["exit"] }}] (exit) at (4,0) {};
49 + \node[rotate=45] at (exit) {\tiny\textsf{sort}};
50 + \node[place,tokens={{ state["far"] }}] (far) at (2,-1) {};
51 + \node[below] at (far.south) {\tiny\textsf{loin}};
52 + \draw[arc] (before) -- (enter);
53 + \draw[arc] (enter) -- (inside);
54 + \draw[arc] (inside) -- (exit);
55 + \draw[arc] (exit) |- (far);
56 + \draw[arc] (far) -| (approach);
57 + \draw[arc] (approach) -- (before);
58 + %
59 + \node[place,tokens={{ state["low"] }}] (low) at (2,1) {};
60 + \node[below] at (low.south) {\tiny\textsf{bas}};
61 + \node[place,tokens={{ state["high"] }}] (high) at (2,3) {};
62 + \node[above] at (high.north) {\tiny\textsf{haut}};
63 + \node[trans,{{ active["down"] }}] (down) at (1,2) {};
64 + \node[rotate=45] at (down) {\tiny\textsf{baisse}};
65 + \node[trans,{{ active["up"] }}] (up) at (3,2) {};
66 + \node[rotate=45] at (up) {\tiny\textsf{lève}};
67 + \draw[arc] (high) -| (down);
68 + \draw[arc] (down) |- (low);
69 + \draw[arc] (low) -| (up);
70 + \draw[arc] (up) |- (high);
71 + %
72 + \node[place,tokens={{ state["godown"] }}] (godown) at (0,2) {};
73 + \node[above] at (godown.north) {\tiny\textsf{descendre}};
74 + \draw[arc] (approach) -- (godown);
75 + \draw[arc] (godown) -- (down);
76 + \node[place,tokens={{ state["goup"] }}] (goup) at (4,2) {};
77 + \node[above] at (goup.north) {\tiny\textsf{relever}};
78 + \draw[arc] (exit) -- (goup);
79 + \draw[arc] (goup) -- (up);
80 +\end{tikzpicture}
81 +
82 +%%/FRAME
83 +
84 +\end{document}
1 +\documentclass[multi={tikzpicture},crop=true,border=5pt]{standalone}
2 +
3 +\usepackage[utf8]{inputenc}
4 +
5 +\usepackage{verbatim}
6 +\usepackage{tikz}
7 +\usetikzlibrary{shapes,arrows,arrows.meta,petri}
8 +\tikzset{
9 + >=latex,
10 + every place/.style={minimum size=6mm},
11 + every transition/.style={minimum size=6mm},
12 + token distance=6pt,
13 +}
14 +
15 +\tikzstyle{trans}=[transition]
16 +
17 +\tikzstyle{arc}=[->,rounded corners]
18 +
19 +\tikzstyle{state}=[draw=blue!50!gray!50!white,
20 + fill=blue!70!gray!10!white,
21 + line width=2pt,
22 + cloud,cloud puffs=8,
23 + inner sep=-1pt]
24 +
25 +\tikzstyle{fire}=[arrows={-Straight Barb[scale=.6]},
26 + shorten >=-2pt, shorten <=-1pt,
27 + draw=blue!50!gray!50!white,
28 + line width=2pt,
29 + line cap=round,
30 + rounded corners]
31 +
32 +\tikzstyle{active}=[draw=green!50!gray!50!white,
33 + fill=green!70!gray!10!white]
34 +
35 +\begin{document}
36 +
37 +%%FRAME
38 +
39 +\begin{tikzpicture}[scale=1.2]
40 + \node[place,tokens={{ state["low"] }}] (low) at (0,0) {};
41 + \node[below] at (low.south) {\tiny\textsf{bas}};
42 + \node[place,tokens={{ state["high"] }}] (high) at (0,2) {};
43 + \node[above] at (high.north) {\tiny\textsf{haut}};
44 + \node[trans,{{ active["down"] }}] (down) at (-1,1) {};
45 + \node[rotate=45] at (down) {\tiny\textsf{baisse}};
46 + \node[trans,{{ active["up"] }}] (up) at (1,1) {};
47 + \node[rotate=45] at (up) {\tiny\textsf{lève}};
48 + \draw[arc] (high) -| (down);
49 + \draw[arc] (down) |- (low);
50 + \draw[arc] (low) -| (up);
51 + \draw[arc] (up) |- (high);
52 + {% if state["low"] == 1 %}
53 + \node at (2.5,1) {\includegraphics[width=2cm]{../chap2/low}};
54 + {% else %}
55 + \node at (2.5,1) {\includegraphics[width=2cm]{../chap2/high}};
56 + {% endif %}
57 +\end{tikzpicture}
58 +
59 +%%/FRAME
60 +
61 +\end{document}
1 +\documentclass[multi={tikzpicture},crop=true,border=5pt]{standalone}
2 +
3 +\usepackage[utf8]{inputenc}
4 +
5 +\usepackage{verbatim}
6 +\usepackage{tikz}
7 +\usetikzlibrary{shapes,arrows,arrows.meta,petri}
8 +\tikzset{
9 + >=latex,
10 + every place/.style={minimum size=6mm},
11 + every transition/.style={minimum size=6mm},
12 + token distance=6pt,
13 +}
14 +
15 +\tikzstyle{trans}=[transition]
16 +
17 +\tikzstyle{arc}=[->,rounded corners]
18 +
19 +\tikzstyle{state}=[draw=blue!50!gray!50!white,
20 + fill=blue!70!gray!10!white,
21 + line width=2pt,
22 + cloud,cloud puffs=8,
23 + inner sep=-3pt]
24 +
25 +\tikzstyle{fire}=[arrows={-Straight Barb[scale=.6]},
26 + shorten >=-2pt, shorten <=-1pt,
27 + draw=blue!50!gray!50!white,
28 + fill opacity=0,
29 + text opacity=1,
30 + line width=2pt,
31 + line cap=round,
32 + rounded corners]
33 +
34 +\tikzstyle{active}=[draw=green!50!gray!50!white,
35 + fill=green!70!gray!10!white]
36 +
37 +\def\matrix #1#2#3#4#5#6#7{%
38 + {\small$\begin{array}{c@{\hspace{12pt}}c}
39 + \multicolumn{2}{c}{#1} \\[-6pt]
40 + #2 & #3 \\[-6pt]
41 + \multicolumn{2}{c}{\color{red}#4} \\[-6pt]
42 + #5 & \color{red}#6 \\[-6pt]
43 + \multicolumn{2}{c}{#7}
44 + \end{array}$}}
45 +
46 +\begin{document}
47 +
48 +%%FRAME
49 +
50 +\begin{tikzpicture}[scale=1.2]
51 + \node[trans,{{ active["approach"] }}] (approach) at (0,0) {};
52 + \node[rotate=45] at (approach) {\tiny\textsf{approche}};
53 + \node[place,tokens={{ state["before"] }}] (before) at (1,0) {};
54 + \node[below] at (before.south) {\tiny\textsf{avant}};
55 + \node[trans,{{ active["enter"] }}] (enter) at (2,0) {};
56 + \node[rotate=45] at (enter) {\tiny\textsf{entre}};
57 + \node[place,tokens={{ state["inside"] }}] (inside) at (3,0) {};
58 + \node[below] at (inside.south) {\tiny\textsf{dedans}};
59 + \node[trans,{{ active["exit"] }}] (exit) at (4,0) {};
60 + \node[rotate=45] at (exit) {\tiny\textsf{sort}};
61 + \node[place,tokens={{ state["far"] }}] (far) at (2,-1) {};
62 + \node[below] at (far.south) {\tiny\textsf{loin}};
63 + \draw[arc] (before) -- (enter);
64 + \draw[arc] (enter) -- (inside);
65 + \draw[arc] (inside) -- (exit);
66 + \draw[arc] (exit) |- (far);
67 + \draw[arc] (far) -| (approach);
68 + \draw[arc] (approach) -- (before);
69 + %
70 + \node[place,tokens={{ state["low"] }}] (low) at (2,1) {};
71 + \node[below] at (low.south) {\tiny\textsf{bas}};
72 + \node[place,tokens={{ state["high"] }}] (high) at (2,3) {};
73 + \node[above] at (high.north) {\tiny\textsf{haut}};
74 + \node[trans,{{ active["down"] }}] (down) at (1,2) {};
75 + \node[rotate=45] at (down) {\tiny\textsf{baisse}};
76 + \node[trans,{{ active["up"] }}] (up) at (3,2) {};
77 + \node[rotate=45] at (up) {\tiny\textsf{lève}};
78 + \draw[arc] (high) -| (down);
79 + \draw[arc] (down) |- (low);
80 + \draw[arc] (low) -| (up);
81 + \draw[arc] (up) |- (high);
82 + %
83 + \node[place,tokens={{ state["godown"] }}] (godown) at (0,2) {};
84 + \node[above] at (godown.north) {\tiny\textsf{descendre}};
85 + \draw[arc] (approach) -- (godown);
86 + \draw[arc] (godown) -- (down);
87 + \node[place,tokens={{ state["goup"] }}] (goup) at (4,2) {};
88 + \node[above] at (goup.north) {\tiny\textsf{relever}};
89 + \draw[arc] (exit) -- (goup);
90 + \draw[arc] (goup) -- (up);
91 + %
92 + \begin{scope}[scale=2,yshift=-12mm]
93 + \node[state,{{ active[0] }}] (0) at (0,0) {\matrix 1000001};
94 + \node[state,{{ active[1] }}] (1) at (1,0) {\matrix 1100100};
95 + \node[state,{{ active[2] }}] (2) at (2,0) {\matrix 0001100};
96 + \node[state,{{ active[3] }}] (3) at (1.5,-1) {\matrix 0001010};
97 + \node[state,{{ active[4] }}] (4) at (.5,-1) {\matrix 0011001};
98 + \draw[fire,{{ active["approach"] }}] (0) -- node[above]{\tiny\textsf{approche}} (1);
99 + \draw[fire,{{ active["down"] }}] (1) -- node[above]{\tiny\textsf{baisse}} (2);
100 + \draw[fire,{{ active["enter"] }}] (2) |- node[left,pos=.1]{\tiny\textsf{entre}} (3);
101 + \draw[fire,{{ active["exit"] }}] (3) -- node[above]{\tiny\textsf{sort}} (4);
102 + \draw[fire,{{ active["up"] }}] (4) -| node[left,pos=.6]{\tiny\textsf{lève}} (0);
103 + \end{scope}
104 +\end{tikzpicture}
105 +
106 +%%/FRAME
107 +
108 +\end{document}
1 +\documentclass[multi={tikzpicture},crop=true,border=5pt]{standalone}
2 +
3 +\usepackage[utf8]{inputenc}
4 +
5 +\usepackage{verbatim}
6 +\usepackage{tikz}
7 +\usetikzlibrary{shapes,arrows,arrows.meta,petri}
8 +\tikzset{
9 + >=latex,
10 + every place/.style={minimum size=6mm},
11 + every transition/.style={minimum size=6mm},
12 + token distance=6pt,
13 +}
14 +
15 +\tikzstyle{trans}=[transition]
16 +
17 +\tikzstyle{arc}=[->,rounded corners]
18 +
19 +\tikzstyle{state}=[draw=blue!50!gray!50!white,
20 + fill=blue!70!gray!10!white,
21 + line width=2pt,
22 + cloud,cloud puffs=8,
23 + inner sep=-1pt]
24 +
25 +\tikzstyle{fire}=[arrows={-Straight Barb[scale=.6]},
26 + shorten >=-2pt, shorten <=-1pt,
27 + draw=blue!50!gray!50!white,
28 + line width=2pt,
29 + line cap=round,
30 + rounded corners]
31 +
32 +\tikzstyle{active}=[draw=green!50!gray!50!white,
33 + fill=green!70!gray!10!white]
34 +
35 +\begin{document}
36 +
37 +%%FRAME
38 +
39 +\begin{tikzpicture}[scale=1.2]
40 + \node[trans,{{ active["approach"] }}] (approach) at (0,0) {};
41 + \node[rotate=45] at (approach) {\tiny\textsf{approche}};
42 + \node[place,tokens={{ state["before"] }}] (before) at (1,0) {};
43 + \node[below] at (before.south) {\tiny\textsf{avant}};
44 + \node[trans,{{ active["enter"] }}] (enter) at (2,0) {};
45 + \node[rotate=45] at (enter) {\tiny\textsf{entre}};
46 + \node[place,tokens={{ state["inside"] }}] (inside) at (3,0) {};
47 + \node[below] at (inside.south) {\tiny\textsf{dedans}};
48 + \node[trans,{{ active["exit"] }}] (exit) at (4,0) {};
49 + \node[rotate=45] at (exit) {\tiny\textsf{sort}};
50 + \node[place,tokens={{ state["far"] }}] (far) at (2,-1) {};
51 + \node[below] at (far.south) {\tiny\textsf{loin}};
52 + \draw[arc] (before) -- (enter);
53 + \draw[arc] (enter) -- (inside);
54 + \draw[arc] (inside) -- (exit);
55 + \draw[arc] (exit) |- (far);
56 + \draw[arc] (far) -| (approach);
57 + \draw[arc] (approach) -- (before);
58 + {% if state["far"] == 1 %}
59 + \node at (5.5,-.5) {\includegraphics[width=2cm]{../chap2/far}};
60 + {% elif state["before"] == 1 %}
61 + \node at (5.5,-.5) {\includegraphics[width=2cm]{../chap2/close}};
62 + {% else %}
63 + \node at (5.5,-.5) {\includegraphics[width=2cm]{../chap2/inside}};
64 + {% endif %}
65 +\end{tikzpicture}
66 +
67 +%%/FRAME
68 +
69 +\end{document}
1 +\documentclass[multi={tikzpicture},crop=true,border=5pt]{standalone}
2 +
3 +\usepackage[utf8]{inputenc}
4 +\usepackage{multirow}
5 +
6 +\usepackage{verbatim}
7 +\usepackage{tikz}
8 +\usetikzlibrary{shapes,arrows,arrows.meta,petri}
9 +\tikzset{
10 + >=latex,
11 + every place/.style={minimum size=6mm},
12 + every transition/.style={minimum size=6mm},
13 + token distance=6pt,
14 +}
15 +
16 +\tikzstyle{trans}=[transition]
17 +
18 +\tikzstyle{arc}=[->,rounded corners]
19 +
20 +\tikzstyle{state}=[draw=blue!50!gray!50!white,
21 + fill=blue!70!gray!10!white,
22 + line width=2pt,
23 + cloud,cloud puffs=8,
24 + inner sep=-3pt]
25 +
26 +\tikzstyle{fire}=[arrows={-Straight Barb[scale=.6]},
27 + shorten >=-2pt, shorten <=-1pt,
28 + draw=blue!50!gray!50!white,
29 + fill opacity=0,text opacity=1,
30 + line width=2pt,
31 + line cap=round,
32 + rounded corners]
33 +
34 +\tikzstyle{active}=[draw=green!50!gray!50!white,
35 + fill=green!70!gray!10!white]
36 +
37 +\tikzstyle{failure}=[draw=red!50!gray!50!white,
38 + fill=red!70!gray!10!white]
39 +
40 +\def\matrix #1#2#3#4#5#6#7{%
41 + {\small$\begin{array}{c@{\hspace{12pt}}c}
42 + \multicolumn{2}{c}{#1} \\[-6pt]
43 + #2 & #3 \\[-6pt]
44 + \multicolumn{2}{c}{\color{red}#4} \\[-6pt]
45 + #5 & \color{red}#6 \\[-6pt]
46 + \multicolumn{2}{c}{#7}
47 + \end{array}$}}
48 +
49 +\begin{document}
50 +
51 +%%
52 +%%
53 +
54 +\begin{comment}
55 +Les réseaux de Petri
56 +
57 +Chapitre 2. Pourquoi ?
58 +Où l'on apprend à quoi servent les réseaux de Petri.
59 +\end{comment}
60 +
61 +\begin{comment}
62 +On utilise généralement les réseaux de Petri pour faire des modèles.
63 +
64 +Non, pas vous monsieur, laissez-nous travailler, merci.
65 +\end{comment}
66 +
67 +% model.gif
68 +
69 +\begin{comment}
70 +Un modèle est une simplification d'un système dont l'étude n'est pas aisée.
71 +
72 +Le modèle étant plus simple, on peut l'analyser plus facilement.
73 +
74 +Les conclusions de l'analyse sur le modèle pourront être reportées sur le système.
75 +\end{comment}
76 +
77 +\begin{comment}
78 +Par exemple, en biologie, la souris est un modèle de l'humain.
79 +\end{comment}
80 +
81 +% mouse.gif
82 +
83 +\begin{comment}
84 +On ne peut pas facilement tester de nouveaux traitements sur des humains, mais on peut plus facilement le faire sur des souris, et en tirer des conclusions quant à l'effet du traitement sur les humains.
85 +\end{comment}
86 +
87 +\begin{comment}
88 +Avec des réseaux de Petri, on peut construire des modèles de systèmes très variés : systèmes critiques, protocoles de sécurité, systèmes biologiques, écosystèmes, etc.
89 +\end{comment}
90 +
91 +\begin{comment}
92 +Trêve de bavardages, voici donc un système à étudier. C'est un système critique : son fonctionnement met en jeu des vies humaines.
93 +\end{comment}
94 +
95 +% train complet
96 +
97 +\begin{comment}
98 +C'est un système jouet (ah ah) très classique car il est assez simple.
99 +
100 +Des trains circulent sur un voie qui croise une route.
101 +
102 +Des barrières doivent se baisser au passage du train pour éviter une collision avec une voiture.
103 +\end{comment}
104 +
105 +\begin{comment}
106 +Une solution facile est de toujours laisser les barrières fermées.
107 +
108 +Mais ne cédons pas à la facilité.
109 +\end{comment}
110 +
111 +\begin{comment}
112 +Voici donc un modèle des barrières.
113 +
114 +Elles peuvent être en haut ou en bas, deux transitions se chargent de les baisser ou les lever.
115 +
116 +C'est un modèle, on simplifie en faisant abstraction du mouvement.
117 +\end{comment}
118 +
119 +% gates.gif
120 +
121 +\begin{comment}
122 +Et voici un modèle de la voie et du train. On représente trois positions cruciales en faisant abstraction des autres.
123 +\end{comment}
124 +
125 +% track.gif
126 +
127 +\begin{comment}
128 +Dans le modèle complet, on retrouve ces deux morceaux qui communiquent via des places permettant à la voie de demander à la barrière de se lever ou de se baisser.
129 +
130 +Regardons le fonctionner.
131 +\end{comment}
132 +
133 +% draft.gif
134 +
135 +\begin{comment}
136 +On a gagné !
137 +On dépose un brevet et on vend notre conception à la SNCF.
138 +On va être millionnaires.
139 +
140 +... Vraiment ?
141 +\end{comment}
142 +
143 +\begin{comment}
144 +On n'a rien oublié ?
145 +\end{comment}
146 +
147 +\begin{comment}
148 +Reprenons.
149 +
150 +Un modèle simplifie la réalité. Ça c'est fait.
151 +
152 +Il peut être analysé. C'est fait ou pas ?
153 +\end{comment}
154 +
155 +\begin{comment}
156 +Non bien sûr !
157 +
158 +Ce qu'on a fait c'est exécuter sur le modèle une séquence d'actions correcte. On a donc juste prouvé que le modèle est capable d'avoir le comportement attendu. Pas qu'il n'a pas de mauvais comportements.
159 +\end{comment}
160 +
161 +\begin{comment}
162 +Pour prouver qu'il n'existe aucun comportement fautif, on va calculer le graphe de marquages en vérifiant qu'aucun marquage découvert n'a de jeton dans la place 'dedans' sans jeton dans la place 'bas'.
163 +\end{comment}
164 +
165 +\begin{comment}
166 +En effet, s'il la place 'dedans' est marquée, c'est que le train se trouve entre les barrières. Il faut alors absolument qu'elles soient fermées.
167 +\end{comment}
168 +
169 +\begin{comment}
170 +Allons-y. L'état initial peut se représenter par le nombre de jeton dans chaque place comme on l'a fait dans le chapitre 1. Et en rouge, on a les deux places à surveiller ('bas' et en haut et 'dedans' est le plus extérieur... hum...).
171 +\end{comment}
172 +
173 +\begin{tikzpicture}
174 + \node[state] {\matrix 1000001};
175 +\end{tikzpicture}
176 +
177 +\begin{comment}
178 +Notre scénario correct donne un graphe simple:
179 +\end{comment}
180 +
181 +% test.gif
182 +
183 +\begin{comment}
184 +Mais lieu de tirer les transitions qui nous arrangent, essayons les toutes. On observe qu'au début, on peut juste tirer 'approche'. Et ensuite, on peut bien sûr tirer 'baisse' mais aussi 'entre'.
185 +
186 +Catastrophe !
187 +\end{comment}
188 +
189 +\begin{tikzpicture}[scale=1.2]
190 + \node[trans] (approach) at (0,0) {};
191 + \node[rotate=45] at (approach) {\tiny\textsf{approche}};
192 + \node[place] (before) at (1,0) {};
193 + \node[below] at (before.south) {\tiny\textsf{avant}};
194 + \node[trans] (enter) at (2,0) {};
195 + \node[rotate=45] at (enter) {\tiny\textsf{entre}};
196 + \node[place,tokens=1] (inside) at (3,0) {};
197 + \node[below] at (inside.south) {\tiny\textsf{dedans}};
198 + \node[trans] (exit) at (4,0) {};
199 + \node[rotate=45] at (exit) {\tiny\textsf{sort}};
200 + \node[place] (far) at (2,-1) {};
201 + \node[below] at (far.south) {\tiny\textsf{loin}};
202 + \draw[arc] (before) -- (enter);
203 + \draw[arc] (enter) -- (inside);
204 + \draw[arc] (inside) -- (exit);
205 + \draw[arc] (exit) |- (far);
206 + \draw[arc] (far) -| (approach);
207 + \draw[arc] (approach) -- (before);
208 + %
209 + \node[place] (low) at (2,1) {};
210 + \node[below] at (low.south) {\tiny\textsf{bas}};
211 + \node[place,tokens=1] (high) at (2,3) {};
212 + \node[above] at (high.north) {\tiny\textsf{haut}};
213 + \node[trans] (down) at (1,2) {};
214 + \node[rotate=45] at (down) {\tiny\textsf{baisse}};
215 + \node[trans] (up) at (3,2) {};
216 + \node[rotate=45] at (up) {\tiny\textsf{lève}};
217 + \draw[arc] (high) -| (down);
218 + \draw[arc] (down) |- (low);
219 + \draw[arc] (low) -| (up);
220 + \draw[arc] (up) |- (high);
221 + %
222 + \node[place,tokens=1] (godown) at (0,2) {};
223 + \node[above] at (godown.north) {\tiny\textsf{descendre}};
224 + \draw[arc] (approach) -- (godown);
225 + \draw[arc] (godown) -- (down);
226 + \node[place] (goup) at (4,2) {};
227 + \node[above] at (goup.north) {\tiny\textsf{relever}};
228 + \draw[arc] (exit) -- (goup);
229 + \draw[arc] (goup) -- (up);
230 + %
231 + \begin{scope}[scale=2,yshift=-12mm]
232 + \node[state] (0) at (0,0) {\matrix 1000001};
233 + \node[state] (1) at (1,0) {\matrix 1100100};
234 + \node[state] (2) at (2,0) {\matrix 0001100};
235 + \node[state,failure] (5) at (1,-1) {\matrix 1100010};
236 + \draw[fire] (0) -- node[above]{\tiny\textsf{approche}} (1);
237 + \draw[fire] (1) -- node[above]{\tiny\textsf{baisse}} (2);
238 + \draw[fire,failure] (1) -- node[left]{\tiny\textsf{entre}} (5);
239 + \end{scope}
240 +\end{tikzpicture}
241 +
242 +\begin{comment}
243 +Mais que s'est-il passé ?
244 +
245 +Comment cela est-il possible ?
246 +\end{comment}
247 +
248 +\begin{comment}
249 +Pour répondre, il suffit de regarder la séquence d'actions jusqu'au marquage fautif.
250 +
251 +Le train s'est approché, a envoyé le signal de descente à la barrière, mais celle-ci n'a pas bougé avant que le train n'arrive à son niveau.
252 +\end{comment}
253 +
254 +\begin{comment}
255 +Nos barrières sont-elles trop lentes ? Faut-il les forcer à descendre tout de suite ?
256 +
257 +Non. Ce scénario peut aussi correspondre à des barrières cassées.
258 +\end{comment}
259 +
260 +\begin{comment}
261 +Donc, si on ne peut pas forcer les barrières à descendre, il faut empêcher le train d'avancer tant que les barrières ne sont pas fermées.
262 +
263 +Mais comment ? (Suspense...)
264 +\end{comment}
265 +
266 +\begin{comment}
267 +Mesdames, messieurs, je vous présente : le feu rouge ! Sous vos applaudissements.
268 +\end{comment}
269 +
270 +% feu-rouge.jpg
271 +
272 +\begin{comment}
273 +On va donc ajouter un feu à notre modèle : une place 'feu' telle qu'un jeton dedans représente le feu vert, et pas de jeton le feu rouge.
274 +\end{comment}
275 +
276 +\begin{comment}
277 +Quand le train approche, il met le feu au rouge.
278 +
279 +Il ne peut entrer entre les barrières que si le feu est vert.
280 +
281 +C'est l'arrivée des barrières en bas qui met le feu au vert.
282 +
283 +Voilà.
284 +\end{comment}
285 +
286 +\begin{tikzpicture}[scale=1.2]
287 + \node[trans] (approach) at (0,0) {};
288 + \node[rotate=45] at (approach) {\tiny\textsf{approche}};
289 + \node[place] (before) at (1,0) {};
290 + \node[below] at (before.south) {\tiny\textsf{avant}};
291 + \node[trans] (enter) at (2,0) {};
292 + \node[rotate=45] at (enter) {\tiny\textsf{entre}};
293 + \node[place] (inside) at (3,0) {};
294 + \node[below] at (inside.south) {\tiny\textsf{dedans}};
295 + \node[trans] (exit) at (4,0) {};
296 + \node[rotate=45] at (exit) {\tiny\textsf{sort}};
297 + \node[place,tokens=1] (far) at (2,-1) {};
298 + \node[below] at (far.south) {\tiny\textsf{loin}};
299 + \draw[arc] (before) -- (enter);
300 + \draw[arc] (enter) -- (inside);
301 + \draw[arc] (inside) -- (exit);
302 + \draw[arc] (exit) |- (far);
303 + \draw[arc] (far) -| (approach);
304 + \draw[arc] (approach) -- (before);
305 + %
306 + \node[place] (low) at (2,1) {};
307 + \node[below] at (low.south) {\tiny\textsf{bas}};
308 + \node[place,tokens=1] (high) at (2,3) {};
309 + \node[above] at (high.north) {\tiny\textsf{haut}};
310 + \node[trans] (down) at (1,2) {};
311 + \node[rotate=45] at (down) {\tiny\textsf{baisse}};
312 + \node[trans] (up) at (3,2) {};
313 + \node[rotate=45] at (up) {\tiny\textsf{lève}};
314 + \draw[arc] (high) -| (down);
315 + \draw[arc] (down) |- (low);
316 + \draw[arc] (low) -| (up);
317 + \draw[arc] (up) |- (high);
318 + %
319 + \node[place] (godown) at (0,2) {};
320 + \node[above] at (godown.north) {\tiny\textsf{descendre}};
321 + \draw[arc] (approach) -- (godown);
322 + \draw[arc] (godown) -- (down);
323 + \node[place] (goup) at (4,2) {};
324 + \node[above] at (goup.north) {\tiny\textsf{relever}};
325 + \draw[arc] (exit) -- (goup);
326 + \draw[arc] (goup) -- (up);
327 + %
328 + \node[place,tokens=1] (green) at (.5,1) {};
329 + \node[above] at (green.130) {\tiny\textsf{feu}};
330 + \draw[arc] (green) -- (approach);
331 + \draw[arc] (down) -- (green);
332 + \draw[<->] (green) -- (enter);
333 +\end{tikzpicture}
334 +
335 +\begin{comment}
336 +Exercice à la maison.
337 +
338 +Dessinez le graphe de marquage de ce réseau et vérifiez que chaque état accessible vérifie la propriété de sécurité : si 'dedans' est marquée, alors 'bas' l'est aussi.
339 +\end{comment}
340 +
341 +\begin{comment}
342 +Ceci clos notre chapitre 2.
343 +
344 +J'ai plusieurs idées de chapitre 3, n'hésitez pas à me poser des question sur ce qui vous intéresserait.
345 +\end{comment}
346 +
347 +%%
348 +%%
349 +
350 +\end{document}
1 +import tempfile, os, os.path, inspect
2 +import jinja2
3 +
4 +class T2G (object) :
5 + def __init__ (self, env, header, body, trailer) :
6 + self.env = env
7 + self.tpl = jinja2.Template(body)
8 + self.trailer = trailer
9 + self.frames = []
10 + self.tmp = tempfile.TemporaryDirectory(suffix=".t2g", dir=os.getcwd())
11 + self.out = open(os.path.join(self.tmp.name, "frames.tex"), "w")
12 + self.out.write(header)
13 + def frame (self, duration) :
14 + env = self.env.copy()
15 + self.out.write("\n%%%%%% FRAME %s\n%s\n"
16 + % (len(self.frames), self.tpl.render(**env)))
17 + self.frames.append(duration * 100)
18 + def gif (self, path, dpi=500) :
19 + self.out.write("\n%%%%%% TRAILER\n\n%s\n" % self.trailer)
20 + self.out.flush()
21 + cwd = os.getcwd()
22 + path = os.path.join(cwd, path)
23 + try :
24 + os.chdir(self.tmp.name)
25 + os.system("latexmk -pdf -cd -f frames.tex")
26 + print("extracting frames")
27 + os.system("convert -background white -alpha remove -density %s"
28 + " frames.pdf frames.png" % dpi)
29 + print("building GIF")
30 + os.system("convert -layers OptimizeFrame -loop 0 %s %s"
31 + % (" ".join("-delay %s frames-%s.png" % (duration, frame)
32 + for frame, duration in enumerate(self.frames)),
33 + path))
34 + print("optimizing GIF")
35 + os.system("gifsicle --batch --optimize=3 %s" % path)
36 + finally :
37 + os.chdir(cwd)
38 +
39 +__t2g__ = None
40 +
41 +def load (path) :
42 + global __t2g__
43 + txt = open(path).read()
44 + header, txt = txt.split("%%FRAME")
45 + body, trailer = txt.split("%%/FRAME")
46 + stack = inspect.stack()
47 + __t2g__ = T2G(stack[1].frame.f_globals, header, body, trailer)
48 +
49 +def frame (duration) :
50 + global __t2g__
51 + assert __t2g__, "no template loaded"
52 + __t2g__.frame(duration)
53 +
54 +def gif (path, dpi=500) :
55 + global __t2g__
56 + assert __t2g__, "no template loaded"
57 + __t2g__.gif(path, dpi)