Showing
79 changed files
with
1295 additions
and
0 deletions
Makefile
0 → 100644
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 $< |
chap1-anim.py
0 → 100644
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") |
chap1-anim.tex
0 → 100644
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} |
chap1.tex
0 → 100644
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} |
chap1/chap1-anim.gif
0 → 100644
778 KB
chap1/fig-000.png
0 → 100644
4.05 KB
chap1/fig-001.png
0 → 100644
4.6 KB
chap1/fig-002.png
0 → 100644
2.73 KB
chap1/fig-003.png
0 → 100644
2.81 KB
chap1/fig-004.png
0 → 100644
3.19 KB
chap1/fig-005.png
0 → 100644
7.87 KB
chap1/fig-006.png
0 → 100644
20.2 KB
chap1/fig-007.png
0 → 100644
7.33 KB
chap1/fig-008.png
0 → 100644
6.97 KB
chap1/fig-009.png
0 → 100644
17.4 KB
chap1/fig-010.png
0 → 100644
55.6 KB
chap1/fig-011.png
0 → 100644
18.3 KB
chap1/fig-012.png
0 → 100644
31.6 KB
chap1/fig-013.png
0 → 100644
67.8 KB
chap1/fig-014.png
0 → 100644
73.6 KB
chap1/fig-015.png
0 → 100644
102 KB
chap1/fig-016.png
0 → 100644
128 KB
chap2-anim.py
0 → 100644
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) |
chap2-draft.tex
0 → 100644
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} |
chap2-gates.tex
0 → 100644
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} |
chap2-test.tex
0 → 100644
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} |
chap2-track.tex
0 → 100644
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} |
chap2.tex
0 → 100644
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} |
chap2/chap2-draft.gif
0 → 100644
244 KB
chap2/chap2-gates.gif
0 → 100644
555 KB
chap2/chap2-test.gif
0 → 100644
174 KB
chap2/chap2-track.gif
0 → 100644
615 KB
chap2/close.jpg
0 → 100644
468 KB
chap2/far.jpg
0 → 100644
465 KB
chap2/feu-rouge.jpg
0 → 100644
18.3 KB
chap2/fig-000.png
0 → 100644
21.7 KB
chap2/fig-001.png
0 → 100644
151 KB
chap2/fig-002.png
0 → 100644
37.4 KB
chap2/gates/IMG_6660.JPG
0 → 100644
4.63 MB
chap2/gates/IMG_6661.JPG
0 → 100644
4.69 MB
chap2/high.jpg
0 → 100644
494 KB
chap2/inside.jpg
0 → 100644
476 KB
chap2/low.jpg
0 → 100644
495 KB
chap2/model.gif
0 → 100644
1.89 MB
chap2/mouse.gif
0 → 100644
407 KB
chap2/track.gif
0 → 100644
9.22 MB
chap2/track/IMG_6628.JPG
0 → 100644
5.17 MB
chap2/track/IMG_6629.JPG
0 → 100644
4.98 MB
chap2/track/IMG_6630.JPG
0 → 100644
5.06 MB
chap2/track/IMG_6631.JPG
0 → 100644
5.07 MB
chap2/track/IMG_6632.JPG
0 → 100644
5.03 MB
chap2/track/IMG_6633.JPG
0 → 100644
4.98 MB
chap2/track/IMG_6634.JPG
0 → 100644
5 MB
chap2/track/IMG_6635.JPG
0 → 100644
4.82 MB
chap2/track/IMG_6636.JPG
0 → 100644
4.92 MB
chap2/track/IMG_6637.JPG
0 → 100644
5.27 MB
chap2/track/IMG_6638.JPG
0 → 100644
5.28 MB
chap2/track/IMG_6639.JPG
0 → 100644
4.98 MB
chap2/track/IMG_6640.JPG
0 → 100644
4.72 MB
chap2/track/IMG_6641.JPG
0 → 100644
4.93 MB
chap2/track/IMG_6642.JPG
0 → 100644
4.98 MB
chap2/track/IMG_6643.JPG
0 → 100644
4.65 MB
chap2/track/IMG_6644.JPG
0 → 100644
5 MB
chap2/track/IMG_6645.JPG
0 → 100644
4.71 MB
chap2/track/IMG_6646.JPG
0 → 100644
4.6 MB
chap2/track/IMG_6647.JPG
0 → 100644
5.01 MB
chap2/track/IMG_6648.JPG
0 → 100644
5.04 MB
chap2/track/IMG_6649.JPG
0 → 100644
4.57 MB
chap2/track/IMG_6650.JPG
0 → 100644
5.03 MB
chap2/track/IMG_6651.JPG
0 → 100644
5.05 MB
chap2/track/IMG_6652.JPG
0 → 100644
5.02 MB
chap2/track/IMG_6653.JPG
0 → 100644
5.12 MB
chap2/track/IMG_6654.JPG
0 → 100644
4.87 MB
chap2/track/IMG_6655.JPG
0 → 100644
5.05 MB
chap2/track/IMG_6656.JPG
0 → 100644
4.89 MB
chap2/track/IMG_6657.JPG
0 → 100644
4.99 MB
chap2/track/IMG_6658.JPG
0 → 100644
5.13 MB
chap2/track/IMG_6659.JPG
0 → 100644
5.15 MB
t2g.py
0 → 100644
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) |
-
Please register or login to post a comment