为什么使用 \DeclareMathOperator 制作的运算符和花括号不会产生问题?

为什么使用 \DeclareMathOperator 制作的运算符和花括号不会产生问题?

以下代码可以正确编译并生成 pdf:

\documentclass{article}
\usepackage{amsmath}

\DeclareMathOperator{\zero}{\overline{0}}

\begin{document}

Writing $V_\alpha$ does not give problems.

\end{document}

但是,以下代码确实存在问题:

\documentclass{article}
\usepackage{amsmath}

\DeclareMathOperator{\zero}{\overline{0}}

\begin{document}

Writing $V_\zero$ gives problems.

\end{document}

这是为什么?有没有什么办法可以让它\zero像这样工作\alpha

答案1

在里面电子书,第 128 页,其中写道:请注意 ^ 和 _ 仅适用于下一个单个字符

因此, 的V_\alpha作品可能应该被视为例外。请注意 的标准定义\alpha\mathchar"010B

使用在原始 TeX 中定义的宏\def,它不起作用(至少,它并不总是起作用),因为使用\def\zero{},您无法写入V_\zero

还要注意的是,TeX 不会将 后面的内容^视为_宏的参数。字符^_非常特殊(就像 或 一样特殊)。 的 catcode是 7, 的 catcode是 8(而例如 的 catcode是 1,{等等)。这意味着您不应该期望和具有宏的行为(即使是 catcode 为 13 的字符,其行为也像宏一样)。#^_{^{

许多人可能会建议写作V_{\alpha}(因为他们建议写作\frac{1}{2}而不是\frac12- 这有效......)。

答案2

尽管说 TeX 将后面的内容^_参数视为宏是“几乎正确的”,但它实际上跳过了关于它们的一个基本事实。

这就是你的 出现问题的地方V_\zero

宏参数的根本区别在于,当你有一个宏接受一个参数(准确地说是一个无界参数)时,比如说\foo,那么 TeX 会在其中寻找该参数无需做任何扩展:如果后面跟着一个开括号,那么直到匹配的闭括号为止的所有内容将被视为参数;否则下一个标记将被视为参数。

相反,看到^_,TeX将要扩展标记以查看后面是否有左括号(可能是隐式的);在此过程中,\relax空格标记将被忽略。一旦\relax发现不可扩展的标记(或空格除外),这种扩展过程就会终止;如果它是左括号,则参数将被抓取到匹配的右括号(也可能是隐式的)。

因此你可以这样做

V_\bgroup 10\egroup

这将10作为下标。请注意,如果\foo是带参数的宏,\foo\bgroup 10\egroup则将\bgroup作为参数(可能产生不良副作用)。

您可以使用简单的纯 TeX 代码进行测试。

\def\foo#1{(#1)}
\def\x{\bgroup}
\def\void{}

\foo{10}

\foo\bgroup 10\egroup

$V_{10} = V_\bgroup 10\egroup=V_\x 10}$

$V_\void x$

\bye

在此处输入图片描述

使用\foo\bgroup 10\egroup,令牌\bgroup被视为参数,因此输入流将变为

(\bgroup)10\egroup

(第二行)。第三行显示所有这些(奇怪的)输入都会导致相同的结果。

第四行显示\void已扩展;扩展为空,因此 TeX 继续寻找不可扩展的标记(使用宏扩展);它找到了x,因此它将其作为下标。

为什么V_\alpha有效?因为\alpha是不可扩展的令牌。它是不是定义为

\def\alpha{\mathchar"010B }

\mathchardef\alpha="010B

非常\alpha不同。因此,当扫描到时,对不可扩展标记的查找结束。

如果你要求 LaTeX 显示你的\zero实际上是如何定义的\show\zero,你会看到

> \zero=macro:
->\protect \zero  .

(最后一个命令的名称中有一个空格,但这并不重要)。上面解释的规则导致\zero扩展为\protect\zero•(项目符号表示名称中的空格)。由于\protect相当于\relax,因此在这种情况下,它会被忽略,因此 TeX 会扩展\zero•

如果你这样做,\ShowCommand\zero你就会得到

> \zero=robust macro:
->\protect \zero  .

> \zero =\long macro:
->\qopname \newmcodes@ o{\overline {0}}.

因此输入流中剩余的第一个标记是\qopname。现在\ShowCommand\qopname产生

> \qopname=robust macro:
->\protect \qopname  .

> \qopname =\long macro:
#1#2#3->\mathop {#1\kern \z@ \operator@font #3}\csname n#2limits@\endcsname .

情况类似:\protect被忽略并且\qopname•被扩展;现在出现错误,因为\mathop是不可扩展的,所以它被视为整个下标,但这样做是非法的

V_\mathop

原因很容易理解。

结论:可以这样V_\alphaV_1类的,但不确定时请避免省略括号。更好的方法是总是括号下标和上标。

相关内容