图灵机的排版图

图灵机的排版图

我必须排版很多看起来像这样的自动机图表。

图灵机图表示例

因此,我花了很多精力引入基于 TikZ 的简化语法。我从这里得到了很多帮助,解决了一些细节问题。现在我可以分享整体实现。

 \documentclass[fontsize=11pt, paper=a4, DIV=9]{scrartcl}

 \usepackage[utf8]{inputenc}
 \usepackage[T1]{fontenc}

 \usepackage{lmodern}
 \usepackage{amsmath}
 \usepackage{amssymb}
 \usepackage{relsize}
 \usepackage{xparse}
 \usepackage{tikz}

 \makeatletter

 % character used in a formal language
 % \Char{}  expands to the empty word
 % \Char{~} expands to the blank character of a Turing machine
 % \Char{#} expands to the bottom-of-stack character of a pushdown automaton
 \ExplSyntaxOn
 \NewDocumentCommand{\Char}{>{\TrimSpaces}m}
 {
   \str_case_x:nnF{\tl_to_str:n{#1}}
   {
     {    }           {\mbox{$\varepsilon$}}
     { ## }           {\mbox{\texttt{\#}}}
     { \c_tilde_str } {\mbox{\textscale{.87}{$\Box$}}}
   }
   {\mbox{\texttt{#1}}}
 }
 \ExplSyntaxOff

 % state of an automaton
 \newcommand{\State}[1]{#1}

 % graph of a Turing machine
 \newenvironment{GraphTM}[1][]{\begin{scope}[#1]}{\end{scope}}

 % state in a graph of a Turing machine
 % #1 = identifier 
 % #2 = state label
 % #3 = "initial" and/or "accepting" (separated by comma)
 % #4 = position in the format "(<x>, <y>)"
 \NewDocumentCommand{\StateTM}{ r() m O{} r() }{%
   \node [state, #3] at (#4) (#1) {$\State{#2}$};}

 % transition in a graph of a Turing machine
 % #1 = identifier of the current state
 % #2 = edge modifier using TikZ syntax
 % #3 = identifier of the subsequent state
 % #4 = position of the edge label using TikZ syntax
 % #5 = edge label
 \NewDocumentCommand{\TransTM}{ r() O{} r() O{} m  }{%
   \path [trans] (#1) edge [#2] node [#4] {\IT@TM@Edge@Label{#5}} (#3);}

 % internal commands used by \TransTM
 \newcommand{\IT@TM@Trans}[3]{%
   \makebox[.6em]{\Char{#1}};\;\makebox[.6em]{\Char{#2}},\,\Char{#3}}
 \NewDocumentCommand{\IT@TM@Edge@Item}{>{\SplitArgument{2}{,}}m}{%
   \IT@TM@Edge@Delim\IT@TM@Trans#1}
 \NewDocumentCommand{\IT@TM@Edge@Label}{>{\SplitList{|}}m}{%
   \def\IT@TM@Edge@Delim{\gdef\IT@TM@Edge@Delim{\\}}
   \shortstack{\ProcessList{#1}{\IT@TM@Edge@Item}}}

 \makeatother

 \usetikzlibrary{automata}

 \tikzset{>=stealth, semithick}
 \tikzset{initial text=}
 \tikzset{state/.style={font=\small, minimum size=0pt, circle, draw}}
 \tikzset{trans/.style={font=\footnotesize, ->}}

 \begin{document}

 \begin{tikzpicture}
 \begin{GraphTM}
 % States
 \StateTM (z0) {z_0} [initial]   ( 0, 0)
 \StateTM (z1) {z_1}             ( 3, 0)
 \StateTM (z2) {z_2}             ( 6, 0)
 \StateTM (z3) {z_3}             ( 9, 0)
 \StateTM (z4) {z_4}             (-2, 3)
 \StateTM (z5) {z_5} [accepting] ( 2, 3)
 % Transitions
 \TransTM (z0)                (z1) [above]    {a, x, R}         
 \TransTM (z0)                (z4) [left=3pt] {y, y, R}          
 \TransTM (z0)                (z5) [left=3pt] {~, ~, N}
 \TransTM (z1) [loop above]   (z1) [above]    {a, a, R | y, y, R}
 \TransTM (z1)                (z2) [above]    {b, y, R}
 \TransTM (z2) [loop above]   (z2) [above]    {b, b, R | z, z, R}
 \TransTM (z2)                (z3) [above]    {c, z, L}
 \TransTM (z3) [loop above]   (z3) [above]    {a, a, L | b, b, L | y, y, L | z, z, L}
 \TransTM (z3) [bend left=23] (z0) [below]    {x, x, R}
 \TransTM (z4) [loop above]   (z4) [above]    {y, y, R | z, z, R}
 \TransTM (z4)                (z5) [above]    {~, ~, N}
 \end{GraphTM}
 \end{tikzpicture}

 \end{document}

\makeatletter和之间的所有内容\makeatother都是我正在编写的包的一部分。

有一些命令和环境(例如\State{}GraphTM)目前什么都不做。它们用于以后对布局的修改。

我暂时没有使用相对定位[right = ... of ...]。此功能以后可以根据需要实现。

你觉得这个实现怎么样?我是不是做了一些奇怪的事情,可能会导致我不知道的问题?

相关内容