从数学量词说起

本学渣最近在补数学。之前已经发现,看懂符号对数学学习有多重要,现在又意识到,理解数学语言这件事也绕不过去。

比如,一个式子里的符号都认识,未必就知道整个式子在说什么。这有点像背单词,单词挨个查过了,句子还是读不通。数学也有这样的情况,只不过它的句子可能长得不像句子。

这次让我注意到这个问题的,是微积分里的定义。定义到底要不要背,我觉得是要的,但是背之前,至少得弄清楚它说了什么。否则把“对任意……存在……”背得滚瓜烂熟,换个地方再看到,还是不知道该怎么办。

任意和存在

学极限时,会遇到所谓的 \(\varepsilon\)-\(\delta\) 语言。比如,函数在 \(x\) 趋近于 \(x_0\) 时,以 \(A\) 为极限,定义里会说:

对任意 \(\varepsilon>0\),存在 \(\delta>0\),使得对定义域内的所有 \(x\),只要 \(0<|x-x_0|<\delta\),就有 \(|f(x)-A|<\varepsilon\)。

这句话有点长,可以先读成:你提出一个误差要求,我给出一个距离限制,保证自变量足够接近时,函数值满足你的误差要求。这里的 \(\varepsilon\) 表示误差要求,\(\delta\) 表示距离限制。

写程序判断浮点数是否相等时,常用 epsilon 表示允许的误差(浮点数有舍入误差,直接判等容易出问题),和这里的 \(\varepsilon\) 意思相近。delta 则常表示差值或变化量,比如 deltaTime;这里的 \(\delta\) 具体表示距离限制。

但只说“一个”还不够。是挑一个容易满足的误差要求就行,还是要求无论误差多小,都能给出这样的保证?定义说的是后者。所以开头才要写“对任意 \(\varepsilon>0\),存在 \(\delta>0\)”:无论提出怎样的正误差要求,都能找到相应的距离限制。

这样看,定义里的不等式说明误差和距离怎么算,“任意”和“存在”则说明这个保证要做到什么程度。它们也有专门的符号,分别是 \(\forall\) 和 \(\exists\),于是定义的开头可以写成 \(\forall\varepsilon>0\,\exists\delta>0\)。这两个词平时也用,似乎没什么特别,但在数学里,它们有明确的名字,叫量词。

这里的量词,和语文课上“一本书”“三只猫”里的“本”“只”不是一回事。数学量词更接近日常说的“所有”“至少有一个”。

“任意”要求讨论范围里的每个对象都满足条件,不能遗漏。“存在”则只要求至少有一个,也没有说只能有一个。

这样看,两个符号本身倒是不难。难的是,它们放在一起之后,顺序也有意义。

每个人喜欢的书

“每个人都有一本喜欢的书”和“有一本书,所有人都喜欢”,显然是两回事。

前一句里,你可以喜欢小说,我可以喜欢数学书,大家各有各的。后一句就麻烦了,要找到一本大家都喜欢的书。

为了把这件事写成数学表达式,先约定 \(x\) 表示我们讨论的人,\(y\) 表示我们讨论的书,再用 \(P(x,y)\) 表示“人 \(x\) 喜欢书 \(y\)”。

第一句话就可以写成:

$$ \forall x\,\exists y\,P(x,y) $$

第二句话则是:

$$ \exists y\,\forall x\,P(x,y) $$

看起来只是换了两个符号的位置,要求却变了。

第一种写法,先任意选一个人,再为这个人找一本喜欢的书。选出来的书,可以随着人的不同而变化。

第二种写法,先找一本书,再检查是不是所有人都喜欢它。书已经选定了,不能看到有人不喜欢,就临时换成另一本。

所以,量词顺序还规定了一件事:后面的选择,取决于前面给定的哪些对象。这个区别,在日常说话时可能靠语境就过去了,数学里却需要写清楚。

这个 P 是函数么

看到 \(P(x,y)\),我又有一个疑问:它长得和函数差不多,是函数么?

这里一般把它叫作“谓词”。这个名字有点陌生,但放到刚才的例子里,就是一个真假取决于 \(x\) 和 \(y\) 的判断。

“人 \(x\) 喜欢书 \(y\)”,在人和书还没有指定的时候,我们不知道它是真是假。换成具体的人和书,就成了一个可以判断真假的命题。

也可以把谓词理解成返回真假的函数:

$$ P:\text{人集合}\times\text{书集合}\to\{\text{真},\text{假}\} $$

这里的 \(\times\) 表示笛卡尔积,也就是把一个人和一本书配成一对;箭头表示把这对对象映射到真或假。这样一说,对程序员而言就容易理解了,有点像一个返回布尔值的函数。

当然,数学里把它写出来,并不意味着我们就有一个程序,能自动判断所有人到底喜欢哪本书。它首先是在表达一个条件。

谓词负责说“满足什么条件”,量词负责说“哪些对象要满足这个条件”。两者组合起来,就能把前面那两句话的区别写清楚。

回头再看极限

有了这个例子,再看“对任意 \(\varepsilon>0\),存在 \(\delta>0\)”,就好理解一些。

\(\varepsilon\) 是对函数值误差的要求,\(\delta\) 是对自变量距离的限制。先提出误差要求,再根据这个要求,找到合适的距离限制。

以 \(f(x)=2x\) 为例,当 \(x\) 趋近于 \(1\) 时,函数值趋近于 \(2\)。因为:

$$ |2x-2|=2|x-1| $$

所以,无论给出多小的 \(\varepsilon>0\),取 \(\delta=\varepsilon/2\) 就行。只要 \(0<|x-1|<\delta\),就能保证 \(|2x-2|<\varepsilon\)。

这里的 \(\delta\) 可以随着 \(\varepsilon\) 变化。误差要求越严格,距离限制也可以越严格。但 \(\delta\) 选定之后,范围内的所有 \(x\) 都必须满足要求,不能只挑一个表现不错的 \(x\) 交差。

原来,“无限接近”可以这样表达:无论你把误差标准定得多严格,我都能给出一个范围,保证范围内的函数值满足要求。

连续和一致连续,也有类似的区别。函数在一个集合上连续,允许针对不同的点,分别找合适的 \(\delta\);一致连续则要求,给定 \(\varepsilon\) 之后,能找到一个 \(\delta\),对集合内的任意两点都管用。

一个允许距离限制随位置变化,一个要求整个集合共用同一个距离限制。看名字只多了“一致”两个字,实际要求却强了不少。

这样的语言有什么用

到这里,我多少理解了,为什么数学要把普通的话写得这么严格。

首先,它能把直觉变成可以检验的定义。“越来越接近”容易产生印象,但印象不够明确。写成量词和条件之后,才知道到底要满足什么。

然后,它还告诉我们证明该怎么做。要证明所有对象都满足一个条件,就不能只检查几个例子;要证明至少存在一个,就可以找一个满足条件的对象,或者证明它必然存在。

反过来,要推翻“所有对象都满足”,找到一个反例就够了。比如“所有素数都是奇数”,一个 \(2\) 就能把它推翻,不需要把其他素数都查一遍。

连否定一句话,也得看量词。“并非所有人都喜欢这本书”,只说明至少有一个人不喜欢;“没有人喜欢这本书”,才说明所有人都不喜欢。这两句话不能混用。

这样的区分,也不只用于数学。比如,“每个用户都有权限访问至少一台服务器”,并不要求所有用户都有权限访问同一台。如果要说这个要求没有满足,那就是“存在一个用户,他没有权限访问任何服务器”。描述程序的条件、检查需求的时候,也会遇到这些问题。

我以前看定义,容易把注意力全放在运算符和不等式上。现在发现,还得留意谁先给定、谁后选择,以及一个条件到底要对多少对象成立。不然计算部分看懂了,整句话还是可能读错意思。

还有哪些数学语言

量词和谓词属于逻辑语言。再往外看,还有集合语言,用 \(x\in A\) 表达归属,用 \(A\subseteq B\) 表达包含;函数语言,用 \(f:X\to Y\) 表达对应关系;以及代数、几何、概率等领域常见的表达方式。

还有递归这样的定义方式,用已经定义的对象继续定义后面的对象。比如 \(a_0=1\),\(a_{n+1}=2a_n\),就是从 \(1\) 开始,每次翻倍。

这些说法也不是互相隔开的。一句 \(\forall x\in\mathbb R,\ f(x)\geq0\),就同时用到了量词、集合、函数和不等式。

这些东西,后面学到哪里就继续研究到哪里。接下来再遇到定义,可以先问一句:这句话到底在要求什么? 至于背下来,等读通了再背,应该会容易一点。