1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
|
% Copyright 2019 by Till Tantau
%
% This file may be distributed and/or modified
%
% 1. under the LaTeX Project Public License and/or
% 2. under the GNU Free Documentation License.
%
% See the file doc/generic/pgf/licenses/LICENSE for more details.
\section{Petri-Net Drawing Library}
\begin{tikzlibrary}{petri}
This packages provides shapes and styles for drawing Petri nets.
\end{tikzlibrary}
\subsection{Places}
The package defines a style for drawing places of Petri nets.
\begin{stylekey}{/tikz/place}
This style indicates that a node is a place of a Petri net. Usually, the
text of the node should be empty since places do not contain any text. You
should use the |label| option to add text outside the node like its name or
its capacity. You should use the |tokens| options, explained in
Section~\ref{section-tokens}, to add tokens inside the place.
%
\begin{codeexample}[preamble={\usetikzlibrary{petri,positioning}}]
\begin{tikzpicture}
\node[place,label=above:$p_1$,tokens=2] (p1) {};
\node[place,label=below:$p_2\ge1$,right=of p1] (p2) {};
\end{tikzpicture}
\end{codeexample}
\begin{stylekey}{/tikz/every place}
This style is evoked by the style |place|. To change the appearance of
places, you can change this style.
%
\begin{codeexample}[preamble={\usetikzlibrary{petri,positioning}}]
\begin{tikzpicture}
[every place/.style={draw=blue,fill=blue!20,thick,minimum size=9mm}]
\node[place,tokens=7,label=above:$p_1$] (p1) {};
\node[place,structured tokens={3,2,9},
label=below:$p_2\ge1$,right=of p1] (p2) {};
\end{tikzpicture}
\end{codeexample}
\end{stylekey}
\end{stylekey}
\subsection{Transitions}
Transitions are also nodes. They should be drawn using the following style:
\begin{stylekey}{/tikz/transition}
This style indicates that a node is a transition. As for places, the text
of a transition should be empty and the |label| option should be used for
adding labels.
To connect a transition to places, you can use the |edge| command as in the
following example:
%
\begin{codeexample}[preamble={\usetikzlibrary{petri,positioning}}]
\begin{tikzpicture}
\node[place,tokens=2,label=above:$p_1$] (p1) {};
\node[place,label=above:$p_2\ge1$,right=of p1] (p2) {};
\node[transition,below right=of p1,label=below:$t_1$] {}
edge[pre] (p1)
edge[post] node[auto] {2} (p2);
\end{tikzpicture}
\end{codeexample}
\begin{stylekey}{/tikz/every transition}
This style is evoked by the style |transition|.
\end{stylekey}
\begin{stylekey}{/tikz/pre}
This style can be used with paths leading \emph{from} a transition
\emph{to} a place to indicate that the place is in the pre-set of the
transition. By default, this style is |<-,shorten <=1pt|, but feel free
to redefine it.
\end{stylekey}
\begin{stylekey}{/tikz/post}
This style is also used with paths leading \emph{from} a transition
\emph{to} a place, but this time the place is in the post-set of the
transition. Again, feel free to redefine it.
\end{stylekey}
\begin{stylekey}{/tikz/pre and post}
This style is to be used to indicate that a place is both in the pre-
and post-set of a transition.
\end{stylekey}
\end{stylekey}
\subsection{Tokens}
\label{section-tokens}
Interestingly, the most complicated aspect of drawing Petri nets in \tikzname\
turns out to be the placement of tokens.
Let us start with a single token. They are also nodes and there is a simple
style for typesetting them.
\begin{stylekey}{/tikz/token}
This style indicates that a node is a token. By default, this causes the
node to be a small black circle. Unlike places and transitions, it
\emph{does} make sense to provide text for the token node. Such text will
be typeset in a tiny font and in white on black (naturally, you can easily
change this by setting the style |every token|).
%
\begin{codeexample}[preamble={\usetikzlibrary{petri,positioning}}]
\begin{tikzpicture}
\node[place,label=above:$p_1$] (p1) {};
\node[token] at (p1) {};
\node[place,label=above:$p_2$,right=of p1] (p2) {};
\node[token] at (p2) {$y$};
\end{tikzpicture}
\end{codeexample}
%
\begin{stylekey}{/tikz/every token}
Change this style to change the appearance of tokens.
\end{stylekey}
\end{stylekey}
In the above example, it is bothersome that we need an extra command for the
token node. Worse, when we have \emph{two} tokens on a node, it is difficult to
place both nodes inside the node without overlap.
The Petri library offers a solution to this problem: The |children are tokens|
style.
\begin{stylekey}{/tikz/children are tokens}
The idea behind this style is to use trees mechanism for placing tokens.
Every token lying on a place is treated as a child of the node. Normally
this would have the effect that the tokens are placed below the place and
they would be connected to the place by an edge. The |children are tokens|
style, however, redefines the growth function of trees such that it places
the children next to each other inside (or, rather, on top) of the place
node. Additionally, the edge from the parent node is not drawn.
%
\begin{codeexample}[preamble={\usetikzlibrary{petri}}]
\begin{tikzpicture}
\node[place,label=above:$p_1$] {}
[children are tokens]
child {node [token] {1}}
child {node [token] {2}}
child {node [token] {3}};
\end{tikzpicture}
\end{codeexample}
In detail, what happens is the following: Tree growth functions tell
\tikzname\ where it should place the children of nodes. These functions get
passed the number of children that a node has an the number of the child
that should be placed. The special tree growth function for tokens has a
special mapping for each possible number of children up to nine children.
This mapping decides for each child where it should be placed on top of the
place. For example, a single child is placed directly on top of the place.
Two children are placed next to each other, separated by the
|token distance|. Three children are placed in a triangle whose side
lengths are |token distance|; and so on up to nine tokens. If you wish to
place more than nice tokens on a place, you will have to write your own
placement code.
%
\begin{codeexample}[preamble={\usetikzlibrary{petri}}]
\begin{tikzpicture}
\node[place,label=above:$p_2$] {}
[children are tokens]
child {node [token] {1}}
child {node [token,fill=red] {2}}
child {node [token,fill=red] {2}}
child {node [token] {1}};
\end{tikzpicture}
\end{codeexample}
\begin{key}{/tikz/token distance=\meta{distance}}
This specifies the distance between the centers of the tokens in the
arrangements of the option |children are tokens|.
%
\begin{codeexample}[preamble={\usetikzlibrary{petri}}]
\begin{tikzpicture}
\node[place,label=above:$p_3$] {}
[children are tokens,token distance=1.1ex]
child {node [token] {}}
child {node [token,red] {}}
child {node [token,blue] {}}
child {node [token] {}};
\end{tikzpicture}
\end{codeexample}
\end{key}
\end{stylekey}
The |children are tokens| option gives you a lot of flexibility, but it is a
bit cumbersome to use. For this reason there are some options that help in
standard situations. They all use |children are tokens| internally, so any
change to, say, the |every token| style will affect how these options depict
tokens.
\begin{key}{/tikz/tokens=\meta{number}}
This option is given to a |place| node, not to a |token| node. The effect
of this option is to add \meta{number} many child nodes to the place, each
having the style |token|. Thus, the following two pieces of codes have the
same effect:
%
\begin{codeexample}[preamble={\usetikzlibrary{petri}}]
\tikz
\node[place] {}
[children are tokens]
child {node [token] {}}
child {node [token] {}}
child {node [token] {}};
\tikz
\node[place,tokens=3] {};
\end{codeexample}
%
It is legal to say |tokens=0|, no tokens are drawn in this case. This
option does not handle ten or more tokens correctly. If you need this many
tokens, you will have to program your own code.
%
\begin{codeexample}[preamble={\usetikzlibrary{petri}}]
\begin{tikzpicture}[every place/.style={minimum size=9mm}]
\foreach \x/\y/\tokennumber in {0/2/1,1/2/2,2/2/3,
0/1/4,1/1/5,2/1/6,
0/0/7,1/0/8,2/0/9}
\node [place,tokens=\tokennumber] at (\x,\y) {};
\end{tikzpicture}
\end{codeexample}
%
\end{key}
\begin{key}{/tikz/colored tokens=\meta{color list}}
This option, which must also be given when a place node is being created,
gets a list of colors as parameter. It will then add as many tokens to the
place as there are colors in this list, each filled correspondingly.
%
\begin{codeexample}[preamble={\usetikzlibrary{petri}}]
\tikz \node[place,colored tokens={black,black,red,blue}] {};
\end{codeexample}
%
\end{key}
\begin{key}{/tikz/structured tokens=\meta{token texts}}
This option, which must again be passed to a place, gets a list of texts
for tokens. For each text, a new token will be added to the place.
%
\begin{codeexample}[preamble={\usetikzlibrary{petri}}]
\tikz \node[place,structured tokens={$x$,$y$,$z$}] {};
\end{codeexample}
%
\begin{codeexample}[preamble={\usetikzlibrary{petri}}]
\begin{tikzpicture}[every place/.style={minimum size=9mm}]
\foreach \x/\y/\tokennumber in {0/2/1,1/2/2,2/2/3,
0/1/4,1/1/5,2/1/6,
0/0/7,1/0/8,2/0/9}
\node [place,structured tokens={1,...,\tokennumber}] at (\x,\y) {};
\end{tikzpicture}
\end{codeexample}
%
If you use lots of structured tokens, consider redefining the |every token|
style so that the tokens are larger.
\end{key}
\subsection{Examples}
\begin{codeexample}[preamble={\usetikzlibrary{petri}}]
\begin{tikzpicture}[yscale=-1.6,xscale=1.5,thick,
every transition/.style={draw=red,fill=red!20,minimum size=3mm},
every place/.style={draw=blue,fill=blue!20,minimum size=6mm}]
\foreach \i in {1,...,6} {
\node[place,label=left:$p_\i$] (p\i) at (0,\i) {};
\node[place,label=right:$q_\i$] (q\i) at (8,\i) {};
}
\foreach \name/\var/\vala/\valb/\height/\x in
{m1/m_1/f/t/2.25/3,m2/m_2/f/t/2.25/5,h/\mathit{hold}/1/2/4.5/4} {
\node[place,label=above:{$\var = \vala$}] (\name\vala) at (\x,\height) {};
\node[place,yshift=-8mm,label=below:{$\var = \valb$}] (\name\valb) at (\x,\height) {};
}
\node[token] at (p1) {}; \node[token] at (q1) {};
\node[token] at (m1f) {}; \node[token] at (m2f) {};
\node[token] at (h1) {};
\node[transition] at (1.5,1.5) {} edge [pre] (p1) edge [post] (p2);
\node[transition] at (1.5,2.5) {} edge [pre] (p2) edge[pre] (m1f)
edge [post](p3) edge[post] (m1t);
\node[transition] at (1.5,3.3) {} edge [pre] (p3) edge [post] (p4)
edge [pre and post] (h1);
\node[transition] at (1.5,3.7) {} edge [pre] (p3) edge [pre] (h2)
edge [post] (p4) edge [post] (h1.west);
\node[transition] at (1.5,4.3) {} edge [pre] (p4) edge [post] (p5)
edge [pre and post] (m2f);
\node[transition] at (1.5,4.7) {} edge [pre] (p4) edge [post] (p5)
edge [pre and post] (h2);
\node[transition] at (1.5,5.5) {} edge [pre] (p5) edge [pre] (m1t)
edge [post] (p6) edge [post] (m1f);
\node[transition] at (1.5,6.5) {} edge [pre] (p6) edge [post] (p1.south east);
\node[transition] at (6.5,1.5) {} edge [pre] (q1) edge [post] (q2);
\node[transition] at (6.5,2.5) {} edge [pre] (q2) edge [pre] (m2f)
edge [post] (q3) edge [post] (m2t);
\node[transition] at (6.5,3.3) {} edge [pre] (q3) edge [post] (q4)
edge [pre and post] (h2);
\node[transition] at (6.5,3.7) {} edge [pre] (q3) edge [pre] (h1)
edge [post] (q4) edge [post] (h2.east);
\node[transition] at (6.5,4.3) {} edge [pre] (q4) edge [post] (q5)
edge [pre and post] (m1f);
\node[transition] at (6.5,4.7) {} edge [pre] (q4) edge [post] (q5)
edge [pre and post] (h1);
\node[transition] at (6.5,5.5) {} edge [pre] (q5) edge [pre] (m2t)
edge [post] (q6) edge [post] (m2f);
\node[transition] at (6.5,6.5) {} edge [pre] (q6) edge [post] (q1.south west);
\end{tikzpicture}
\end{codeexample}
Here is the same net once more, but with these styles changes:
%
\begin{codeexample}[code only]
\begin{tikzpicture}[yscale=-1.1,thin,>=stealth,
every transition/.style={fill,minimum width=1mm,minimum height=3.5mm},
every place/.style={draw,thick,minimum size=6mm}]
\end{codeexample}
\begin{tikzpicture}[yscale=-1.1,thin,>=stealth,
every transition/.style={fill,minimum width=1mm,minimum height=3.5mm},
every place/.style={draw,thick,minimum size=6mm}]
\foreach \i in {1,...,6} {
\node[place,label=left:$p_\i$] (p\i) at (0,\i) {};
\node[place,label=right:$q_\i$] (q\i) at (8,\i) {};
}
\foreach \name/\var/\vala/\valb/\height/\x in
{m1/m_1/f/t/2.25/3,m2/m_2/f/t/2.25/5,h/\mathit{hold}/1/2/4.5/4} {
\node[place,label=above:{$\var = \vala$}] (\name\vala) at (\x,\height) {};
\node[place,yshift=-8mm,label=below:{$\var = \valb$}] (\name\valb) at (\x,\height) {};
}
\node[token] at (p1) {}; \node[token] at (q1) {};
\node[token] at (m1f) {}; \node[token] at (m2f) {};
\node[token] at (h1) {};
\node[transition] at (1.5,1.5) {} edge [pre] (p1) edge [post] (p2);
\node[transition] at (1.5,2.5) {} edge [pre] (p2) edge [pre] (m1f)
edge [post] (p3) edge [post] (m1t);
\node[transition] at (1.5,3.3) {} edge [pre] (p3) edge [post] (p4)
edge [pre and post] (h1);
\node[transition] at (1.5,3.7) {} edge [pre] (p3) edge [pre] (h2)
edge [post] (p4) edge [post] (h1.west);
\node[transition] at (1.5,4.3) {} edge [pre] (p4) edge [post] (p5)
edge [pre and post] (m2f);
\node[transition] at (1.5,4.7) {} edge [pre] (p4) edge [post] (p5)
edge [pre and post] (h2);
\node[transition] at (1.5,5.5) {} edge [pre] (p5) edge [pre] (m1t)
edge [post] (p6) edge [post] (m1f);
\node[transition] at (1.5,6.5) {} edge [pre] (p6) edge [post] (p1.south east);
\node[transition] at (6.5,1.5) {} edge [pre] (q1) edge [post] (q2);
\node[transition] at (6.5,2.5) {} edge [pre] (q2) edge [pre] (m2f)
edge [post] (q3) edge [post] (m2t);
\node[transition] at (6.5,3.3) {} edge [pre] (q3) edge [post] (q4)
edge [pre and post] (h2);
\node[transition] at (6.5,3.7) {} edge [pre] (q3) edge [pre] (h1)
edge [post] (q4) edge [post] (h2.east);
\node[transition] at (6.5,4.3) {} edge [pre] (q4) edge [post] (q5)
edge [pre and post] (m1f);
\node[transition] at (6.5,4.7) {} edge [pre] (q4) edge [post] (q5)
edge [pre and post] (h1);
\node[transition] at (6.5,5.5) {} edge [pre] (q5) edge [pre] (m2t)
edge [post] (q6) edge [post] (m2f);
\node[transition] at (6.5,6.5) {} edge [pre] (q6) edge [post] (q1.south west);
\end{tikzpicture}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "pgfmanual-pdftex-version"
%%% End:
|