根据定义点的计数器创建宏

根据定义点的计数器创建宏

我有一个包含各种编号对象的文档,例如带有编号功能符号的术语重写系统,如下所示:

在此处输入图片描述

虽然我需要这些符号的编号输出(它应该说明自动分析的输出 - 事实上变量最终也会被编号),但在我的例子中,它们对应于一些语义对象。因此对于图中的系统,我将使用如下代码:

\documentclass{article}

\newcommand{\initstate}{f_1}
\newcommand{\processstate}{f_2}

\begin{document}

\[\initstate(x,y,z) \to \processstate(x,z)\]

\[\initstate(0,0,z) \to z\]

\[\processstate(s(x),y) \to \initstate(x,x,y)\]

\end{document}

现在的问题是,每当我想用一个不是最后一个的新符号来扩展这样的系统时(或者如果想重新排序数字),我需要手动更改所有命令(例如,如果我添加另一个符号并使用\storestate符号的命令f_2,那么我需要将命令更改\processstatef_3)。因此示例将如下所示:

\documentclass{article}

\newcommand{\initstate}{f_1}
\newcommand{\storestate}{f_2}
\newcommand{\processstate}{f_3}

\begin{document}

\[\initstate(x,y,0) \to \storestate(x,y)\]

\[\initstate(x,y,z) \to \processstate(x,z)\]

\[\initstate(0,0,z) \to z\]

\[\storestate(x,y) \to \processstate(y,x)\]

\[\processstate(s(x),y) \to \initstate(x,x,y)\]

\end{document}

我希望命令中的数字是根据命令定义的顺序插入的(而不是在命令中明确指定)。因此,如果我切换和的定义顺序\initstate\processstate它们对应的符号也应该切换它们的数字。同样,如果我在两个现有命令定义之间添加另一个命令定义,则所有命令中的数字都应自动更新。以这种方式“分配”给命令的数字在使用新命令期间不应再更改。所以最后,这两个示例的代码应该如下所示(并产生相同的输出):

\documentclass{article}

\newcounter{funcsyms}
\setcounter{funcsyms}{1}
\numberedcommand{\initstate}{f_}{funcsyms}{}
\numberedcommand{\processstate}{f_}{funcsyms}{}

\begin{document}

\[\initstate(x,y,z) \to \processstate(x,z)\]

\[\initstate(0,0,z) \to z\]

\[\processstate(s(x),y) \to \initstate(x,x,y)\]

\end{document}

第二个例子:

\documentclass{article}

\newcounter{funcsyms}
\setcounter{funcsyms}{1}
\numberedcommand{\initstate}{f_}{funcsyms}{}
\numberedcommand{\storestate}{f_}{funcsyms}{}
\numberedcommand{\processstate}{f_}{funcsyms}{}

\begin{document}

\[\initstate(x,y,0) \to \storestate(x,y)\]

\[\initstate(x,y,z) \to \processstate(x,z)\]

\[\initstate(0,0,z) \to z\]

\[\storestate(x,y) \to \processstate(y,x)\]

\[\processstate(s(x),y) \to \initstate(x,x,y)\]

\end{document}

因此,我想指定 4 项内容:新命令的名称、数字前的定义、用于数字的计数器以及数字后的定义。数字基本上应该是相应命令定义的位置,即,如果我\initstate首先定义该命令,则其数字应该是 1。如果将此命令定义为第二个命令,则其数字应该是 2,依此类推。

如果我像这样改变上一个例子中命令定义的顺序:

\documentclass{article}

\newcounter{funcsyms}
\setcounter{funcsyms}{1}
\numberedcommand{\storestate}{f_}{funcsyms}{}
\numberedcommand{\processstate}{f_}{funcsyms}{}
\numberedcommand{\initstate}{f_}{funcsyms}{}

\begin{document}

\[\initstate(x,y,0) \to \storestate(x,y)\]

\[\initstate(x,y,z) \to \processstate(x,z)\]

\[\initstate(0,0,z) \to z\]

\[\storestate(x,y) \to \processstate(y,x)\]

\[\processstate(s(x),y) \to \initstate(x,x,y)\]

\end{document}

输出应为:

在此处输入图片描述

如果我只是在这样的代码中引用一个计数器\numberedcommand并增加它,那么在使用新命令的几个地方,我将得到不同的数字。所以这并不能解决问题。如果我在定义之间增加计数器,那么所有符号都会得到相同的数字。我如何定义根据其定义点自动编号的宏(即如何\numberedcommand在上面的示例中定义)?

答案1

在我看来,将\numberedcommand两个调用合并为一个调用并提供宏名\initstate和`\processstate作为参数更容易。

无论如何,\number\value{foo}将评估计数器值并将其用作索引。\the\numexpr\value{foo}+1将使用下一个整数值而不真正增加计数器。

\documentclass{article}

\newcounter{funcsyms}
\setcounter{funcsyms}{0}

\providecommand{\initstate}{f_}
\providecommand{\processstate}{f_}

\newcommand{\numberedcommand}[4]{%
  \renewcommand{#1}{#2{\number\value{#3}}}%
  \renewcommand{#4}{#2{\the\numexpr\value{#3}+1}}%
  \stepcounter{#3}
 }

\numberedcommand{\initstate}{f_}{funcsyms}{\processstate}

\begin{document}

\[\initstate(x,y,z) \to \processstate(x,z)\]

\[\initstate(0,0,z) \to z\]

\[\processstate(s(x),y) \to \initstate(x,x,y)\]


\numberedcommand{\initstate}{f_}{funcsyms}{}{\processstate}


\[\initstate(x,y,z) \to \processstate(x,z)\]

\[\initstate(0,0,z) \to z\]

\[\processstate(s(x),y) \to \initstate(x,x,y)\]


\end{document}

在此处输入图片描述

更新

编辑与\xdef(虽然有点不尽人意)

\documentclass{article}

\newcounter{funcsyms}
\setcounter{funcsyms}{0}

\providecommand{\initstate}{f_}
\providecommand{\processstate}{f_}
\providecommand{\storestate}{f_}

\newcommand{\numberedcommand}[4]{%
  \stepcounter{#3}%
  \xdef#1{#2{\number\value{#3}}#4}
}

\numberedcommand{\storestate}{f_}{funcsyms}{}
\numberedcommand{\processstate}{f_}{funcsyms}{}
\numberedcommand{\initstate}{f_}{funcsyms}{}

\begin{document}



\[\initstate(x,y,0) \to \storestate(x,y)\]

\[\initstate(x,y,z) \to \processstate(x,z)\]

\[\initstate(0,0,z) \to z\]

\[\storestate(x,y) \to \processstate(y,x)\]

\[\processstate(s(x),y) \to \initstate(x,x,y)\]


\end{document}

相关内容