集合与逻辑符号

表示“存在”的 ∃ 是把大写 E 旋转半圈得来的,表示“任意”的 ∀ 则是把大写 A 上下颠倒。LaTeX 提供的集合论与逻辑符号——\forall\exists\in\subset\cup\land——并不是设计好的体系,而是这类临时想法碰巧留了下来;这两个翻转字母之间隔着三十八年,出自两位不同的人。本页追踪这些临时想法,只谈今天写文档时仍要付出代价的地方:为什么 ⊂ 在不同读者眼里有两种含义,为什么 \setminus\backslash 印出完全相同的图形却排版不同,以及为什么空集的记号是一个丹麦字母。

\forall\exists:把字母倒过来就成了符号

两个符号都是 LaTeX 标准命令,\forall\exists 都不需要宏包,而且它们真的就是被转过来的活字。朱塞佩·皮亚诺在 1897 年《Formulaire de mathématiques》第二卷中印出了表示“存在”的反写 E——那是他在 1889 年用希腊字母 epsilon 表示属于关系之后的第八年。上下颠倒的 A 出现得晚得多:它首见于格哈德·根岑的《Untersuchungen über das logische Schließen》,载《Mathematische Zeitschrift》第 39 卷(1935 年)第 178 页。也就是说,有三十八年之久,逻辑学只有“存在”的记号而没有“任意”的记号,约束变元就写在括号里,记作 (x)。否定形式 ∄ 更年轻,而且根本不在 LaTeX 内核中:\nexists 属于 amssymb

它们全都住在数学模式里。在正文中写 \forall 不只是难看,而是会以 ! Missing $ inserted. 中断编译,因为数学模式之外根本不存在可以套用的间距规则。而模式之内套用的规则值得知道:fontmath.ltx\forall\exists 声明为 \mathord(普通符号),而不是关系符。因此量词本身不占间距,\forall x\exists y 会挤成一团;讲究的稿件写成 \forall x\, \exists y\, P(x,y),在中间塞入细空白 \,,原因就在这里。

latex
% quantifiers, and a set defined by a condition
\[
  \forall \varepsilon > 0 \;\exists \delta > 0 \;
  \bigl( |x - a| < \delta \implies |f(x) - f(a)| < \varepsilon \bigr)
\]
\[
  A \cup B = \{\, x \mid x \in A \lor x \in B \,\}, \qquad
  A \subseteq B \iff \forall x\,(x \in A \implies x \in B)
\]

\land\wedge\lnot\neg:该敲哪一个

输出没有任何差别,所以哪个名字更能表达意图就敲哪个fontmath.ltx 写的是 \DeclareMathSymbol{\wedge}{\mathbin}{symbols}{"5E},接着为 \land 写了一行完全相同的声明——同类别、同字体、同槽位;\lor/\vee"5F)与 \lnot/\neg"3A)也是如此。六者都不需要 amssymb。已经定型的惯例是:逻辑公式里用逻辑的名字,而在 ∧ 表示的不是逻辑时用几何的名字——微分形式的外积写 \wedge,格的并写 \vee。读者在源文件里看到 \land,立刻知道这里是“且”。好处仅此一条,但只要文件还要给人看,这条好处就是实打实的。

命令字形名称 / 用法
\forall全称量词(对所有);\mathord
\exists存在量词(存在);\mathord
\nexists不存在;需要 amssymb
\neg¬否定;与 \lnot 声明完全相同
\lnot¬否定;逻辑式中这个名字更易读
\land合取(且);\mathbin
\wedge同一字形;用于外积与格的交
\lor析取(或);\mathbin
\vee同一字形;格的并等非逻辑用途
\Rightarrow蕴含;短的双线箭头
\implies蕴含,两侧带粗空白;amsmath
\Leftrightarrow等价;短的双线箭头
\iff等价;内核已定义,无需宏包

\implies\iff 需要单独说明。\iff 在 LaTeX 内核中已定义为 \;\Longleftrightarrow\;——长双线箭头,两侧各有粗空白——因此不需要任何宏包就能用。amsmath 把它重定义为 \DOTSB\;\Longleftrightarrow\;,间距毫无变化,变的是 \dots\DOTSB 标记该命令属于二元运算符或关系符,使紧随其后的 \dots 排成居中的 ⋯,而不是贴在基线上。\implies 则只存在于 amsmath。在同一份文档里,短的 \Rightarrow 与长的 \implies 只选一个并贯彻到底;在证明中途换用,读者会以为这两个箭头含义不同。

\in\notin\ni:属于关系与 \epsilon 的陷阱

属于符号 ∈ 最初就是希腊字母 epsilon:皮亚诺在 1889 年用 ε 作为拉丁语 est(“是”)的缩写。这段来历,以及它的后果——x \epsilon A 会顺利编译,却因为 \epsilon\mathord\in\mathrel,印出一个间距被挤掉的公式——在本参考的希腊字母页中有详细叙述。同一张声明表还能读出另外两件事。第一,\notin 并不是一个字符:fontmath.ltx 把它构造为 \mathrel{...\c@ncel\in},在 \in 上叠印一道小斜线,所以斜线的位置是算出来的,而不是从字体里取来的,写成 \not\in 也落在完全相同的宽度上。第二,∋(\ni,“以……为元素”)另有一个声明到同一槽位的名字 \owns——在句子里 A \owns xA \ni x 读起来更顺,而且不花任何代价。

\subset\subseteq 的区别:⊂ 有两种读法

要表示“子集,可以相等”就写 \subseteq;要表示“严格更小”就写 \subsetneq。避开 ⊂ 的理由不是它错,而是它有两种读法:在相当大一部分文献中,A \subset B 允许 A = B,只是 ⊆ 的另一种写法;在另一大部分文献中,它断言 A ≠ B。两种读法都已确立,都出现在当今的教科书里,也都不会压倒对方。⊂ 与 ⊃ 这一对符号由恩斯特·施罗德在 1890 年《Vorlesungen über die Algebra der Logik》第一卷中引入,表示“被包含于”和“包含”;严格与否的问题是在此后的用法中分裂开的,至今仍未合拢。

命令字形名称 / 用法
\in属于;\mathrel
\notin不属于;在 \in 上叠印斜线的合成
\ni以……为元素;别名 \owns
\subset包含;有的流派读作真子集,故有歧义
\subseteq子集或等于;没有歧义
\subsetneq真子集;需要 amssymb
\supset⊂ 的反向;带有同样的歧义
\supseteq超集或等于

实务上由此产生两个习惯。第一,文档若要用 ⊂,就在开头处声明一次采用哪种读法——很多书正是这么做的。第二,当严格与否支撑着论证时,就把话说明白:amssymb\subsetneq(⊊)不留任何解释余地。amssymb 还提供 \subsetneqq(下方为双横线)以及 \varsubsetneq\varsubsetneqq,它们只在斜线与横线的画法上不同;除非期刊格式点名要哪一个,\subsetneq 都是稳妥的默认选择。顺带一提,LaTeX 内核里根本没有真子集符号——这本身就透露了这套记法是怎样长成的。

\cup\cap\setminus——错用 \backslash 会怎样

\setminus\backslash 从同一字体的同一槽位取来同一个图形——symbols 字体的 "6E 位。不同的只是它们被声明的类别,而故事到此为止。fontmath.ltx 写的是 \DeclareMathSymbol{\setminus}{\mathbin}{symbols}{"6E},而把 \backslash 声明为 \mathord,源文件里还附了一句注释,说它是“为双陪集 G\backslash H 而设”。在 10pt 下把 A \setminus BA \backslash B 并排量一量,盒子分别是 25.03pt 和 20.59pt:少掉的 4.44pt 正是二元运算符在两侧各取的 4mu 中等空白。不报错,不警告,差距又小到足以躲过校对——这正是值得一次性定下来的原因。集合差用 \setminus\backslash 则留给它本来要服务的双陪集。

同样的陷阱,会以更大一号的尺寸出现在集合的内涵记法里。|\mid 同样是一个字形——槽位 "6A——分别被声明为 \mathord\mathrel\{x \mid x > 0\} 量得 48.10pt,\{x | x > 0\} 为 42.54pt,相差 5.56pt,正是关系符在两侧各取的 5mu 粗空白。内涵记法里的竖线本来就是关系符——它把变量和关于变量的陈述隔开——所以正确选择是 \mid,用 | 会让整个集合黏成一团。若式子较高、括号需要撑大,写成 \left\{\, x \in X \;\middle|\; f(x) = 0 \,\right\},竖线会随括号一起长高;而在 \left\{ ... \right\} 里放一个光秃秃的 \mid,括号撑大了,竖线还是原来的小个子。

latex
% set difference and set-builder: pick the relation-class commands
\[
  A \setminus B = \{\, x \in A \mid x \notin B \,\}
\]
% \middle| grows with \left\{ ... \right\}; a bare \mid does not
\[
  \left\{\, x \in X \;\middle|\; \frac{f(x)}{g(x)} = 0 \,\right\}
\]
命令字形名称 / 用法
\cup并集;\mathbin
\cap交集;\mathbin
\setminus差集;按二元运算符留空
\backslash同一字形,但为 \mathord;用于双陪集 G\H
\mid内涵记法中的竖线;\mathrel
\complement补集,如 A^\complementamssymb

\emptyset\varnothing 的区别:空集是个丹麦字母

∅ 不是希腊字母 phi,也不是划了一道线的零。它是丹麦语和挪威语字母表中的字母 Ø,于 1939 年经由布尔巴基的《Éléments de mathématique》进入数学。安德烈·韦伊后来在回忆录中认领了这件事:他写道,这个符号来自挪威语字母表,而布尔巴基成员中只有他熟悉挪威语。知道了来历,用哪个 LaTeX 命令的争论就有了结论——因为这两个命令画的是同一个字母的两种理解

\emptyset 是内核版本,\varnothing 来自 amssymb,两者形状并不相同。在 10pt 的 Computer Modern 下实测:\emptyset 宽 5.00pt、高 7.50pt,是一个瘦长的竖椭圆被一道线穿过;\varnothing 宽 7.78pt、高 5.82pt,是一个圆形被两端出头的斜线划过。后者更接近手写的 Ø,也更接近多数人听到“空集”时脑中浮现的样子。实务上的结论只有一条:载入 amssymb,全篇统一用 \varnothing,别让 \emptyset 中途溜回来。同一份文档里同一个集合出现两种形状,正是编辑会用红笔圈起来的那类事故。

\vdash\models\top\bot:证明与 turnstile 记号

这四个都是 LaTeX 标准命令,而且谈的都是证明而不是集合。⊢(\vdash)是句法可导出性的 turnstile——Γ ⊢ φ 表示“φ 可从 Γ 导出”——⊨(\models)则是语义后承的双 turnstile,表示“Γ 的任何模型都使 φ 为真”。分清这两者是数理逻辑一半的课题,所以选错并不是排版细节。顺带一提,\models 也不是单个字符:fontmath.ltx 用一条竖线连上一条双横线,写成 \mathrel{|}\joinrel\Relbar 拼出来。⊣(\dashv)是 ⊢ 的镜像,在逻辑之外用来写伴随函子 F ⊣ G。⊤ 和 ⊥ 是真与假两个常元,也是格的最大元与最小元。

这里起作用的同样是类别。\vdash\dashv\models\mathrel,两侧会自带间距;\top\bot\mathord,因为它们通常作为常元单独出现。于是想表达“L 垂直于 M”而写成 L \bot M,排出来就会挤在一起。这个位置该用 \perp,它是把同一个槽位 "3F 重新声明为关系符的结果。实测 L \bot M 为 25.38pt,L \perp M 为 30.93pt——相差的 5.56pt,仍旧是关系符在两侧各取的粗空白。\perp 同样在内核中,不需要宏包。

命令字形名称 / 用法
\vdash可导出(turnstile);\mathrel
\dashv⊢ 的镜像;也用于伴随 F ⊣ G
\models语义后承;竖线加双横线的合成
\top恒真 / 最大元;\mathord
\bot恒假 / 最小元;\mathord
\perp同一字形的关系符;“垂直”用这个
\therefore因此;声明为关系符;amssymb
\because因为;声明为关系符;amssymb

哪些命令需要 amssymb?(以及 ∴、∵ 该怎么用)

本页真正在 LaTeX 内核之外的,恰好是六个命令:\nexists\varnothing\subsetneq\complement\therefore\because。六者都来自 amssymb;导言区若没有 \usepackage{amssymb},每一个都会以 ! Undefined control sequence. 中断编译。第七个外来者是 \implies,它属于 amsmath 而非 amssymb。由于 amssymb 会自动载入 amsfonts,而带公式的文档一般也需要 amsmath,所以导言区两行就足以覆盖本页的全部内容。

document.tex
\usepackage{amsmath}  % \implies, \impliedby, \iff with \DOTSB
\usepackage{amssymb}  % \nexists \varnothing \subsetneq \complement \therefore \because

% \therefore is a relation: it already carries space on both sides
\[
  x^2 = 4 \quad \therefore x = \pm 2
\]

最后清理一个流传甚广的说法。常有人说 ∴ 和 ∵ 前后必须手工加空白,于是写成 \therefore\ 之类。并不需要。 amssymb 把两者都声明为 \mathrel,所以写下 x \therefore y 时两侧就已经带上了关系符的粗空白;再加一个 \ ,只会把空白加倍。真正值得留意的是该不该用:这两个记号属于黑板,多过属于印刷页面。在成稿的散文里,写成“因此”“因为”几乎总是更好读,∴ 最好留给真正挤不下的地方,比如公式内部。

  • 空集统一用 \varnothingamssymb),不要混入 \emptyset
  • 包含用 \subseteq,真包含用 \subsetneq;避免有歧义的 \subset,或在开头声明其含义
  • 集合差用 \setminus\backslash 留给双陪集
  • 内涵记法的竖线用 \mid,需要撑大时用 \middle|,不要用光秃秃的 |
  • 逻辑式里用 \land\lor\lnot;外积与格用 \wedge\vee
  • 蕴含只选短的 \Rightarrow 或长的 \implies 之一,并贯彻到底