为什么添加 \usepackage{breqn},即使没有使用,也会导致 LaTeX 在某些地方编译错误?

为什么添加 \usepackage{breqn},即使没有使用,也会导致 LaTeX 在某些地方编译错误?

我有许多 LaTeX 文件,其中包括一个带有前导代码的通用 .tex 文件。

在此包含文件中,我在最后添加了以下内容

\usepackage{breqn}

然后运行 ​​make 来构建整个树。我现在看到以前编译正常的文件中出现了新的错误。

其中一个例子是问题

下面是另一个示例。LaTeX 代码由 SWP 自动生成。

\documentclass[]{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
%\usepackage{breqn}  %uncomment this to see the error
\begin{document}
\[
\left(  X\circledast Y\right)  \circledast W={\displaystyle\sum\limits_{l=-\infty}^{\infty}}\left(  \overset{\left(  X\circledast Y\right)  \left(  l\right)}{\overbrace{{\displaystyle\sum\limits_{k=-\infty}^{\infty}}X\left(  k\right)  Y\left(  l-k\right)  }}\right)  W\left(  n-l\right)
\]
\end{document}

在此处输入图片描述

\usepackage{breqn}取消上面的注释,会出现错误

>pdflatex foo.tex 
This is pdfTeX, Version 3.1415926-2.4-1.40.13 (TeX Live 2012/Debian)
 restricted \write18 enabled.

(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd)
! Limit controls must follow a math operator.
<argument> {\displaystyle \sum \limits 
                                       _{k=-\infty }^{\infty }}X\left ( k\ri...
l.8 ...}X\left(  k\right)  Y\left(  l-k\right)  }}
                                                  \right)  W\left(  n-l\right)
? 

我只是想了解什么可以帮助解决这个问题。我看到了上面的错误消息,但如果 LaTeX 代码无效,那么在添加 breqn 之前它怎么可能编译成功?为什么添加会breqn导致一些之前不存在的地方出现编译错误?

使用 TexLive 2012 debian 原始软件包。在我的 Linux 机器上没有对其进行任何更改/添加。

答案1

breqn包改变了(以及几乎所有其他数学模式命令)的定义\sum。它使用的定义是(使用的输出\show

> \sum=\protected\long macro:
->\@sym \sum \math_sym_COs:Nn \mg@cop {50}.

该宏\@sym与 相同\@gobble,至少在\[和之间\],因此前两个标记消失。现在 TeX 发现\math_sym_COs:Nn

> \math_sym_COs:Nn=\long macro:
->\math_bsym_COs:Nn .

嗯。我们看看吧\math_bsym_COs:Nn

> \math_bsym_COs:Nn=\long macro:
#1#2->\math_char:NNn 1#1{#2}\sumlimits .

因此标记\mg@cop{50}\math_char:NNn

> \math_char:NNn=\protected\long macro:
#1#2#3->\tex_mathchar:D \__int_eval:w "#1#2#3\__int_eval_end: .

这仅仅产生

\mathchar"1350

因为\mg@cop扩展为3(数学扩展字体系列的编号)。所以产生了符号,但\sumlimits它后面还有

> \sumlimits=\displaylimits.

等一下!这意味着这\sum\limits应该是合法的!

确实如此。但在某些情况\@sym不是相当于\@gobble(这就是它存在的原因)。当\overset处理第二个参数时,\@sym它相当于\binrel@sym

\def\binrel@sym#1#2#3#4{%
  \xdef\binrel@@##1{%
    \ifx\math_sym_Ord:Nn #2 \math_csym_Ord:Nn
    \else\ifx\math_sym_Var:Nn#2 \math_csym_Var:Nn
    \else\ifx\math_sym_COs:Nn#2 \math_csym_COs:Nn
    \else\ifx\math_sym_COi:Nn#2 \math_csym_COi:Nn
    \else\ifx\math_sym_Bin:Nn#2 \math_csym_Bin:Nn
    \else\ifx\math_sym_Rel:Nn#2 \math_csym_Rel:Nn
    \else\ifx\math_sym_Pun:Nn#2 \math_csym_Pun:Nn
    \else\exp_not:N\@symErr \fi\fi\fi\fi\fi\fi\fi
  ?{\exp_not:N\OrdSymbol{##1}}}%
}

这是错误的原因:\limits出现在没有什么,因为 的工作原理之一\overset是检查其第二个参数,以便在整个构造周围应用正确的间距。这里breqn(更准确地说flexisym.sty)试图变得聪明,并进行与 不同的测试amsmath。失败就在这里:当\@sym重新定义时,它仅使用第二个参数(\sum本身)吸收四个参数。并且\limits独自留在输入流中。

一个显示失败的最小例子是

\documentclass{article}
\usepackage{amsmath}
\usepackage{breqn}  %uncomment this to see the error
\begin{document}
\[
\overset{X}{\sum\limits_0}
\]
\end{document}

做出的(错误)假设flexisym是的第二个参数\overset包含单个标记。

答案2

要将东西放在上面,只需\overbrace使用构造\overbrace{-bottom-}^{-top-},它可以很好地与配合使用breqn

您的构造\overset{-top-}{\overbrace{-bottom-}}滥用了\overset,据我所知,它用于堆叠单个符号或关系。在这里,您将整个公式堆叠在另一个公式之上。解决该错误的一种方法egreg是保存原语\let\orig@limits\limits并重新定义\def\limits{\ifx\@sym\binrel@sym\else \orig@limits \fi},以便仅在正常模式下调用原语。唉!还有第二个错误Limit controls must follow a math operator。没有什么可以如此轻松地拯救我们,因为这次\sum实际上并没有排版为运算符。为什么?好吧,breqn试图找出您要用 堆叠的符号\overset。事实证明,底部数学列表中的最后一个原子是一个普通符号,因此breqn将整个底部的东西视为一个普通符号:其中的所有内容都被视为普通符号(\mathord)。特别是\sum变成\mathord{\sum},并且不接受\limits控件。

有效的文件:

\documentclass[]{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{breqn}
\begin{document}
\[
\left(  X\circledast Y\right)  \circledast W
={\displaystyle
\sum\limits_{l=-\infty}^{\infty}} \left(
\overbrace{
  {\displaystyle\sum\limits_{k=-\infty}^{\infty}}X
  \left(  k\right)  Y\left(  l-k\right)
}^{
  \left(  X\circledast Y\right)
  \left(  l\right)}
\right)
W\left(  n-l\right)
\]
\end{document}

存在一些问题,breqn但这不是其中之一。

相关内容