我有一个包含各种编号对象的文档,例如带有编号功能符号的术语重写系统,如下所示:
虽然我需要这些符号的编号输出(它应该说明自动分析的输出 - 事实上变量最终也会被编号),但在我的例子中,它们对应于一些语义对象。因此对于图中的系统,我将使用如下代码:
\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
,那么我需要将命令更改\processstate
为f_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}