16-bit LaTeX
In my continuing quest to have the worst handwriting ever, I’ve been taking all my notes this quarter on my laptop using LaTeX (namely TeXShop on the Mac). Some of those notes are for Theory of Computation, which naturally involves a bunch of state machines and finite automata; as such, I needed a decent way of typesetting diagrams without resorting to an external image editor and \includegraphics
.
My first attempt involved the open-source visualizer graphviz with a LaTeX package for inline code called graphvizzz. This worked really well for a couple days, but then I ran across this (rather opaque) error:
No room for a new \write
After some Google magic, I found out something rather upsetting about the LaTeX typesetting system: it’s limited to sixteen files of output at any given time. The graphvizzz package used one file per graph (writing temporary PDFs), exhausting LaTeX’s supply of output files (called “registers”).
Even though the consensus turned out to be that this was bad practice - the graphvizzz package should use a single register overall and serialize its use, not use one for every graph all in parallel - the implications are rather disturbing. When was the last time you used an operating system that limited users to 16 open files at a time? Even most hardened systems aren’t that restrictive.
So I turned to the kindly folks at the TeX StackExchange with a question: what can I use instead of graphvizzz? The (almost immediate) answer was to use pgf and tikz instead, and so far it’s been working well: it renders inline, requires no registers, and produces nice-looking graphs. On the downside, the tikz automata don’t auto-route transition arrows (so they overlap unless specified to “bend” in a certain direction), and I have to specify the relative positioning of all the nodes, but after dealing with graphviz’s often-suboptimal layout engine and subgraph support, it’s an acceptable tradeoff.
The final result is a transition to a slightly more verbose but much more flexible language. Take, for example, this state machine in graphviz:
\digraph[scale=0.5]{nfa_intro}{
margin="0 0 0 0";
rankdir="LR";
node [ shape = circle ] q1 q2 q3;
node [ shape = doublecircle ] q4;
q1 -> q1 [ label = "0,1" ];
q1 -> q2 [ label = "1" ];
q2 -> q3 [ label = "0" ];
q3 -> q4 [ label = "0" ];
}
The equivalent machine in pgf/tikz:
\begin{tikzpicture}[node distance=2cm,auto]
\node[initial,state] (q1) {$q_1$};
\node[state] (q2) [right of=q1] {$q_2$};
\node[state] (q3) [right of=q2] {$q_3$};
\node[accepting,state] (q4) [right of=q3] {$q_4$};
\path[->] (q1) edge [loop above] node {0,1} (q1);
\path[->] (q1) edge node {1} (q2);
\path[->] (q2) edge node {0} (q3);
\path[->] (q3) edge node {0} (q4);
\end{tikzpicture}