在 alignat 中使用 \qedhere 时出现问题

在 alignat 中使用 \qedhere 时出现问题

Barbara Beeton 建议这里,我将此作为新问题发布。

当证明以显示的公式结束时,为了将 QED 符号放在正确的位置,您必须\qedhere在公式内使用。

问题是,如果通过环境给出公式alignat*,那么 LaTeX 在编译时会发出(无害的)警告。

以下是 MWE:

\documentclass{article}
\usepackage{amsmath}
\usepackage{amsthm}
\begin{document}
\begin{proof}
 \begin{alignat*}{2}
  &x && =1 \\
  &y && =2 
  \qedhere
 \end{alignat*}
\end{proof}
\begin{proof}
 \begin{align*}
  x & =1 \\
  y & =2 
  \qedhere
 \end{align*}
\end{document}

请注意,amsmath在之前调用amsthm,如在中指定amsthdoc

编译时,我收到(双重)警告

Package amsthm Warning: The \qedhere command may not work correctly here on input line 10.

Package amsthm Warning: The \qedhere command may not work correctly here on input line 10.

QED 符号仍然在那里(尽管没有向右对齐)。

另一方面,如果您使用环境align*而不是,那么一切都会顺利进行。alignat*

正如芭芭拉所说,它们应该发挥同样的作用,但看起来却并非如此。

PS:避免出现警告的一种方法是使用\tag*{\qedhere}而不是\qedhere,这也有副作用,即将 QED 符号刷新到右侧,将其恢复到其预期位置,但这看起来更像是一种变通方法,而不是 的预期用途\qedhere

答案1

以下解决方案适用于带有或不带有 的两个文档leqno

\documentclass{article}
\usepackage{amsmath}
\usepackage{amsthm}

\makeatletter
\def\qed@tag@alignat{%
    \global\tag@true \nonumber
    &\omit\setboxz@h {\strut@ \qedsymbol}%
    \iftagsleft@%
        \global\advance\tagshift@-\displaywidth%
    \fi%
    \tagsleft@false
    \place@tag
    \kern-\tabskip
    \ifst@rred \else \global\@eqnswtrue \fi \global\advance\row@\@ne \cr
  }

\def\alignat@qed{%
    \ifmeasuring@ \tag*{\qedsymbol}%
    \else \let\math@cr@@@\qed@tag@alignat
    \fi
  }
  \@xp\let\csname alignat*@qed\endcsname\alignat@qed
\makeatother

\begin{document}
\begin{proof}
 \begin{alignat*}{2}
  &x && =1 \\
  &y && =2 
  \qedhere
\end{alignat*}
\end{proof}
\begin{proof}
 \begin{align*}
  x & =1 \\
  y & =2 
  \qedhere
 \end{align*}
 \end{proof}
\end{document}

解释

align大部分代码都是直接从环境中使用的代码复制而来amsthm.sty,关键的区别是我们定义了一个新的\qed@tag@alignat宏。

amsthm.sty宏中\qed@tag定义,它适用于gatheralign环境;但事实上它适用于align主要是黑客行为。关于为什么需要黑客行为的一个简短且略微不准确的描述是:

理想情况下,我们希望像 这样的方法\tag*{\qedsymbol}能够奏效。如果世界上没有leqno文档,那么上面的形式就可以了。但是如果你有一个左编号的等式,那么它会打印在错误的一侧。所以我们必须做一些更聪明的事情,即使涉及到,也\tag*{\qedsymbol}要把 推到右边。\qedsymbolleqno

通常,标签的位置在gatheralign环境之间以不同的方式计算(它们有自己的\place@tag@gather\place@tag宏)。在\qed@taghack 中,它被(滥用)用于允许\place@tag@gather在环境上下文中工作;我还没有完全弄清楚这个机制,但它与右对齐列的工作align方式以及在列组之间插入的间距有关\llapalign。无论它是什么没有与...合作alignat

在上面的代码中,我们尝试以不同的方式解决 的问题。从根本上讲,导致使用 出现问题leqno的原因是,在排版过程中,由 确定的标签位置是在方程排版的“测量阶段”计算的(众所周知, 使用了两遍方法来设置方程)。在此阶段,代码不知道会有一个应该放在右侧。差异( 是否有效)归结为 的长度。因此,在上面的代码中,我们调用(旨在与 一起使用),但如果有必要,我们会纠正缺失。这允许在左侧和右侧编号的 中正确放置。leqno\place@tag\tagshift@amsmath\qedsymbolleqno\displaywidth\place@tagalignat\displaywidthalignat

(原则上,这也应该适用于align;但这不适用于gather。因此,人们可能会设想进行修补amsthm.sty,以便\qedhere使用上述代码对align和进行调用alignat,但保留 的原始代码gather

相关内容