# 证明(Proofs)
- 数学证明(Mathematical proofs)与计算机程序(Computer programs)之间有着非常紧密的联系。
- 具体来说:
- 对于一个程序P,它是否对任意的输入都会中止(有结果)?这个程序能否对任意的输入x,正确计算f(x)?(注意这里x代表的是无穷多的输入)
- 为了确保对无穷多的输入都能正确输出,我们就需要严格的证明(proof)。
# 什么是证明?
- 证明指代的是用一系列有限的推导步骤(称为逻辑推理logical deductions),建立一个我们想得到的命题(结论)的过程。
- 证明的强大之处就在于它可以用有限的手段保证结论适用于无限的情况。
- 具体而言,一个证明是按照以下方式架构的:
- 首先,将一些特定的命题(被称为公理(axioms)或先决假设(postulates)。这些命题是公认的,无需证明)作为证明的起点。
- 然后,进行一系列逻辑推理(基于简单的逻辑规则),这样可以使得在当前命题为真的条件下,后续的命题一定为真。(即一系列的“蕴含”⟹)
- 上面的这种逻辑规则在人类思维中起到了非常重要的作用,同时也是计算机设计的基石。更进一步,这也是人工智能不可或缺的一部分,因为它的目标就是用计算机模仿人类思维。
# 一些数学符号约定及事实
- Z={⋯,−2,−1,0,1,2,⋯}:整数集
- N={0,1,2,⋯}:自然数集
- 注意到,整数集和自然数集在加法与乘法运算上都是封闭的。
- 关于整除:给定整数a和b,如果存在整数q使得b=aq,那么我们称a整除b(a∣b)。
- 我们称自然数p(p≥2)为质数,当且仅当它能被1和自身整除。
- 最后,我们使用:=表示定义。(比如: a:=6657定义了a的值为6657)
# 直接证明(Direct proof)
- 从一个简单的例子开始:
- 对于任意a,b,c∈Z,当a∣b且a∣c,那么a∣(b+c)。
- 注:当我们用P(x,y)代表“x∣y”,那么上述定理可记为(∀a,b,c∈Z)(P(a,b)∧P(b,c))⟹P(a,(b+c))
- 直接证明的过程:
- 确定需要证明的命题:P(x)⟹Q(x)
- 假设P(x)对满足条件的x都成立,再通过一条蕴含链(chain of implications)得到命题Q(x)成立的结论。
- 具体来说,对于上面这个例子:
- 假设a∣b且a∣c,那么存在q1,q2∈Z使得b=q1a,c=q2a
- 然后有b+c=(q1+q2)a,又因为整数集加法封闭,有q1+q2∈Z
- 于是得到a∣(b+c),正是我们想要得到的结论。
- 那么在证明中,a,b,c的“∀”性如何体现呢?实际上,在证明过程中,a,b,c都没有被赋予特定的值,所以它们自然就是任意的!
- 有时,我们想要证明P(x)⟺Q(x),那么就需要证明以下两个命题都成立:P(x)⟹Q(x)和Q(x)⟹P(x)
# 利用逆否命题证明(Proof by Contraposition)
- 在CS70 Chapter1中,我们已经知道P⟹Q和¬Q⟹¬P等价
- 而有时,证明¬Q⟹¬P要比直接证明P⟹Q容易得多
- 因此,我们有时会用逆否命题¬Q⟹¬P来证明
- 例子略
# 利用反证法证明(Proof by Contradiction)
- 反证法的思路核心:假定结论不成立,再通过条件与结论两边的推理得出矛盾(Contradiction),由此得到结论成立。
- 这基于一个重要定律:排中律(见于CS70 Chapter1)
- 更加严谨的证明:
- 反证法证明过程:目标是证明P成立(条件为R)。先假设¬P成立,通过逻辑推理得到¬R,得到结论¬P⟹R∧¬R。
- 而¬P⟹R∧¬R≡False,它的逆否命题就是True⟹P,即P成立。
# 一个经典的例子
- 欧几里得质数定理 :证明质数有无穷多个。
- 如果尝试直接证明,会发现似乎很困难。
- 于是我们选择换个角度:假设结论不成立,即质数只有有限个,我们尝试推出矛盾。
- 在进一步推理之前,先给出一个引理(lemma):
- 对于任意的大于1的自然数,它要么是质数,要么能被一个质数整除。
- 这个引理的证明将会在后面归纳的章节进行,在此不赘述。
- 有了这个引理,我们可以有继续证明:
- 设质数只有有限个,将它们记为p1,p2,⋯,pk;
- 现在定义q:=p1×p2×⋯×pk+1,根据条件与引理可知,q不是质数,于是q可以被一个质数整除,设这个质数为p;
- 则p一定在p1,p2,⋯,pk之中,所以p∣r:=p1×p2×⋯×pk;
- 因此,有p∣q且p∣r,那么p∣(q−r),又q−r=1,于是p≤1,p不是质数。这就与上述条件矛盾,最终得到结论成立。
# 另一个经典的例子
- 证明2为无理数。
- 同样先给出一个引理,这个引理同样也可以用反证法证明(过程略):
- 引理:如果a2是偶数,那么a也是偶数。
- 下面用反证法证明:
- 假设2为有理数,那么存在互质的整数p,q,使得2=qp;
- 有等式可知2=q2p2,即p2=2q2。而q是整数,因此p2为偶数,由引理得p为偶数,即存在整数r使得p=2r;
- 那么带入可得4r2=2q2⟶q2=2r2,类似可得q也是偶数。
- 那么p和q就有公因子2,这与p,q互质矛盾,因此结论成立。
# 分情况证明(Proof by cases)
- 有时将条件作为整体去证明结论比较困难,那么就可以选择将条件进行分解,通过分类讨论证明同一个结论。
- 在分类讨论时,有时也不一定需要严格的枚举,对于每一种情况,只要能找到一个具体的取值(案例)能得到结论就可以。
# 例子
- 证明:存在无理数x,y使xy为有理数。
- 注意到命题中使用了“存在”,那么只需要举出一对x,y满足条件和结论就可以了。
- 我们先取x=2,y=2,并将结果分为两种情况:
- xy=22是有理数,那么已经满足条件和结论;
- 22是无理数,那么我们再取x=22,y=2,有xy=(22)2=(2)22=(2)2=2是有理数,满足条件和结论。
- 因为所有情况只会归为1和2中的一个,所以结论成立。
- 事实上,我们在上述证明过程中甚至都不知道真正满足条件的x是什么,但我们还是完成了证明。这种证明可以称为非构造性证明(non-constructive proof)。
# 一些证明时的注意事项
- 不要将结论直接当作条件——这有可能得到错误的结果。
- 注意“0”的存在——等式两边同时有0时不能同时消去。
- 不等式推导中注意两边同时乘负数时不等号方向改变。
- 其实这些感觉都是从小就培养的思维了,应该不会有什么问题
# 书写证明的风格
- 关于逻辑推理的步骤:在书写下一步之前,确保当前得到的命题已经被严格证明成立(基于公理和之前的推理)。必要时可能需要将一个步骤分解为若干个步骤,以让读者理解并接受。
- 关于引理的使用:引理本质是由一个相对简单的命题得到的结论。一个复杂的命题可以分解为若干个引理,就像一个计算机程序可以分解为几个子程序一样。当然,设置引理的目标还是让引理尽量具有普适性。
- 另外,引理其实和定理之间没有明确的界限。在一个特定的命题中,定理一般是最终得到的结论,而引理可视为在证明中使用的命题。(然而实际上有一些著名的引理常被用来作为命题以证明,如the Pumping Lemma and the Lifting Lemma)