这不是一本教材,而是一册入门书:全书只讲一件事——数理逻辑,即「把推理写成符号,再问符号能推出什么」的学问。它回答的问题朴素而尖锐:什么才算一个证明?证明能不能被机械地检查?有没有一种算法判定任一命题的真假?为什么一个足够强的形式系统证明不了自己的一致性?两千多年里,逻辑从亚里士多德的三段论(第一套推理规则)走到弗雷格的《概念文字》(1879,语言的转向),再经希尔伯特纲领(把数学变成符号游戏)、哥德尔的完备性与两条不完备定理(1929/1931)、Gentzen 的切割消除(1934)、图灵机与不可判定(1936),最终长成今天可以在 Lean、Coq 里跑起来的形式化数学。全书按章组织:绪论用三段论、莱布尼茨之梦与希尔伯特纲领提炼主题;第一章把真假变成可计算的真值表;第二章升到一阶逻辑并给出完备性定理,沿途参观希尔伯特几何、一阶算术与 Tarski 初等欧氏几何三套公理系统;第三章让证明本身成为研究对象(相继式、切割消除、证明即程序);第四章回答「什么能机械地算」(图灵机、停机问题、不可判定);第五章完整走出哥德尔两条定理,并在此交代希尔伯特第一问题(连续统假设)为何被判「独立」;第六章走向当代——证明助手、同伦类型论、逆向数学与人工智能中的逻辑;综合站用年表、人物谱、概念总图、实验与自查收束全书。
写作的三条约束(本书的自我要求)。① 直觉与图形先行:每个概念都从一张图、一个具体的小例子讲起——先在真值表上逐行穷举、把一条推理画成树、把一台图灵机的纸带摊开看读写头怎样游走、把哥德尔编码逐位译回句子,再抽成定义。② 一步一图:凡能画的都画——推理树、相继式证明的形状、图灵机纸带与状态图、编码对照表、五种几何的模型图。③ 自给自足:所需的集合记号、归纳法与初等数论在书内随用随补,不假设手边另有教材;个别深刻结论(完备性定理、两条不完备定理、力迫法)给出精确陈述与证明路线,计算对拍在实验页随附。
页型节奏。每章以 导引 开篇(一页说清这一章要解决什么);主体是 讲义 页(定义、定理、证明,一步一图);每章配 例题 与 习题(末附提示);每章收在 地图(依赖关系)+小结+思想卡(把技术升成观念)+挑战与实验(动手核验);另有 〖札记〗格物札记做中西思想传统的对照。每页右上角标页码,页眉灰色小字标出所属章与页题。
难度标记。讲义页首行用 ★–★★★★★ 标出阅读难度:★ 高中基础即可,★★ 需要集合与计数的基本功(书内自给),★★★ 需要一点抽象经验(等价关系、商结构,书内自给),★★★★ 需要形式证明与归纳的功夫(书内自给),★★★★★ 触及不完备性、力迫法与前沿(第五章、第六章)。若只求理解主线,读绪论、第一章、第二章的完备性定理、第四章的停机问题即可;若求完整掌握,按章顺序逐页推进,并把每章习题做完。
三条线索贯穿全书:
① 明线——从三段论到可运行的证明:先把推理写成符号(绪论),再把真假变成真值表(第一章),升到一阶逻辑并证明完备性(第二章),让证明成为研究对象(第三章),回答机器能算什么(第四章),走到可证性的边界(第五章),最后看见数学在计算机里被逐行验证(第六章)——这正是逻辑一百八十年从「辩论术」长成「工程学」的轨迹。
② 暗线——每一次「显然」都要过形式化的关。「这句话是真的」显然吗?说谎者悖论说否。「这个证明没错」显然吗?切割消除定理要求它可被机械检查。「这个系统不会自相矛盾」显然吗?第二不完备定理说它证明不了。「所有几何都用同一套公理」显然吗?五种几何的模型给了否定的答复。找出「哪些直觉可信、哪些必须形式化、哪些命题永不可判」,是全书反复演练的判官功夫。
③ 接口——通往四个邻域。数理逻辑是数学与计算的共同语法:与集合论(ZFC 与力迫法,第五章、第六章直接合流)、模型论(公理与模型、可判定性,第二章、第三章)、计算(图灵机、复杂度、程序验证与证明助手)、数学基础与哲学(构造主义、希尔伯特纲领与它的终结)四条战线相通。相邻领域中的序数、基数、选择公理与力迫法,在本册中被反复调用与重讲,对读互证。
写法约定(TEX 标准):命题用 p, q, r、公式用 φ, ψ(变量斜体);联结词 ¬ ∧ ∨ → ↔、量词 ∀ ∃、可证 ⊢、满足 ⊨、结构用花体 𝒜, ℬ, ℳ、理论记 T、图灵机记 M、停机问题记 H、连续统假设记 CH。变量斜体,系统名与算子(ZFC、PA、Prov、Con、LK)正体;关键一步配图,直觉与证明逐章对照。
人每天都在推理。看见天边压着乌云,就断定要下雨;听说某人身在另一座城,就断定他此刻不在家。这些「从已知滑到未知」的动作顺滑得几乎不需要练习。可一旦追问一句:这一步凭什么成立?换一个人来做,会不会滑向别的结论?——问题立刻变得既朴素又尖锐。数理逻辑的全部工作,正是把这种「滑」的动作用符号钉下来,再逐字检查它。
本册讲一门既古老又年轻的学问:数理逻辑。说它古老,是因为源头可以追溯到公元前四世纪的亚里士多德;说它年轻,是因为真正的现代化要到十九世纪末才起步,而它最锋利的结论——证明有极限、机器有盲区——全部诞生在二十世纪。本册要回答四个问题。第一,什么是形式语言:像 p → q 这样的符号串怎么读、怎么算。第二,什么是证明:从公理到定理的那一串符号,凭什么算作证明。第三,什么是可计算:机器能做的推理与做不到的推理,边界画在哪里。第四,什么是可证的极限:为什么足够强大的形式系统也证明不了自己的清白。
为看清这条线索,本册反复回到三个场景。真值表把一切可能逐行穷举,是「语义」的化身;证明树把推理的每一步摊开,是「语法」的化身;纸带把计算交给一台只懂读写与移动的机器,是「可计算」的化身。三者合起来,就是二十世纪逻辑学的主干。
本册还有一条自我约束值得先交代:凡「显然」,必过形式化的关。一个论断「显然为真」不足为凭,它要么能被规则推出来,要么就不是定理;一个系统「显然不会自相矛盾」也不足为凭,哥德尔会说明,这件事系统自己说不清。全书就是持续的「过秤」:把直觉放上去,看它几斤几两。
读法建议:凡标有「完整证明」的定理,都在纸上跟着写一遍。逻辑这门学问的特点是——看懂不等于会做,会做才算看懂。
★ 逻辑作为一门有规则的技艺,起点通常定在公元前四世纪的雅典。亚里士多德在《工具论》的《前分析篇》里第一次系统地写下:什么样的推理形式,无论把词换成什么内容,都必然有效。这套学说叫三段论(syllogism),它统治了此后两千年的逻辑教学。
三段论处理的是直言命题,即断定某类对象与某类对象之间包含或不包含关系的句子。亚里士多德区分出四种形式,后世用四个元音字母称呼它们。
| 形式 | 名称 | 句式 | 现代解读 |
|---|---|---|---|
| A | 全称肯定 | 所有 S 是 P | S ⊆ P |
| E | 全称否定 | 所有 S 不是 P | S ∩ P = ∅ |
| I | 特称肯定 | 有的 S 是 P | S ∩ P ≠ ∅ |
| O | 特称否定 | 有的 S 不是 P | S 不包含于 P |
一个三段论由两个前提、一个结论组成,句中只出现三个词项:大词 P(结论的谓词)、小词 S(结论的主词)、中词 M(只在两个前提里出现、负责搭桥)。中词摆放的位置决定格,四个字母的搭配决定式;格与式合起来,就定死了推理的形状。
三段论的关键在于形式:只要形状对,内容随便换都成立。「所有猫是动物;所有动物是生物;所以所有猫是生物」和「所有 M 是 P;所有 S 是 M;所以所有 S 是 P」是同一个推理的两副面孔。亚里士多德甚至把二十余种有效形式逐一列出,让「有效性」第一次成为可以对照清点的对象。
两千年后的裂缝。三段论只认得「主词—谓词」这一种结构,遇到关系就失灵。有一条显然有效的推理:「所有人是动物,所以所有人之头是动物之头。」结论必然成立,却带着一个前提里没出现过的词——「头」。要表达「x 是 y 的头」这种两项之间的关系,直言命题的语言不够用;「每个数都有一个比它大的数」这样的多重量词,也找不到安身之处。这些裂缝一悬就是两千三百年。
补一句常被忽略的公案:与亚里士多德平行的还有公元前三世纪的麦加拉—斯多亚学派(克里西普斯等人)。他们研究的不是主谓包含,而是「如果……那么……」这种联结结构,相当于另一条通往命题逻辑的支线。两支流派要到很晚才真正汇合。
★★ 亚里士多德把推理写成了规则,可规则仍要靠人来执行。能不能再进一步,把推理本身交给计算?这个大胆的念头,最早由莱布尼茨在十七世纪明确说出。
莱布尼茨(Gottfried Wilhelm Leibniz,1646–1716)身兼哲学家与数学家,发明了微积分的符号体系,也发明了二进制。他一生念念不忘两样东西:一套普遍文字(characteristica universalis),把人类全部概念分解为基本概念、各配一个符号;一部推理演算(calculus ratiocinator),让符号按固定规则运算,从而把一切结论推出来。
他给这套设想留下了一句流传最广的话:Calculemus——让我们计算。设想两人意见相左,不必再吵,只需说一声:让我们算一算。算完,谁对谁错自然见分晓。这几乎是「把推理变成可检查对象」最早的宣言。
莱布尼茨还亲自做了准备:他设计二进制,主张一切推理都可归约为符号的机械操作。可这梦想要搁浅两百年——不是缺勇气,是缺工具:当时既没有成熟的符号语言,也没有一套能把「且、或、非」当作运算的代数。
两百年后的 1847 年,英国数学家布尔(George Boole,1815–1864)让一本小册子《逻辑的数学分析》问世,把逻辑第一次真正代数化。七年后的 1854 年,他写出《思维规律的研究》,直言推理的法则就是「思维的规律」,可以写成方程。布尔的做法惊人地简单:把「类」(集合的雏形)当作运算对象,让 xy 表示「既是 x 又是 y」的类,让 x + y 表示「是 x 或是 y」的类,让 1 − x 表示「不是 x」的类。于是推理变成了解方程。
布尔逻辑里有一条与算术分道扬镳的定律:x2 = x(对同一个类重复取交集,结果不变)。这条幂等律宣告逻辑代数不是普通代数,而是一种新代数;后世的「布尔代数」正由此得名,第一章将专门重访它。
不过布尔的逻辑仍停留在类与主谓的层面:他有了运算,还没有量词——说不出「对一切」与「存在」,也说不出两项之间的关系。要把莱布尼茨之梦真正推进一步,需要一次语言的革命。
★★★ 布尔让逻辑会算数了,却还算不出「对一切」与「存在」。补上这一环的是德国数学家、逻辑学家弗雷格(Gottlob Frege,1848–1925)。1879 年,他出版了一本只有几十页的小书——《概念文字》(Begriffsschrift),副标题是「一种模仿算术语言构造的纯思维的形式语言」。今天公认,现代逻辑从这一页开始。
弗雷格做了三件破天荒的事。
第一,把「所有」和「有的」变成算子。在三段论里,「所有 S 是 P」是一个整体句式;弗雷格把它拆成:对每一个个体 x,若 x 是 S 则 x 是 P,前面再加一个「对一切」的符号。量词一旦成为算子,就能一层套一层地嵌套。
第二,把「关系」请进逻辑。三段论说不出的「x 是 y 的头」,在弗雷格的语言里只是把单项谓词 P(x) 换成两项的 R(x, y)。前面那条显然有效却无处安放的关系推理立刻可以形式化,「所有人之头是动物之头」不再是逻辑的漏网之鱼。
第三,用「函项—自变量」取代「主词—谓词」。弗雷格把概念看成不完整的函项:像 x2 = 1 这样的表达式缺一个自变量,填进去才成句。命题与概念于是被统一到同一种分析下——这正是后来一阶逻辑「项与公式」两分的雏形。
语言的转向。这三件事合起来,是一次研究对象的迁移:逻辑不再直接盯着「思维」,而盯着表达思维的符号语言。既然推理要用语言承载,那就先把语言造得没有歧义,再在符号上谈推理。史称这场迁移为「语言的转向」。
弗雷格的雄心不止于逻辑。1884 年的《算术基础》里,他提出逻辑主义纲领:算术的真理归根到底是逻辑的真理,数可以用逻辑概念定义。为落实它,他写了两卷《算术的基本法则》。可惜的是,正当第二卷付印之时,他收到罗素的一封来信——信中一个悖论,恰好击中全书的根基。弗雷格在附录里写下那句沉痛的告白:一个科学家所能遭遇的最难堪的事,莫过于自己大厦将倾之际,被人指出地基早已开裂。
★★★ 十九世纪末二十世纪初,数学正经历一场地基大检视:微积分被严格化推着重写,集合论刚由康托尔开创,罗素的悖论又给朴素集合论凿开一个洞。面对满地裂缝,希尔伯特(David Hilbert,1862–1943)提出一个雄心勃勃的回应:与其零敲碎打地修补,不如把整个数学一次性建成一个可控的形式系统。
1900 年,希尔伯特在巴黎国际数学家大会上提出著名的 23 个问题,为二十世纪的数学列出清单。清单的第二个问题语出惊人:证明算术公理系统是一致的——从它推不出矛盾。这个要求看似技术,实则致命:一个能推出矛盾的数学系统,原则上可以证明任何命题,一切结论同时为真又同时为假,谈不上「可靠」二字。
二十年代,希尔伯特把这一诉求发展成一整套纲领。它的构想分三层:
这套纲领有一个立竿见影的副产品:它把「证明」本身变成了一门可研究的对象。既然证明是符号串,那么证明的长度、形状、能否化简,统统成了数学问题。这正是证明论(proof theory)的诞生,第三章会给它一整章的篇幅。
1928 年,希尔伯特与阿克曼出版《理论逻辑原理》;同年,他在波隆那的国际数学家大会上,把纲领里最后一个悬而未决的问题正式摆上台面——判定问题(Entscheidungsproblem):是否存在一个机械程序,对任意给定的一阶命题,都能在有限步内判定它是否可证、是否有效?换句话说,数学的真理能否被一台忠实执行规则的机器一网打尽?
希尔伯特对这套纲领充满信心。1930 年,他在柯尼斯堡的演讲以一句口号收尾:我们必须知道,我们必将知道(Wir müssen wissen, wir werden wissen)。讽刺的是,正是在同一年,年轻的哥德尔在这个城市的同一系列会议上宣布:一个足够强的形式系统,若一致,必不完备——纲领的完备性与可判定性两端,注定落空。
★★★ 从亚里士多德到希尔伯特,逻辑一路在壮大:推理被写成规则、写成代数、写成量词,最后被写成一场符号游戏。可就在这座大厦看似封顶之际,接连落下三记重击。它们合称「逻辑的三次危机」——说「危机」,是因为每一次都让当时的最高期望落空;说「不是危机」,是因为每一次都长出了一片新天地。
第一次:罗素悖论(1901)。朴素集合论有一条看似天经地义的原则:任何一个明确的「性质」,都对应一个集合,由满足该性质的对象组成。罗素(Bertrand Russell,1872–1970)盯上了这条原则本身。定义集合 R 为「一切不把自己当作元素的集合」:
R = { x : x ∉ x }.
现在问一句:R 是不是它自己的元素?若 R ∈ R,按定义它必须满足「不自属」,即 R ∉ R;若 R ∉ R,它又满足定义、应被收进 R,即 R ∈ R。两头一逼,得到
R ∈ R ⟺ R ∉ R,
一个自相矛盾的等价式。这记重拳正中弗雷格刚刚结卷的《算术的基本法则》:那个悖论用的正是他赖以定义数目的概括原则。修补之道是收缩原则——罗素与怀特海在《数学原理》(1910–1913)中用类型论分层,策梅洛(Zermelo)1908 年给出公理化集合论(后经扩充为 ZFC),把「想造什么集合就造什么集合」改成「按公理逐条造集合」。
第二次:哥德尔不完备(1931)。希尔伯特指望用有穷方法证明算术一致,哥德尔(Kurt Gödel,1906–1978)证明这条路走不通。他的两条定理是:一个一致且能表达基本算术的形式系统,必定存在既不能证明也不能否证的命题(第一不完备定理);并且这样的系统无法在自身内部证明自己的一致性(第二不完备定理)。这里有一个常被混淆的对照必须分清:1929 年,哥德尔先证明了一阶逻辑的完备性——凡是逻辑有效的公式都可被推出;两年后,他证明的是算术理论的不完备性。完备性属于逻辑,不完备性属于数学理论,两句话一点也不矛盾。
第三次:图灵不可判定(1936)。还剩一线希望:即使系统不完备,也许存在一个机械程序,能逐一判定任意命题是否可证?图灵(Alan Turing,1912–1954)用一个极简的抽象机器(图灵机)给「机械程序」下了精确定义,随即证明:不存在这样的程序。他先证明著名的停机问题不可判定——没有任何算法能对任意机器与输入判断它会不会停;据此推出希尔伯特的判定问题无解。同年丘奇(Church)用另一套工具得到相同结论,这就是丘奇—图灵论题的由来。
危机的另一面。三记重击并非全盘否定,而是划定边界:逻辑证明了自己能做什么(一阶逻辑完备、证明可机械检查),也证明了自己不能做什么。可计算性理论与证明论这两门学科,正是从危机中长出来的新大陆。本册后半程将逐一走进这三记重击的内部。
★★ 前面几页把「从哪里来」讲完:三段论、莱布尼茨之梦、弗雷格的转向、希尔伯特纲领、三次危机。从第一章起,旅程正式出发,共六章,每章解决一个大问题,同时沉淀一批标准工具。
第一章 命题逻辑:真值表与推理的骨架。先把真假本身变成可计算的对象:五个联结词、真值表、重言式、范式、函数完备性,然后是形式证明与健全性、完备性。命题逻辑足够简单,简单到能被完整地算清楚——它是全书的地基,也是「可判定」的第一个成功范例。
第二章 一阶逻辑:量词、结构与完备性。加入量词、变元、关系与结构,逻辑的表达力跃升;再证明哥德尔完备性定理:逻辑有效的公式都可被推出。沿途参观希尔伯特几何、一阶算术与 Tarski 初等欧氏几何三套公理系统,看形式化如何落地。
第三章 证明论:相继式、自然演绎与切割消除。把「证明」自身当作对象:自然演绎的引入与消去、相继式演算、Gentzen(1934)的切割消除定理、直觉主义的分岔,直到「证明即程序」的深层对应。
第四章 可计算性:图灵机与不可判定。给「机械地算」下定义,走进停机问题的完整证明,再用归约把不可判定性扩散开来,最后看一眼 P 与 NP 的资源世界与算法的边界地图。
第五章 不完备性:哥德尔的两条定理。哥德尔编码、可证性谓词、对角线引理,完整走出两条不完备定理;并交代连续统假设为何被判「独立」于集合论公理。
第六章 逻辑的当代面孔。证明助手(Coq、Lean、Isabelle)、同伦类型论、构造主义与逆向数学,以及逻辑在数据库、模型检测与人工智能中的身影——逻辑正在变成一门工程。
三条线索贯穿全书。明线是从三段论到可运行的证明——把推理写成符号,再把符号交给机器;暗线是每一次「显然」都要过形式化的关——哪些直觉可信,哪些必须形式化,哪些命题永不可判;接口是逻辑与集合论、模型论、计算、数学基础四条战线相通。行李清单并不长:集合与映射的基本记号、归纳法、一点初等数论,这些在书内随用随补,不假设手边另有教材。
本页任务。把绪论的行李清点一遍:哪些年份必须记准,哪些概念必须带走,哪些问题留作路标。
概念清单。① 三段论与直言命题:亚里士多德用 A、E、I、O 四种句式把推理形式化,中词搭桥,格与式定形状;② 莱布尼茨之梦:普遍文字加推理演算,Calculemus「让我们计算」;③ 布尔代数:把「且 / 或 / 非」变成「乘 / 加 / 补」,x2 = x 的幂等律划开逻辑与算术;④ 弗雷格的转向:量词成为算子、关系进入逻辑、函项取代主谓,「语言的转向」由此发生;⑤ 希尔伯特纲领三问:一致性、完备性、可判定性;⑥ 三次危机:罗素悖论、哥德尔不完备、图灵不可判定。
年表(史实年份须记准)。
| 年份 | 事件 |
|---|---|
| 约前 350 | 亚里士多德《前分析篇》:三段论 |
| 约前 300 | 麦加拉—斯多亚学派:假言推理 |
| 1670 年代 | 莱布尼茨提出普遍文字与推理演算 |
| 1847 / 1854 | 布尔《逻辑的数学分析》/《思维规律的研究》 |
| 1879 | 弗雷格《概念文字》:量词与语言的转向 |
| 1900 | 希尔伯特巴黎演讲,第二问题(算术一致性) |
| 1901 | 罗素悖论:朴素集合论被击穿 |
| 1910–1913 | 罗素与怀特海《数学原理》:类型论 |
| 1928 | 希尔伯特—阿克曼提出判定问题 |
| 1929 | 哥德尔完备性定理(一阶逻辑) |
| 1931 | 哥德尔两条不完备定理(算术) |
| 1934 | Gentzen 相继式演算与切割消除 |
| 1936 | 图灵机与不可判定、丘奇论题 |
路标问题(各章的靶心)。① 命题逻辑为何可判定?(第一章)② 一阶逻辑为何完备?(第二章)③ 证明能否化简、能否机械化?(第三章)④ 什么是可计算、什么是不可判定?(第四章)⑤ 足够强的系统为何不完备?(第五章)⑥ 逻辑如何走进工程?(第六章)
预习提示。第一章会密集使用集合记号、归纳法与一点初等数论。若手感生疏,自测三件小事:① 把「p 与 q 中至少一个为真」写成符号;② 用归纳法证明 1 + 2 + ⋯ + n = n(n + 1)2;③ 复述「等价关系」的三条性质。三件小事都顺手,第一章可以放心加速。
行李点清,出发。第一章的号令只有一句:先把真假变成可以计算的东西。
绪论把「推理」立成一个必须被逐行核对的物件,也留下一个问题:最小的那块砖长什么样?本章给出答案——把每一句陈述的真假压成一个符号 0 或 1,把每一个连接词压成一张有限的小表。于是推理不再玄妙:一句话对不对,或者把一张表算到底,或者把一串规则查到底。
这条路分两股。一股是语义:给命题变元指派真假,用真值表穷举一切可能,看哪些公式在所有指派下都取真(重言式),哪些公式彼此同真同假(逻辑等价)。另一股是语法:把「允许的推理步」写成规则,把「证明」定义成一串可以逐行验收的符号,完全不提真假,只看符号怎样变形。本章最重的两块基石,正是最后证明这两股路合流:语义上恒真的公式,恰好就是语法上可证的公式——命题逻辑的健全性与完备性。
五阶路线如此展开。第一阶(§1.1–1.4)语义:五个联结词、真值表、重言式与逻辑等价、析取与合取范式——把「真假」变成可计算的对象。第二阶(§1.5)完备性:证明单独一个 NAND 或 NOR 就能搭出全部联结词,语言由此可以极简。第三阶(§1.6–1.8)语法:肯定前件与假言三段论、演绎定理、自然演绎、形式证明的定义——让「证明」成为一串可检查的符号。第四阶(§1.9–1.11)元定理:健全性、完备性、紧致性、布尔代数——回答「语法与语义为什么一致」。第五阶(§1.12–1.15)机器:可判定性、开关电路、SAT 与 NP 完全、卢卡西维茨公理系统——让逻辑落到硅片上,也落到公理的骨架里。
常驻嘉宾:一个公式。本章从 §1.2 起反复使用一个具体公式——「若 p 蕴含 q,且 q 蕴含 r,则 p 蕴含 r」,写成符号即
((p → q) ∧ (q → r)) → (p → r).
它小到真值表只有八行,却足够承载全章的概念:在 §1.2 它是真值表的第一号标本;在 §1.3 它是重言式的样板;在 §1.6 它是假言三段论规则的另一副面孔;在 §1.7 它由一个演绎定理的证明兑现;在 §1.10 它再次作为紧致性里的有限片段出场。与它保持熟络——读完本章,应当能在三分钟内默写出它的真值表,并说清它为什么恒真。
读法建议:凡标着「完整证明」的定理,纸笔重写一遍。逻辑这门手艺的特点是——看懂只算见过,写对才算学会。
★ 逻辑的最小单位是一句话的真假。本节把「一句话」切成两样东西:不可再分的原子(命题变元),与把它们拼接起来并决定真假的黏合剂(联结词)。五个联结词就是五个按钮,每个按钮的行为由一张有限的小表写死。
五个联结词分别是:否定 ¬(一元),合取 ∧、析取 ∨、蕴含 →、等值 ↔(二元)。关键在于它们不是靠「意思」定义的,而是靠「表」定义的——表怎么定,词就怎么算。下表就是这五个按钮的全部说明书。
| p | q | ¬p | p∧q | p∨q | p→q | p↔q |
|---|---|---|---|---|---|---|
| 0 | 0 | 1 | 0 | 0 | 1 | 1 |
| 0 | 1 | 1 | 0 | 1 | 1 | 0 |
| 1 | 0 | 0 | 0 | 1 | 0 | 0 |
| 1 | 1 | 0 | 1 | 1 | 1 | 1 |
逐列读这张表,各联结词的性格一目了然。¬ 只做一件事:把 0 翻成 1、把 1 翻成 0。∧ 苛刻,只有两真才真。∨ 宽容,只要有一真即真(注意这是兼容的「或」,不是日常「要么这样要么那样」的排他或——排他或将成为习题里的明星)。↔ 数「相同」:两值一样则真。
真正需要停一秒的是 →。表告诉我们:p → q 只有在 p 真而 q 假时才是假,其余三行一律为真——这叫实质蕴含。它带来的第一个「反直觉」是:前件为假时整个蕴含自动为真。于是「若 2 + 2 = 5,则雪是黑的」按此定义是一个真命题。这不是诡辩,而是形式化的纪律:若要把「如果……那么……」当成一个只依赖真值的算子,它的表只能这么填——否则推论规则(下一节)就无法成立。把「→ 不是因果,也不是推理过程」这句话记牢,本章后半程会反复回来算这笔账。
为省括号,约定结合优先级由紧到松为 ¬ > ∧ > ∨ > → > ↔;同级的 ∧ 与 ∨ 左结合。例如 p ∨ q ∧ r 读作 p ∨ (q ∧ r)。凡省略会引起歧义处,一律补括号,宁可啰嗦。
练习式观察。把日常语言翻译成符号:令 r 表示「下雨」、u 表示「带伞」,则「如果下雨,我就带伞」写作 r → u;「既没下雨也没带伞」写作 ¬r ∧ ¬u;「或者下雨,或者带伞(至少一件)」写作 r ∨ u。第一句翻成 → 之后,它在「没下雨」的两行自动为真——这正是形式化必须付出的代价与获得的收益。
★★ 一个公式含 n 个命题变元,每个变元只有真、假两种取值,于是全部可能的指派恰有 2n 种。真值表就是把它们一行一行摊开,逐行算出公式的值。这是本章最笨、也最可靠的方法:它把一个「是否恒真」的疑问,换成一次有限的查表。
造表的纪律是「由内向外、逐列求值」:先给每个变元列出全部取值的组合,再按公式的构造顺序,先算子公式、后算母公式。以常驻嘉宾 φ = ((p → q) ∧ (q → r)) → (p → r) 为例,它有三个变元,八行,需要依次计算 p → q、q → r、(p → q) ∧ (q → r)、p → r,最后一列才是整个公式。
| p | q | r | p→q | q→r | (p→q)∧(q→r) | p→r | φ |
|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |
| 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 |
| 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 |
| 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
| 1 | 0 | 1 | 0 | 1 | 0 | 1 | 1 |
| 1 | 1 | 0 | 1 | 0 | 0 | 0 | 1 |
| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
末列八个 1,无一例外。亲手补一遍中间几列——这是全章唯一一次可以「按机械劳动换确定性」的机会,务必亲手走过。观察一个易错点:第 3 行里 q → r 取 0,于是合取列取 0;但合取为 0 只说明前提包没被满足,母公式的前件为假,整个蕴含反而为真。这条「前件假 ⇒ 蕴含真」的规则是全表恒真的关键,也是初学者最容易数错的地方。
真值表把「恒真」这个性质变成了一次可完成的检查。但它有一个代价,本页先把账记下、留到 §1.12 细算:行数随变元数指数增长。n = 10 时 1024 行尚可忍受,n = 20 时上百万行,n = 60 时已超过宇宙原子的数量级。真值表是「原则上可达」的,却未必是「实践上可行」的——这条裂缝,最终撕出了计算复杂性这一整片天地(§1.14)。
另一种读法。真值表还可以反过来用:它是一张「公式的行为指纹」。两个公式若真值表逐行相同,就在一切场合表现一致——这正是下一节「逻辑等价」的定义来源。所以真值表不只回答「是否恒真」,更提供了一个判等、分类与查错的通用仪表盘。
★★ 真值表把公式按「行为的脾气」分成三类。本节给这三类命名,并由此引出全章最常用的一件工具——逻辑等价,以及它背后一条精美的对称律:对偶原理。
三类之间的换算值得记牢:φ 是重言式 ⟺ ¬φ 不可满足;φ 是矛盾式 ⟺ ¬φ 是重言式。重言式与可满足性是一枚硬币的两面——这一点在 §1.14 会变成「判定重言式与判定可满足性同样难」的复杂度等价。
符号上要分清两把不同的尺子:↔ 是语言内部的联结词,它造出一个新公式;而 ≡ 是语言外部的断言,它说「这两个公式恒同真值」。同理 ⊨ 也是外部记号。此时不妨先把「内部 vs 外部」这条线记住,§1.8 会把它升格为「对象语言 vs 元语言」。
下表列出最常备的等价律,它们是把复杂公式化简、改写、变形的基本钳工工具。
| 名称 | 等价式 |
|---|---|
| 双重否定 | ¬¬p ≡ p |
| 幂等 | p∧p ≡ p,p∨p ≡ p |
| 交换 | p∧q ≡ q∧p,p∨q ≡ q∨p |
| 结合 | (p∧q)∧r ≡ p∧(q∧r) |
| 分配 | p∧(q∨r) ≡ (p∧q)∨(p∧r) |
| 德摩根 | ¬(p∧q) ≡ ¬p∨¬q,¬(p∨q) ≡ ¬p∧¬q |
| 蕴含改写 | p→q ≡ ¬p∨q |
| 逆否 | p→q ≡ ¬q→¬p |
「蕴含改写」与「逆否」是本章出现频率最高的两条。p → q ≡ ¬p ∨ q 把蕴含化成纯粹的和差,下一节的范式构造全靠它;逆否律 p → q ≡ ¬q → ¬p 则解释了「反证法为什么合法」:要证 p → q,可以改证它的逆否命题。
对偶原理的直觉来自德摩根:把「非」推入括号内层,∧ 会翻成 ∨、∨ 会翻成 ∧。于是给一个公式整体取反,等价于给它对偶化后再把每个变元取反。这条律省下了大量重复劳动:证了一条分配律,它的对偶版本自动到手;写了一份真值表,它对偶版的表也一并写好了。
本节的落点可以一句话概括:真值表把公式分类,等价律把公式变形,对偶律让变形成对出现。下一节要证明一件更强的事:无论公式多复杂,它都能被整理成两种标准形状之一——析取范式与合取范式。这等于宣布,命题逻辑里「所有的公式」其实只长成有限几种样子的组合。
★★ 等价律能做变形,但变形可以千变万化,缺少一个「终点」。本节给出两种标准终点:析取范式与合取范式。令人安心的是,终点不但存在,而且在固定变元集合的意义下唯一——任何一个公式,都有一张只属于它的「标准身份证」。
构造法(真值表法)。先写真值表,再「照抄真行」。设 φ 在某行的取值为 1。把该行中取 1 的变元写成自身、取 0 的变元写成其否定,再把这些文字全部用 ∧ 连成一个合取子句——这个子句只在该行取 1,称为该行对应的极小项。把 φ 所有取 1 的行对应的极小项全部用 ∨ 连起来,就得到主析取范式:它恰好在 φ 为真的那些行取 1。对偶地,把 φ 取 0 的行对应的极大项(取 0 的变元写自身、取 1 的写否定,再用 ∨ 连)全部用 ∧ 连起来,就得到主合取范式。
唯一性为什么成立。主析取范式为真的行集合,恰是它所含极小项的指标集合;若两式等价,则两式的真值列相同,故极小项指标集合相同,于是两式只差子句次序。这就是「不计次序唯一」的全部内容——唯一性不是深奥的定理,而是「真值列决定一切」的直接推论。由此还得到一条极好用的判据:两个公式等价,当且仅当它们的主析取范式(在同一变元集合下)相同。
唯一性带来一个漂亮的计数:含 n 个变元的公式,其主析取范式由「选哪些极小项」完全决定,而极小项共 2n 个,故不同的真值函数共有 22n 个。这条计数将直接支撑下一节的函数完备性——「所有 n 元布尔函数」不是一团不可名状的东西,而是一个可以被数出来的有限集合。
范式还有一个实践上的用途,将在 §1.14 兑现:把公式写成 CNF 之后,「哪些指派能满足它」变成一个可以交给机器的查表问题。SAT 问题的输入标准就是 CNF。所以本节不只是理论整理,它同时在为「机器如何读逻辑」制定文件格式。
★★★ 范式告诉我们:任一公式都等价于「选取若干极小项」的组合。既然选极小项要用到 ¬、∧、∨ 三个联结词,那么这三件工具是否够用了?本节把这个问题问到底,并把答案推到极端——只用一个联结词就够。
证明。任取公式 φ,由定理 1.6,φ 等价于其主析取范式 (l11 ∧ … ∧ l1n) ∨ … ∨ (lk1 ∧ … ∧ lkn),其中每个 l 是变元或其否定。该范式只用到 ¬、∧、∨ 三者,故它们能表达任意 φ。∎
证明。先看 {¬, ∧}:析取可用德摩根律写出 p ∨ q ≡ ¬(¬p ∧ ¬q),于是在完备集 {¬, ∧, ∨} 里把每个 ∨ 替换成该式即得只用 {¬, ∧} 的表达式。{¬, ∨} 对称地由 p ∧ q ≡ ¬(¬p ∨ ¬q) 得证。{¬, →} 则由蕴含改写 p ∨ q ≡ ¬p → q 与 p ∧ q ≡ ¬(p → ¬q) 得到。∎
到此为止,每去掉一个联结词,都需要「否定」留守——¬ 似乎是不可替代的。真的如此吗?下面这个联结词将证明 ¬ 也可以一并省去。
证明。只需用 ↑ 表达出完备集 {¬, ∧} 的两个成员,再由定理 1.10 的传递性即得。
证明。平行地:¬p ≡ p ↓ p;p ∨ q ≡ (p ↓ q) ↓ (p ↓ q);p ∧ q ≡ (p ↓ p) ↓ (q ↓ q)。于是 ↓ 表达了完备集 {¬, ∨},故完备。∎
这两个定理把「语言的最小化」推到极限:整个命题逻辑,可以只用一种门来建造。它并非纸上奇观——真实的数字电路正是以 NAND 门为基本砖块,工程师偏爱它,因为它的晶体管实现最省、最稳(§1.13 再看)。一个更一般的问题留作余韵:哪些联结词单独够用?答案是 ↑ 与 ↓ 这两个「独裁者」。Post 在 1920 年代给出了完整的分类定理,在习题中尝到它的边角。
★★ 前五节都在描述公式的真假,接下来要问:怎样从一组前提出发,合法地走到结论?本节给出第一批推理规则,它们是形式证明的螺丝钉。
把「有效」落成可执行的检验,只需一张真值表:凡是前提全真的行,结论那一列也必须真。只要找到一行前提全真而结论为假——这叫反例指派——论证立即无效。一票否决,干脆利落。
下面两条规则是本章使用频率最高的推理动作。
为什么这两条规则合法?用真值表一击即可:只要 p 与 p → q 同真,p → q 的真值表就逼着 q 为真(否则蕴含为假);HS 的合法性则正是 §1.2 那张八行表恒真的另一种说法——常驻嘉宾公式说的就是「HS 有效」。推理规则与重言式,其实是同一件事的两副面孔:一个说「这样写合法」,一个说「这样写导出的公式恒真」。
常用的规则还有一批,列在下面的卡片里。它们都可以用真值表逐条验证,自证其中两条。
| 规则 | 形式 | 俗称 |
|---|---|---|
| 拒取式 MT | p→q, ¬q ⊢ ¬p | 反证的味道 |
| 析取三段论 | p∨q, ¬p ⊢ q | 排除法 |
| 附加 | p ⊢ p∨q | 弱化 |
| 化简 | p∧q ⊢ p | 取其一 |
| 合取 | p, q ⊢ p∧q | 打包 |
与规则同样重要的是认清谬误。肯定后件(由 p → q 与 q 推 p)与否定前件(由 p → q 与 ¬p 推 ¬q)都无效:把 (p,q) = (0,1) 代入,前件假、后件真,p → q 仍真,却足以让这两个「推理」的结论翻车。承认 → 只谈真假、不谈因果,就是避免踩进这两个坑的关键。
本节留下的问题是:这些规则用法千变万化,如何保证「每一步都合法」?答案是把证明当作一个符号序列,逐步验收——这正是 §1.7 与 §1.8 的主题。
★★★ 人在推理时会说「假定 φ 成立……于是 ψ 成立,所以 φ → ψ」。这个日常动作要合法化,就需要演绎定理;而把各类规则组织成一套贴近人的证明书写法,则得到自然演绎。
证明(要点)。右推左方向容易:若 Γ ⊢ φ → ψ,那么在原证明后再接一步「由 φ 与 φ → ψ 经 MP 得 ψ」,其中 φ 现成取自新增的前提——于是 Γ ∪ {φ} ⊢ ψ。左推右方向对证明的长度作归纳:设 ψ1, …, ψn 是从 Γ ∪ {φ} 出发到 ψ 的证明。逐行证明每个 Γ ⊢ φ → ψi:若 ψi 是公理或属于 Γ,则 ψi 可证,再由公理 ψi → (φ → ψi)(即 §1.15 的第一条公理 A1)与 MP 得 φ → ψi;若 ψi 就是 φ 本身,则 φ → φ 可证(§1.15 将演示);若 ψi 由前面两行 ψj 与 ψj → ψi 经 MP 得到,则用归纳假设得 φ → ψj 与 φ → (ψj → ψi),再由公理 A2 (φ → (ψj → ψi)) → ((φ → ψj) → (φ → ψi)) 两次 MP 得 φ → ψi。归纳到底即 Γ ⊢ φ → ψ。∎
演绎定理的实践意义叫条件证明:要证 φ → ψ,可以先「假定 φ」,把 φ 当作临时前提推出 ψ,然后宣布蕴含成立。这条策略把许多难证的目标化成一个顺着走的推导。
自然演绎干脆把这条策略写进规则。它给每个联结词配一对动作:引入(把该联结词造出来)与消去(把它拆开用)。核心规则如下。
| 联结词 | 引入规则 | 消去规则 |
|---|---|---|
| → | →I:假定 φ 推出 ψ,得 φ→ψ | →E:由 φ 与 φ→ψ 得 ψ(即 MP) |
| ∧ | ∧I:由 φ 与 ψ 得 φ∧ψ | ∧E:由 φ∧ψ 分别得 φ 或 ψ |
| ∨ | ∨I:由 φ 得 φ∨ψ(或由 ψ 得) | ∨E:两种情形都推出同一结论 χ |
| ¬ | ¬I:假定 φ 推出矛盾,得 ¬φ | ¬E:由 φ 与 ¬φ 得矛盾 ⊥ |
看 →I 的运作方式:把「假定 φ」这一段的推导放进一个假设盒,盒内可以自由使用 φ;当盒内推出 ψ,就把盒子关上,在盒外写下 φ → ψ。盒内的 φ 不能拿到盒外使用——这条「封装」纪律正是演绎定理在书写层面的化身。若把 →I 与演绎定理并读,会发现二者说的是同一件事:「临时假设」与「蕴含」是一体两面。
自然演绎与下一节的「公理系统 + 规则」路线形式不同,效力却一致:两者可证的东西完全相同(可互相模拟)。前者像人,直观、好写;后者像机器,条目统一、易于分析。命题逻辑的健全性与完备性,对两者都成立——§1.9 就走元定理那条路。
★★★ 「证明」这个词在数学里一直靠默契运转。形式逻辑要做的事,是把它变成一件可以机械检查的物件。本节给出定义:一个证明,就是一串符号,加上一台逐行核对器。
先说两种语言。逻辑学家区分对象语言与元语言。对象语言是被研究的符号系统本身(公式 p → q、联结词、公理);元语言是我们谈论对象语言时用的语言(「φ 是重言式」「Γ ⊢ ψ」)。本页的定理都是元语言里的陈述,而它们说的对象是对象语言里的符号串。这条区分是读懂整个元数学的前提。
定义里每个字都在为「机器可检」服务。序列有限,所以检查会终止;每个 φi 的身份只依赖「是否公理 / 是否假设 / 由前面哪几项按哪条规则得到」,所以检查只需逐步查表,不需要任何「洞察」。
形式证明有几条立刻可用的性质,都由定义直接读出。
注意「有限性」这条看似平淡的性质,会在紧致性里放大成定理。形式证明的力量恰恰来自它的贫瘠:它只允许有限的符号操作,因而每一步都能被审计。把推理限制到可检查的程度,换来的是确定性——这是本册反复出现的主旋律。
最后留一句预告。Γ ⊢ φ 是一条存在性陈述:存在某个符号序列。它与 Γ ⊨ φ(一条普遍性陈述:一切指派都如此)看上去毫不相干。下一节要证明的,恰恰是这两条看似无关的陈述其实处处同步——这就是命题逻辑的健全性与完备性。
★★★★ 语法说「符号能变形到」,语义说「真假处处如此」。本节证明它们步调一致——先证「能证的必真」(健全性),再证「必真的能证」(完备性)。后者是本章的顶点,走极大一致集(又称 Lindenbaum 扩张)路线。
证明。对证明长度归纳。设公理系统的一切公理都是重言式(§1.15 的三条公理各自如此,又任意代换入公理仍得重言式)。取任一满足 Γ 的指派 v,归纳证明序列中每一项 φi 都满足 v(φi) = 1:若 φi 是公理,则是重言式,故取 1;若 φi 是假设,由 v 满足 Γ 故取 1;若 φi 由 φj 与 φj → φi 经 MP 得到,则两项的归纳假设给出二者皆真,而 v(φj) = 1 与 v(φj → φi) = 1 逼出 v(φi) = 1。特别地末项 φ 取 1。由于 v 是任取的满足 Γ 的指派,得 Γ ⊨ φ。∎
完备性走一条等价的路。先证一个形式上更整齐的命题:每个一致的公式集都可满足。它与完备性等价,但结构更清晰。
把两条定理合起来:Γ ⊢ φ ⟺ Γ ⊨ φ。符号的变形能力与真值的必然性完全吻合——这正是希尔伯特所说的「逻辑的可靠性」:形式系统不会证出假的东西(健全),也不会漏掉真的东西(完备)。
这一路线的每一块砖都已在本章铺好:一致与矛盾的语法定义(§1.8)、演绎定理(§1.7)、蕴含改写为析取(§1.3)。完备性定理并非孤立奇观,而是本章前半全部工具的合流。命题逻辑的第一个伟大定理,就此收口。
★★★★ 上一节的完备性有一个立竿见影的推论:整体可满足,只取决于每个有限片段可满足。这条性质看似平淡,却能把无穷多个条件的问题压缩成有限次可检验的条件,是本章最有「魔术感」的一条定理。
证明。一个方向是显然的:若 v 满足整个 Γ,则它自然满足 Γ 的任一子集,特别地满足每个有限子集。
另一个方向用反证。设 Γ 的每个有限子集都可满足,但 Γ 本身不可满足。由定理 1.24 的逆否(不可满足蕴含不一致),Γ 不一致,即存在 φ 使 Γ ⊢ φ 且 Γ ⊢ ¬φ。而任何证明都只有有限行(§1.8),两个证明实际动用的假设合起来仍只有有限多条——记为 Γ0 ⊆ Γ,则 Γ0 ⊢ φ 且 Γ0 ⊢ ¬φ。由健全性(定理 1.23),Γ0 ⊨ φ 且 Γ0 ⊨ ¬φ;但这不可能,因为满足 Γ0 的指派会同时逼出 φ 与 ¬φ 都取 1。于是 Γ0 不可满足,与「每个有限子集可满足」矛盾。故 Γ 可满足。∎
证明短得近乎狡猾:它没有直接构造满足 Γ 的指派,而是绕道「不可满足 ⇒ 不一致 ⇒ 有限个假设就够用 ⇒ 某个有限子集不可满足」。整条链的关键,是证明的有限性——那个在 §1.8 里不起眼的性质,在这里变成了从无穷跨向有限的桥。
这个例子的震撼之处在于:结论本身是「存在一个全局着色」,而所用的全部证据只是「每个有限部分都有着色」。紧致性把「整体存在」悄悄换成了「局部存在的可检查总和」。同样的手法可以推出「任意偏序集可扩张为全序」的有限版本,以及一阶算术存在非标准模型(含大于一切自然数的元素)——后者是第五章哥德尔定理的舞台布景。
与完备性一样,紧致性的所有部件都来自本章:一致性(§1.8)、健全性与完备性(§1.9)、证明的有限性(§1.8)。它也是把命题逻辑的经验抬升到一阶逻辑的经验——第二章的完备性与紧致性,走的仍是这条「有限片段撑起整体」的路。
★★★ 前九节把真假当作真值表来算,本节换一副眼镜:把 ∧, ∨, ¬ 看成三种「运算」,把等价律看成「运算律」。于是命题逻辑忽然成了代数的一个分支,可以像解方程那样去变形。
把 §1.3 的等价律表与上面的公理逐条对照,会发现它们一一对应:逻辑里的 ≡ 正是代数里的 =,逻辑里的重言式正是代数里恒成立的等式。于是「化简公式」与「化简代数式」变成同一门手艺。¬ 是求补,0 / 1 是下界与上界。
布尔代数还能装上「序」。定义 a ≤ b 当且仅当 a ∧ b = a(直觉:a 不比 b 强)。可验证这是一个偏序,且任两元有最小上界(a ∨ b)与最大下界(a ∧ b),故布尔代数首先是一个格。在幂集代数里,这个序就是 ⊆;在公式代数里,它就是「a → b 是重言式」。
Stone(1936)给出的证明路线极具启发:把布尔代数的「超滤子」(对 ∧, ∨ 封闭、不含 0 且对每个 a 恰含 a 或 ¬a 的最大家庭)全体记为 S(B),配以适当拓扑成为布尔空间;再证明 B 同构于 S(B) 上闭开集的代数。超滤子扮演的角色,就是「完备性证明里的那个赋值 v」——把每个命题送向真或假。§1.9 的极大一致集,在代数语言里正是林登鲍姆–塔斯基代数的一个超滤子。于是完备性定理获得了第二种证法:存在足够的超滤子来区分一切元素(布尔素理想定理)。
本节的收获可以概括为三步并作一步:等价律是公理、公式类是元素、赋值是超滤子。同一件事被三种语言描述,各有各的方便——这正是二十世纪数学「结构主义」的典型面貌。下一节回到最具体的层面:既然一切都能算,那么命题逻辑的判定,究竟要付多少代价?
★★★ 到目前为止,「是否重言式」「是否可满足」都是靠人算出来的。本节问一个更硬的问题:有没有一种机械程序,对任意输入公式都能在有限步内给出「是/否」?命题逻辑的答案是肯定的,而这道肯定恰好是一整片否定结果的对照物。
算法。输入含 n 个变元的公式 φ。枚举全部 2n 个指派(每一指派可看作一个 n 位二进数 0, 1, …, 2n − 1),对每个指派按语法树自底向上求值;若某指派使 φ 取 1,输出「可满足」,否则输出「不可满足」。停机性来自枚举有限:循环次数恰为 2n,必停。正确性来自真值表的定义 1.2:逐行覆盖了一切可能,无遗漏。
这条定理的分量,在它的对照物面前才显出来。谓词逻辑(一阶逻辑)没有这样的程序——是否存在一个算法判定任意一阶公式是否有效,这就是希尔伯特 1928 年提出的判定问题(Entscheidungsproblem)。Church 与 Turing 在 1936 年各自独立给出否定回答:一阶逻辑不可判定。命题逻辑与一阶逻辑之间隔着的,正是量词 ∀ ∃(第二章登场)——量词把「有限的穷举」升级成「无穷的搜索」,判定性就此失守。这条分界线是全书最重要的一条分界线之一。
不过「可判定」只保证存在一个总会停机的程序,并不保证它快。真值表算法的时间是 O(2n):n = 10 要一千次求值,尚可;n = 30 要十亿次,吃紧;n = 100 则连宇宙寿命都不够。指数增长意味着原则上可判定、实践上不可行——这条裂缝,下一节将把它生产成整片计算复杂性理论。
把本节的措辞收紧一点:「可判定」是关于存在性的断言,「复杂度」是关于资源量的断言。两者分属两个年代——前者是 1930 年代逻辑学的主要关切,后者是 1970 年代理论计算机科学的主要关切。命题逻辑同时落在两个战场的正中央:它既可判定(逻辑的好消息),又藏着一个 NP 完全问题(计算的最难谜题之一)。下一节正面迎战后者。
★★ 逻辑能不能被造出来?能。1937 年, Shannon 在硕士论文《继电器与开关电路的符号分析》中证明:布尔代数与开关电路是同一个东西的两副面孔。这一篇论文,是数字时代的开工令。
于是任何命题公式都能被翻译成一张电路图,任何电路也都能被读成一个公式。公式的求值与电路的导通判定是同一件事:给每个开关定开合状态,看整条线路通不通——这正是一次真值指派下的公式求值。
把开关抽象成符号,就得到逻辑门:AND 门、OR 门、NOT 门,以及 §1.5 的主角 NAND 门与 NOR 门,还有常用的 XOR 门(异或,记 ⊕,恰是「相异为真」的排他或)。门电路的输入输出都是 0/1 电平,行为由真值表写死。两个门拼在一起做一个小任务,就得到可复用的组合元件——其中最有名的是加法器的半成品:
这里出现了本章与工程世界最要紧的一段对话。§1.5 证明了 NAND 单独完备,工程上又发现 NAND 门的晶体管实现最省——两者一配合,结论就是:整台计算机的逻辑,可以完全用 NAND 门搭出来。从真值表到 NAND 完备性再到芯片版图,一条直线走通。逻辑不是对推理的比喻,而是芯片上电流的真实走向。
本节还留了一个技术疑点给电路设计者:一个组合电路的「输出是否正确」,本质上是一次公式求值,可以逐位核对;但要让电路「更省、更快」,就要找同样功能里最短的表达式——这是布尔函数最小化问题,与下一节的复杂度话题同宗。
★★★★ 上一节证明了命题逻辑可判定,也指出了代价的指数墙壁。本节把这个问题正式命名、正式量化,并迎来逻辑学对计算理论的最大一次馈赠——SAT 是第一个 NP 完全问题。
SAT 之所以自然,是因为 §1.4 已把「任意公式」标准化成 CNF,所以「任意公式是否可满足」都能翻译成一个 SAT 实例。而判定一个公式是否重言式,等价于判定其否定是否不可满足,故重言式问题与 SAT 同难。
归约思路(要点)。设 L 是任一 NP 语言,由多项式时间验证器 V 刻画:x ∈ L 当且仅当存在见证 y(长度多项式有界)使 V(x, y) 停机接受。把 V 在输入 (x, y) 上的整段计算历史摊成一张二维表格:行是时刻 0, 1, …, T,列是纸带格。引入命题变元,刻画三条事实:①每一时刻机器恰处于一个状态;②每一时刻读写头恰在一个位置;③每一时刻每个带格恰含一个符号;再用子句强制相邻两行遵守转移函数(本次与下次格局合法)、首行编码初始格局(x 固定、y 用待填变元)、末行含接受状态。所得 CNF 的规模是 T 的多项式,而 φx 可满足 ⟺ 存在见证 y 使 V 接受 ⟺ x ∈ L。这就是把「存在一条接受计算路径」翻译成「存在一个满足指派」的全部内容。
Cook 与 Levin 的结果意义深远:它给 NP 里所有问题立了同一把标尺。此后一旦证明某个新问题能多项式归约自 SAT,它就立刻晋升 NP 完全——今天已知的 NP 完全问题已逾四千个,覆盖排课、装箱、旅行商、蛋白质折叠、电路布线。它们如同被同一根锁链拴住:只要其中任何一个有多项式算法,则全部都有,P = NP 成立;反之若认定 P ≠ NP,则它们全体都无法被高效求解。P 是否等于 NP,是克雷数学研究所七大千禧年问题之首,悬赏百万美元,至今未决。
本章到此完成了从真值表到复杂性的整条链:真假 → 联结词 → 真值表 → 范式 → 可判定性 → 复杂度。逻辑最初是一套讲「怎样算推得对」的规矩,走到这里,它已经把「机器能不能高效判定」这一整个领域纳入了自己的疆域。下一节回到起点,用最省的符号把这条链的骨架重搭一遍——卢卡西维茨的三条公理。
★★★★ 本章一路用了自然演绎与推理规则,却始终没有把「公理」正式列出。本节补上最经典的一套:卢卡西维茨三公理系统。它只用两个联结词、三条公理、一条规则,就撑起了整个命题逻辑——极简到几乎苛刻。
φ → (ψ → φ).
(φ → (ψ → χ)) → ((φ → ψ) → (φ → χ)).
(¬φ → ¬ψ) → (ψ → φ).
唯一的推理规则是肯定前件 MP:由 φ 与 φ → ψ 得 ψ。其余联结词按习惯缩写:φ ∨ ψ := ¬φ → ψ,φ ∧ ψ := ¬(φ → ¬ψ),φ ↔ ψ := (φ → ψ) ∧ (ψ → φ)。「代入例式」的含义是:把公理中的 φ, ψ, χ 换成任意公式,得到的新公式仍算公理——这一条使公理从三条膨胀成无穷多条,却也使证明的机械检查依旧可行。
这三条为什么是这三条?A1 说的是「一个真命题被任何命题蕴含」;A2 说的是「蕴含可以沿括号分配」,它是 MP 在证明内部运作所需的燃料;A3 说的是「逆否等价」,它把否定与蕴含焊接起来,是反证与经典逻辑的支柱。三条合起来恰好完备——这是上一节完备性定理的一个实例:这套系统能证出全部重言式。
证明。下列五公式构成一个证明序列,每行的身份都注明在括号内。
末行即所求,证毕。∎
这段证明只有五行,却是本章「证明即符号序列」这一观念的极致标本:没有一步依赖「p → p 看起来显然」的直觉,每一步都能被机器按「是公理 / 由前两行 MP」逐字核对。任何一位,只要愿意,都能拿一张纸逐行验收它。亲手对一遍——这是全章唯一一次把「形式证明」四个字落到实处的机会。
有了 ⊢ p → p 与 A1、A2,配上演绎定理(§1.7,其在系统 L 内的证明恰好用到 A1、A2),就能派生出自然演绎里的一切规则。那条为了显示严苛而牺牲可读性的公理路线,就这样与直觉友好的自然演绎路线在同一片天空下汇合。
解。两变元,四行。逐行算:(p,q) = (0,0) 时 ¬p → q 为 1 → 0 = 0、p → q 为 0 → 0 = 1,析取得 1;(0,1) 时两分支皆 1,得 1;(1,0) 时第一支 0 → 0 = 1,得 1;(1,1) 时两支皆 1,得 1。末列全 1。
答。四行皆真,故为重言式。∎
解。用等价律变形,不必列八行表。对左式两次用蕴含改写 α → β ≡ ¬α ∨ β:p → (q → r) ≡ ¬p ∨ (¬q ∨ r) ≡ ¬p ∨ ¬q ∨ r。对右式先用德摩根:(p ∧ q) → r ≡ ¬(p ∧ q) ∨ r ≡ (¬p ∨ ¬q) ∨ r ≡ ¬p ∨ ¬q ∨ r。两式化到同一个析取式。
答。等价。这条等价律在数学写作里叫括号合并(「多前提的蕴含可打包成合取前件」),是化简证明的常备招式。∎
解。真值表四行:(0,0),(0,1),(1,1) 三行取 1,(1,0) 一行取 0。主析取范式取三行极小项之析取:
(¬p ∧ ¬q) ∨ (¬p ∧ q) ∨ (p ∧ q).
主合取范式取取 0 行的极大项:该行 (p,q) = (1,0),取 0 的变元 q 写自身、取 1 的 p 写否定,得 (¬p ∨ q)。
答。主析取范式如上,主合取范式为 (¬p ∨ q)。这条合取子句正是 §1.3 的蕴含改写——范式法竟「自动」发现了等价律:极小项与极大项这两套标准写法,把等价关系完全暴露在纸面上。∎
解。由 §1.5,¬q ≡ q ↑ q,且 p → q ≡ ¬(p ∧ ¬q) ≡ p ↑ (¬q)。代入得 p → q ≡ p ↑ (q ↑ q)。验证:q ↑ q = ¬q,故 p ↑ (q ↑ q) = ¬(p ∧ ¬q) = ¬p ∨ q = p → q。四行代入 (0,0),(0,1),(1,0),(1,1),依次得 1,1,0,1,与蕴含表逐行吻合。
答。p → q ≡ p ↑ (q ↑ q)。整式的每个联结词都换成了 NAND,若画成电路,只需两个与非门。∎
复盘。例 1.38 用真值表、例 1.39 用等价律、例 1.40 用范式、例 1.41 用完备性——本章语义部分的四大件各出一手。做题顺序的纪律是:先估规模(两三个变元就查表,多了就化式),再选工具,能不动真值表就不动。
解。把三段前提依次摆出,再用 MP 两次。
证明序列。① p(前提);② p → q(前提);③ q(由 ①、② 经 MP);④ q → r(前提);⑤ r(由 ③、④ 经 MP)。末项即结论。∎
这正是假言三段论 HS 的「展开版」:p → q 与 q → r 合成 p → r,再与 p 一碰,得 r。把两步写开而不直接引用 HS,是为了示范「每一步都是原始规则」。
解。由演绎定理,只需证 {p ∧ q} ⊢ p。这是一个单步推导:由合取消去(化简规则)∧E,从 p ∧ q 直接得 p。于是 {p ∧ q} ⊢ p,演绎定理回代,得 ⊢ (p ∧ q) → p。
答。证毕。这里体现了演绎定理的省力之处:把「证一个蕴含」换成「假定前件、推出后件」,往往一步到位。∎
解。自然演绎的证法是把假设盒与否定引入拼起来。
答。证毕。这条证明展示了否定引入 ¬I 的标准用法,也解释了反证法为何合法:「假定某式推出矛盾」本身就是「该式的否定成立」的证明。∎
解。用演绎定理把目标拆成两层。目标形如 ⊢ A → (B → C),故只需证 {q → r} ⊢ (p → q) → (p → r);再用一次演绎定理,只需证 {q → r, p → q, p} ⊢ r。后者的证明序列:
答。由演绎定理回代两次,即得所求蕴含式。注意整条链只用了 MP 与演绎定理,而演绎定理在系统 L 内的证明(§1.7)只用到 A1、A2——于是这条「三段论变形」被彻底还原成三条公理与一条规则。∎
复盘。证明题的通用策略是从结论往回看:结论是蕴含就上演绎定理,结论是否定就上否定引入,结论是合取就分开证两半。本题的四道例各自穿过一条通路,做题时应先认路再动笔。
习题 1-1(判类型)。用真值表判断下列公式属于重言式、矛盾式还是可满足式(非重言亦非矛盾):① (p → q) ↔ (¬p ∨ q);② p ∧ ¬p;③ (p ∧ q) → p;④ p ∨ q。
提示。① 把 → 改写成 ¬p ∨ q,左右两式恒同,故为重言式;② 第二、四行分别为 (1,0)、(0,1) 时取 0,全表无 1,为矛盾式;③ 化简规则的公式版,重言式;④ 只在 (1,1)、(1,0)、(0,1) 为 1,非重非矛,是可满足式。
习题 1-2(判等价)。判断下列各组公式是否逻辑等价:① p → (q ∨ r) 与 (p → q) ∨ (p → r);② ¬(p ↔ q) 与 p ⊕ q(异或)。
提示。① 左式 ≡ ¬p ∨ q ∨ r;右式 ≡ (¬p ∨ q) ∨ (¬p ∨ r) ≡ ¬p ∨ q ∨ r——等价。② 写出定义:p ⊕ q := (p ∨ q) ∧ ¬(p ∧ q),四行核对与 ¬(p ↔ q) 逐行相同——等价。这道题说明「异或」就是「等值的否定」,也解释了 §1.13 半加器为何用 XOR。
习题 1-3(求范式)。求 φ = (p ∨ q) ∧ ¬r 的主析取范式与主合取范式。
提示。三变元。φ 取 1 的行是「r = 0 且 p ∨ q 为真」,即 (0,1,0),(1,0,0),(1,1,0) 三行;极小项相析取得主析取范式。取 0 的五行使极大项,可先写出简化 CNF (p ∨ q) ∧ ¬r,再把每个子句补齐缺失变元:p ∨ q ≡ (p ∨ q ∨ r) ∧ (p ∨ q ∨ ¬r),¬r ≡ (p ∨ ¬r) ∧ (¬p ∨ ¬r) 后再补。
习题 1-4(NAND/NOR 化)。只用 ↑ 表示 p ↔ q;只用 ↓ 表示 p ∨ q。
提示。用 §1.5 的三块积木:¬a ≡ a ↑ a、a ∧ b ≡ (a ↑ b) ↑ (a ↑ b)、a ∨ b ≡ (a ↑ a) ↑ (b ↑ b)。先把 p ↔ q 化为只用 {¬, ∧, ∨} 的式子再逐处替换。NOR 侧:a ∨ b ≡ (a ↓ b) ↓ (a ↓ b),两个或非门即可。
习题 1-5(完备性的边界)。证明:仅用 ∧ 与 ∨ 两种联结词不能表达 ¬p,故 {∧, ∨} 不完备。
提示。关键观察:若公式 φ 只由 ∧, ∨ 与变元构成,则它是单调的——把所有变元从 0 改成 1,φ 的值绝不下降。用对构造的归纳证明:变元情形显然;φ ∧ ψ 与 φ ∨ ψ 的单调性由归纳假设直接得到。于是把全部变元取 0,任何这样的 φ 都取 0;而 ¬p 在 p = 0 时取 1——矛盾,故不可表达。本习题的要点是「不完备性」也需证明,用的是单调性这条结构性质。
习题 1-6(形式证明)。给出 {p → q, q → r, r → s, p} ⊢ s 的形式证明,并指出哪一步用了 HS。
提示。序列:① p;② p → q;③ q(MP ① ②);④ q → r;⑤ r(MP ③ ④);⑥ r → s;⑦ s(MP ⑤ ⑥)。若把 ②④⑤ 写成 HS 一步,则「合成链」处用了 HS;两种写法都对,区别只在是否显式引用导出规则。
习题 1-7(演绎定理)。用演绎定理证明 ⊢ (p → (q → r)) → (q → (p → r))(前件交换律)。
提示。两次演绎定理把目标化为 {p → (q → r), q, p} ⊢ r。证明:① p;② p → (q → r);③ q → r(MP ①②);④ q;⑤ r(MP ③④)。回代两次即得。要点:演绎定理允许自由引入与释放假设,但释放的顺序必须与引入相反。
习题 1-8(自然演绎)。证明 ⊢ (p ∨ q) → (q ∨ p)。
提示。由 →I,只需证 {p ∨ q} ⊢ q ∨ p。对 p ∨ q 用 ∨E:分两种情形。情形一(假设 p):由 ∨I 得 q ∨ p;情形二(假设 q):由 ∨I 得 p ∨ q……注意方向,应得 q ∨ p。两情形同得 q ∨ p,故 ∨E 给出结论。核心是 ∨E 的「两情形都得同一结论」纪律:分支里可以各取所需,但出口必须一致。
习题 1-9(公理与导出规则)。在系统 L 中,说明假言三段论 HS 并非必需的原始规则,并给出它的导出思路。
提示。先用 A2 的例式 (q → r) → ((p → q) → (p → r))(见例题 1.45 的完整还原)。给定 p → q 与 q → r 作假设:① 由 A1 得 (q → r) → (p → (q → r));② 用例题 1.45 的式子两次 MP 得 (q → r) → ((p → q) → (p → r));③ 与 q → r 作 MP,再与 p → q 作 MP,得 p → r。要点:一切导出规则都能被还原到 A1、A2、A3 与 MP。
习题 1-10(边界讨论)。已知命题逻辑可判定,一阶逻辑不可判定。解释:为什么 SAT 属于 NP,而「判定任意一阶公式是否有效」不属于 NP?
提示。关键是见证的长度。SAT 属于 NP,因为一个候选指派就是多项式长度的见证,验证只需逐子句核对——「是」答案有多项式可验证的凭证。「一阶有效性」说的是「在所有结构中都为真」,量词允许搜索无穷多的结构,任何有限凭证都无法覆盖全体的检验;更根本地,一阶逻辑的有效性问题(Church–Turing 1936)根本不可判定,而 NP 中的问题都至少是可判定的(做一个穷举总会停)。故一阶有效性连 NP 都进不去。本习题的落点:可判定性(会不会停)与复杂度(多快能判)是两个层次的问题,量词把第一个层次都击穿了。
本章十五节不是平行地摊开的,而是一棵树。箭头 A → B 读作「B 的定义或证明用到 A」。读图时特别盯住居中的那个金色节点——它是全章两条主干的合流处。
通向外部的接口。① 完备性与紧致性 → 第二章一阶逻辑的对应定理(同一套路,量词添乱);② 正规形式与真值表 → 第三章证明论的切割消除(范式化的语法版本);③ 可判定性与 SAT → 第四章可计算性与复杂性(判定性问题在此升级为「不可判定」);④ 形式证明的「可机械检查」→ 第六章证明助手(Lean、Coq 逐行验收)。章内概念树是自足的——读完本章,后五章每一步都能在此找到根系。
本页任务。把 §1.1–1.5 的语义装备压缩成几张随身卡片;语法与元定理的卡片在下页。
一个必背实例。常驻公式 ((p → q) ∧ (q → r)) → (p → r):八行真值表末列全 1,是重言式;它是假言三段论 HS 的公式版,也是本章语义部分的第一个标本。
三个一分钟快检。① 判类型:末列全 1 / 全 0 / 其余;② 判等价:把两式都化成主析取范式比指标集合,或就地用等价律化简;③ 判完备:试着用给定的联结词造出 ¬ 与 ∧,造得出则(多半)完备,造不出要找结构性理由(如单调性)。
下一步。语义篇回答「式子何时为真」,语法篇回答「式子怎样被证」。两篇的最后会证明它们同步——翻页。
本页任务。把 §1.6–1.15 的语法与元定理装备收进卡片,并以方法论的封印收束全章。
方法论的封印。本章全部推理只动四样东西:查表(真值表穷举)、化式(等价律变形)、写序列(形式证明)、造赋值(极大一致集/超滤子)。调用成本依次升高,实战顺序恒定:能查表就查表,查不动就化式,证明题先摆前提,元定理才赋值。这套「成本阶梯」是逻辑工作的纪律。
下一站。把命题变元换成带量词的公式,会发生什么?需要新的公理吗?完备性还成立吗?判定性还守得住吗?——这三个问题就是第二章的全部议程。
本章最深的一课,落在 §1.1 那张小小的蕴含表上。日常语言的「如果……那么……」是有体温的:它暗示因果、暗示时序、暗示说话人的期待。逻辑把它一把夺过来,剥掉全部体温,只留下四行真值——前件假的部分自动为真,前件真时后件的真假决定一切。这一步是形式化的原初暴力,也是之后全部收益的来源。
为什么必须这么狠?因为只有把「如果」压成一个只依赖真值的算子,推理规则才能成立。若「如果」还要看因果,那么由 p 与 p → q 推出 q 就不再是一条定理,而是要看「这段因果成不成立」——推理就被拖进了难以检验的泥潭。逻辑的选择是:牺牲含义的丰富,换取操作的确定。于是「若 2 + 2 = 5,则雪是黑的」被判为真命题——它不好听,但它让整个机器跑了起来。
本章反复出现的两条线,其实是这同一决定的两种回响。语义线把真假铺成真值表,让「恒真」变成可查的名单;语法线把变形铺成规则,让「可证」变成可写的序列。而 §1.9 的健全性与完备性证明:这两条线不是两种意见,而是同一件事的两个出口——能证的恰好就是恒真的。逻辑由此获得它最想要的东西:一部可以被机器逐行核对、却不会说假话的推理机器。
留一个自问:如果「如果」只是一个算子,那么人类在推理时感到的那种「必然性」究竟从哪里来?是来自语言的形状,还是来自我们对世界的经验?本章给了一个技术性的答案——必然性就是「在所有指派下都取 1」。但这个答案是否说尽了「必然」二字,还是只圈定了它的一个可计算的影子?——这是第二、五两章将反复回头追问的问题。
任务。本章的联结词只能谈「真假」,不能谈「所有」「存在」。下一章将加入量词 ∀ ∃,届时就能把整门几何写成公理。本挑战提前预演:为一种最朴素的几何——只有点与直线,只有「点在直线上」一种关系——设计一套一阶公理,并检查它的模型。
语言。取一元谓词 P(x)(x 是点)、L(z)(z 是线),二元谓词 I(x, z)(点 x 在线 z 上);等号 = 可用。函数符号一概不用——几何的朴素关系不必借助作图工具。
分步引导。① 先把参考公理组抄成公式,逐条说明它排除了哪些「退化模型」(例如「所有点都不在线上」的空模型);② 求它的最小模型:直觉上应是「三点不共线、三条线两两相交」的三角形,公式验证三角形满足全部公理;③ 若再加一条射影公理「任意两条不同直线恰交于一点」,模型的形状会怎样变化?有限模型还够用吗?(提示:射影平面 PG(2,2) 恰有 7 点 7 线,正是本文 §1.9 与第二章将重逢的对象。)
进阶(选做)。把这套公理组看成一个理论 T。① 用紧致性(§1.10)的思想讨论:若 T 的每个有限子集都有模型,T 是否有模型?② 查阅资料了解 Tarski 的初等欧氏几何(1948)是全称可判定的:为什么「只有关联关系的几何」比「含实数算术的几何」更容易判定,并把这条直觉记下,第五章与第六章会回来兑现。
实验目的。§1.9 证明了「⊢ φ 与 ⊨ φ 同步」。这句话在纸上是一条定理,在机器上则是一次可以逐条打印的对拍。本实验把两条主干各写成一短段程序:语义侧用真值表枚举判重言式,语法侧把「公式恒真」翻译成「它的否定的合取范式被归结反驳掉」,然后让二者在同一批公式上逐条比对。若完备性定理为真,则两侧的判定必须字字相同。
def to_cnf_clauses(f):
"""¬f 的 CNF 子句集:对每个使 f 为真的赋值,取被它证伪的极大项。"""
vs = sorted(atoms(f))
out = []
for bits in itertools.product([0, 1], repeat=len(vs)):
if eval_f(f, dict(zip(vs, bits))) == 1:
out.append([(v, bits[i]) for i, v in enumerate(vs)])
return out
def resolve(c1, c2):
"""找一对互补文字消去;无互补对返回 None。"""
for lit in c1:
comp = (lit[0], 1 - lit[1])
if comp in c2:
return [l for l in c1 if l != lit] + [l for l in c2 if l != comp]
return None
def refute(clauses):
"""归结闭包:导出空子句即反驳成功(¬f 不可满足)。"""
S = [c for c in clauses if not is_taut_clause(c)]
if not S:
return False
changed = True
while changed:
changed = False
for i in range(len(S)):
for j in range(i + 1, len(S)):
r = resolve(S[i], S[j])
if r is None:
continue
if len(r) == 0:
return True
if r not in S:
S.append(r); changed = True
return False
报告要求。① 给出自选五条公式的两侧判定,注明是否一致;② 说明为什么「使 φ 为真的赋值」生成的是 ¬φ 的子句,而不是 φ 的子句;③ 把第四步的随机测试扩到四条变元,观察归结闭包的规模增长速度,并解释它与真值表 2n 的增长为什么不同。本实验的完整脚本见本章配套的 exp_c1.py。
亚里士多德在《前分析篇》里把三段论拆成格与式,配上换位规则,做成了人类第一套可检查的推理清单。几乎同一时期,东方的名辩之学也在处理「推」这件事,只是走了一条不同的路。《墨经》里的《经上》《经下》《大取》《小取》四篇,留下了一批关于「辩」的条目:有对「故」(理由)与「类」(类推的根据)的讨论,有「以类取,以类予」的推论原则,也有对「悖」的自指警告。战国之世,惠施讲「历物之意」,公孙龙以「白马非马」「坚白离」立说,惠施、公孙龙这一路把概念辨析推到了极限——可惜这些讨论多以具体命题的胜负收场,少有把「推理形式本身」抽出来列为公理的自觉。
古印度的因明学提供了一条更接近形式化的旁证。陈那(约五至六世纪)把旧因明的五段论简化为「三支作法」:宗(待证命题)、因(理由)、喻(同喻与异喻的例证)。《因明入正理论》与《集量论》里对「因三相」的规定,实际上已经在追问「什么样的理由才算有效」,与亚里士多德对中间项的要求遥相呼应。不过因明服务于论辩胜负,讨论大量围绕过失与成立展开,也未能长成一部纯粹的推理演算。
近代的转折靠翻译与重写完成。严复译出《穆勒名学》(1905)与《名学浅说》(1909),第一次把「逻辑」这个学科名搬进汉语;章士钊、金岳霖随后把这个学科带进课堂与自己的体系——金岳霖 1937 年出版《逻辑》,把演绎系统的观念正式引进;沈有鼎 1980 年出版《墨经的逻辑学》,用现代逻辑的眼光回头清点《墨经》里的推理材料。至此两千年悬置的问题有了新的问法:说一种传统「没有形式逻辑」,究竟是说它没有推理,还是说它没有把推理和对象分离?
把这三条线放在一起看,本册后面的路就更好理解了:形式化不是唯一处理「推」的方式,却是一种能让机器接手的处理方式。第三章的相继式演算、第四章的图灵机、第六章的证明助手,都是把「推」的规则从人手里取出来、交给符号去执行的结果;而本页的三条传统提示,这条路上还有别的走法与别的问法。
本页把第一章的全部装备压成一张表:左边是要查的条目,中间是内容,右边标注它第一次出现的位置。复习时先盖住中间一列自查,答不出再回读对应小节。
| 条目 | 内容 | 出处 |
|---|---|---|
| 五个联结词 | ¬ 翻转;∧ 两真才真;∨ 一真即真;→ 只在前真后假时为假;↔ 同真同假才真 | §1.2 |
| 三类公式 | 重言式(末列全 1)、矛盾式(末列全 0)、可满足式(至少一真) | §1.3 |
| 真元数 | 含 n 个变元的公式真值表有 2n 行;n 元真值函数共 22n 个 | §1.3 |
| 等价律 | 德摩根、逆否、蕴含改写 p → q ≡ ¬p ∨ q、分配、吸收、双重否定 | §1.4 |
| 对偶原理 | ∧ ↔ ∨、0 ↔ 1 互换得对偶式;等价式对偶后仍等价 | §1.4 |
| 两种范式 | 主析取范式=真行之积的析取;主合取范式=假行之和的合取;变元固定后各自唯一 | §1.5 |
| 函数完备性 | {¬, ∧, ∨}、{¬, ∧} 皆完备;↑(NAND)、↓(NOR)各自单独完备;{∧, ∨} 不完备 | §1.5 |
| 形式证明 | 公理集 + 推理规则 + 有穷长的公式序列;记 ⊢ φ 为「φ 可证」 | §1.6–1.8 |
| 健全性 | ⊢ φ ⟹ ⊨ φ:证得出的必为真 | §1.9 |
| 完备性 | ⊨ φ ⟹ ⊢ φ:为真的必证得出;与健全性合起来即 ⊢ φ ⟺ ⊨ φ | §1.9 |
| 紧致性 | 公式集有模型的充要条件是其每个有穷子集有模型 | §1.10 |
| 可判定性 | 存在算法在有限步内判定任意公式是否重言——真值表法即是 | §1.12 |
| 归结反驳 | 把 ¬φ 化为合取范式,做归结闭包;导出空子句 ⟺ φ 重言 | §1.9 |
| SAT 与 NP | 判可满足是历史上第一个被证明的 NP 完全问题;P = NP 至今未决 | §1.13–1.14 |
| 五条公理组 | 希尔伯特式公理的常见取法;公理的选取以健全与完备为准,不唯一 | §1.15 |
三句自测。① 拿到一个公式,能在三十秒内用真值表定其类型吗?② 能说出「完备性」与「可判定性」的区别吗(一个是语义与语法的重叠,一个是存在判定程序)?③ 能讲清为什么 {∧, ∨} 造不出否定吗(提示:单调性)?三句都能答,本章的骨架就算立住了。
第一章把「如果……那么」炼成了真值表,于是「这句话在什么情况下为真」可以被穷举。可真值表有一块够不着的天窗:它看不见句子内部。「所有素数都大于 1」与「2 是素数」在命题逻辑眼里只是两个互不相干的代号 p 与 q,而「所以 2 大于 1」这一滑步,真值表永远算不出来——因为「所有」「存在」「大于」这些词根本没有对应的格子。
本章要补上这块天窗,造一门能谈「对象」的语言。办法是加三样东西:名字(常量符号,让语言指称具体对象)、构造(函数符号,让语言拼出新对象)、关系与量词(关系符号判断对象之间的性质,∀ 与 ∃ 说出「对每一个」与「存在一个」)。三样装齐,就得到二十世纪最有用的形式语言——一阶逻辑。它的影响遍及数学基础、程序验证与人工智能,本册余下各章都站在它的地基上。
本章的路线是一道「先语义、后语法、再合流」的台阶,每一级都踩在前一级上:
第一阶(§2.1–2.5)——语义先行。从符号表出发,递归地定义「项」与「公式」,分清哪些变元被量词管住(约束)、哪些还露在外面(自由);再由结构 𝒜 = (A; …) 与解释给出满足关系 ⊨ 的递归条款。这一阶的全部工作,是把塔斯基 1933 年那句「φ 为真当且仅当……」写成一串可以逐条核对的规则。
第二阶(§2.6–2.9)——语法登场,完成会师。列出一套希尔伯特式公理与两条推理规则,定义「可证」⊢;随后证明本章的顶点——哥德尔完备性定理(1929):凡在所有结构中为真的,都能被形式推出。语义与语法这两条平行线,第一次在一阶逻辑里握上了手。它的直接推论是紧致性定理,一台造模型的机器。
第三阶(§2.10–2.16)——装备与实例。处理相等号与商模型,学会把公式拧成前束范式、看清 ∃∀ 与 ∀∃ 谁更强;再把「公理系统」当作研究对象,清点一致性、独立性、完备性、范畴性、可判定性五个元数学概念。最后参观三套真实系统:希尔伯特几何、一阶算术 PA、塔斯基初等欧氏几何,并把群、环、域这些代数公理拿来对照。
第四阶(§2.17 与章末)——算账与动手。清点形式化的代价与收获,做例题、习题、实验,把本章的概念接成一张网。
随身行李只需三件:第一章的真值表、一点集合语言、写递推定义的耐心。行李齐备时直接迈上第一级台阶。出发前先认识本章的常驻嘉宾。
常驻嘉宾:自然数结构 𝒩 = (ℕ; 0, S, +, ·, <)。它是本章出镜率最高的结构——语言最小、性质最深。§2.3 用它演示解释,§2.4 用它算真值,§2.9 用它长出非标准模型,§2.14 把它公理化成一阶算术 PA。它小到可以手算,又深到能承载哥德尔的不完备定理,是全书反复回来的坐标原点。
★★ 造语言的规矩只有一条:先把词汇表定死,再谈句子。一阶语言的词汇表分两栏——任何语言都带的逻辑符号,与这门语言自选的非逻辑符号。
三样非逻辑符号各司其职。常量符号是「专名」,一个符号钉住论域里的某个对象;函数符号是「构造器」,吃进若干对象、吐出一个对象;关系符号是「判词」,吃进若干对象、给出一句可判真假的话。三者在句法上分工,恰好在语义上对应论域里的三类东西(§2.3 把这份对照列成表)。
五门常用语言。记住它们的符号表,本章反复出场。① 算术语言:常元 0,一元函数 S(后继),二元函数 + 与 ·,二元关系 <。② 群语言:二元函数 ·,常元 e,一元函数求逆。③ 序语言:只含二元关系 <。④ 集合论语言:只含二元关系 ∈。⑤ 图语言:只含二元关系 E。语言越瘦,能说的越少——这正是下一节要小心的。
项是「名字」,不是「话」。S(S(0)) 是一个项,它在标准算术结构里指称 2;x + S(0) 也是一个项,指称「比 x 多 1 的那个数」——但「多 1」相对于 x 取什么值而言,要等赋值出场(§2.4)才说得清。项只说「哪个对象」,从不说「真或假」;真假的活儿交给公式(§2.2)。
唯一可读性。项由括号分层,任一符号串至多有一种剖析方式:任何项只有一个语法树。这条「唯一可读性」保证了后面「归纳地定义项的值」不会撞车——凡是递归定义,前提都是每一步的构件唯一。下一节把项装配成公式,并引入本章第一对主角概念:自由变元与约束变元。
★★ 有了名字,就能开口说话。最朴素的一句是「这几个对象满足某关系」,再往上用联结词与量词层层搭积木。本节把「公式」的递归定义写死,并分清哪些变元被量词管住、哪些还露在外面。
自由与约束。量词是「管辖」符号:一旦写下 ∀x,紧随其后的那段公式里 x 的每次出现都被它管住。递归地判定一个变元出现是约束还是自由:① 在 ∀x φ 与 ∃x φ 中,x 的一切出现都约束;② 在原子公式中,一切变元出现都自由;③ 联结词不改变出现方式——¬φ 与 (φ □ ψ) 中,出现保持原样。
四个例子(盯住管辖范围)。① ∀x(x < x + S(0)) 是句子。② x < S(0) 中 x 自由,不是句子。③ ∀x(P(x) → R(x, y)) 中 x 被 ∀ 约束、y 自由——管辖范围在 → 之后依然有效。④ (P(x) ∧ ∃x Q(x)):第一个 x 自由,第二个被 ∃ 约束——同名变元各归其主,它可以在同一公式里「半自由半约束」。
代入与捕获(预告)。把公式 φ(x) 中的 x 换成项 t 记作 φ(t)。若 t 中含变元 y,而 φ 里恰好有管辖 y 的量词,代入后 y 会被「顺手抓走」——这叫变元捕获。安全的代入要求 t 对 x 是可代的,§2.6 的量词公理要靠它,§2.10 与 §2.11 会两次回访这个坑。
下一节把公式放进「结构」里,让这些符号第一次获得意义。
★★ 句法只管符号怎么排,语义要回答符号指什么。这一步由「结构」完成:它给符号表上的每个非逻辑符号指派一个具体的数学对象。
注意两件事。第一,论域非空——否则 ∀ 的条款会变得别扭(§2.4)。第二,关系符号被解释成「有序 n 元组」的集合,因此 R(a, b) 真当且仅当有序对 (a, b) ∈ R𝒜。这是把「是非句」翻译成「属于集」的关键一步,也是塔斯基语义的全部秘密所在。
三个标本。① 标准算术结构 𝒩 = (ℕ; 0, S, +, ·, <):论域是自然数集,S 是后继,+、· 是通常运算,< 是通常顺序。② 实数域 ℛ = (ℝ; 0, 1, +, ·, <):同样一串符号,落到实数上长出完全不同的性质——§2.12 会看到这套公理是「完备、可判定」的。③ 图结构 𝒢 = (V; E):论域是顶点集,E𝒢 是边的有序对集合。
怎样比较两个结构。若两个 L-结构之间有一个双射 h,保常量、保函数、保关系((a1, …, an) ∈ R𝒜 当且仅当 (h(a1), …, h(an)) ∈ Rℬ),则称它们同构,记 𝒜 ≅ ℬ。同构的结构在所有一阶句子面前「同生共死」——这是 §2.12 讨论范畴性时的标尺。
赋值。结构解释了符号,还没管变量。给每个变量指派一个论域中的对象,得到赋值 s : {x1, x2, …} → A。有了结构与赋值,一个项才算「指定了」某个对象。下一节就把结构、赋值与公式三者拼在一起,写下满足关系的递归条款。
★★★ 万事俱备:语言给符号,结构给意义,赋值给变元。本节写下本章最核心的一段机器——塔斯基 1933 年的满足关系 ⊨,它把「φ 在 𝒜 中于赋值 s 下为真」定义成一个纯递归、可逐条执行的程序。
其中 s(x ↦ a) 表示把 x 的值改成 a、其余不变的新赋值。这段定义值得逐行咀嚼:(S1) 把「为真」还原成「有序组属于某集合」,语义问题由此变成集合论问题;(S5)(S6) 是全章的枢纽——∀ 要求对整个论域逐一兑现,∃ 只要求找到一处见证。塔斯基的关键洞察是:量词不是模糊的「所有」,而是「对论域的每个元素做一次检查」这一可执行的指令。真值因此有了不依赖人直觉、只依赖结构的机械判据。
为什么对。对 φ 的结构归纳:项的值只通过自由变元的取值结果影响真假(由 (V1)–(V3)),量词步把 x 的新取值盖掉、不影响其余自由变元((S5)(S6)),归纳假设逐条兑现。∎
句子的真值。句子没有自由变元,由命题 2.8,它的真假与赋值无关,于是可以直接写 𝒜 ⊨ φ,读作「𝒜 满足 φ」或「φ 在 𝒜 中为真」。这颗定心丸是全章的地基:从下一页起,本册谈论的「真」,都是句子在某个结构中的真。
,这台机器在有限论域上完全可执行:逐个元素检查 ∀ 与 ∃,真值必然算得出。可一旦论域无穷,「逐点检查」就成了一件需要无穷多步的事——第 §2.5 节开始,我们的兴趣就转向那些「一步到位、无需逐个检查」也仍然为真的公式。这一转向,正是从「算真值」走向「证明」的起点。
★★ 有了满足关系,就能给「真」分层:有的句子只在一个结构里真,有的在所有结构里真。后者是逻辑学的珍宝,本节的中心概念。
两个立刻的等式。① ⊨ φ 当且仅当 ∅ ⊨ φ——有效式是「无前提的后承」。② Γ ⊨ φ 当且仅当 Γ ∪ {¬φ} 不可满足——后承问题可以翻译成可满足性问题,后者是模型论的通用「证件」。这条翻译会在 §2.8、§2.9 反复出场。
为什么「有效」比「碰巧为真」珍贵。「2 是素数」在 𝒩 里真,换个结构就未必;而 ∀x(P(x) → P(x)) 在任何结构、任何解释下都真——它真得与符号的含义无关,只与符号的形状有关。有效式因此是可被纯符号规则认出的真,这条路直通下一节的「证明」。
与第一章的分水岭:命题逻辑的有效式可以靠真值表逐行穷举判定;一阶逻辑没有等价的真值表(论域可无穷)。它失去判定的捷径,却换来「表达一切数学结构」的能力——这笔交易是否值得,带着问题读下去。
★★★ 语义说「什么为真」,语法说「什么推得出」。本节立下一套极简的推理装置:几条公理模式加两条规则。它的部件越少,后面的完备性证明就越干净。
五行足矣。① (φ → ((φ → φ) → φ)) → ((φ → (φ → φ)) → (φ → φ))——(A2) 取 ψ := φ → φ、χ := φ。② φ → ((φ → φ) → φ)——(A1) 取 ψ := φ → φ。③ (φ → (φ → φ)) → (φ → φ)——①②经 MP。④ φ → (φ → φ)——(A1) 取 ψ := φ。⑤ φ → φ——③④经 MP。∎
可靠性的预告。这套装置有一条底线:凡公理都有效、两条规则都保有效性。公理 (A1)–(A3) 是命题重言式的模式,(Q1)(Q2) 在 §2.5 例 2.11 已验证有效;MP 保真、Gen 在任意赋值下保真。故结论:若 ⊢ φ 则 ⊨ φ(可靠性,§2.8 正式陈述)。语法难不倒语义——真正惊人的是反方向也成立,那是 §2.7 的正戏。
也许已经在抱怨:证明 φ → φ 竟然要五行,而它「显然」成立。这个抱怨——它正是 §2.17 讨论形式化代价的起点。眼下先忍住,去看这台笨机器如何造出一件惊人的成就。
★★★★ 全章顶点。它说:语义给的东西,语法全都够得着。凡在一切结构中为真的,都能被形式推出。证明的思想只有一句话——把一个一致集「喂」成自己的模型。
证明。本章只讨论可数语言(符号可数),不可数情形留待更专门的处理。全程只用「把 Γ 撑大」这一个动作。
★★★ 上一节的技术成果,一转身就变成一条极简的元定理:语法上不矛盾,语义上就住得下。一致与可满足,是一枚硬币的两面。
证明。(⇐ 可满足 ⟹ 一致)这就是可靠性:设 𝒜 ⊨ Γ。公理 (A1)–(A3)、(Q1)(Q2) 都在一切结构中为真(§2.5 例 2.11、§2.6),而 MP 与 Gen 把真句子送到真句子。由归纳,证明的每一行都在 𝒜 中为真,故 Γ ⊢ φ 蕴含 𝒜 ⊨ φ。特别地不可能从 Γ 证出矛盾(矛盾句无处为真),故 Γ 一致。(⇒)这正是定理 2.16。∎
证明。(⇒ 可靠性)由定理 2.17 前半证的同一归纳。(⇐ 完备性)设 Γ ⊨ φ。若 Γ ⊬ φ,则 Γ ∪ {¬φ} 一致,由定理 2.17 有模型 𝒜 ⊨ Γ ∪ {¬φ},这与 Γ ⊨ φ 相矛盾。故 Γ ⊢ φ。∎
两句话记住这张图。可靠性说「⊢ 不越界」:能推的都是真的;完备性说「⊢ 不遗漏」:真的都能推。⊢ 与 ⊨ 之间的关系,不是包含,而是相等。这是命题逻辑第一章「语义=语法」会师的升级版——这一次,语言能谈对象、能量化,会师依然成立。
特别分清两件常被混为一谈的事:本节的完备性是「语言对世界完备」(为真即可证);第五章的不完备性是「理论对真理不完备」(存在既不可证也不可否证的句子)。前者是一个结构对一切理论成立的正面定理,后者是足够强的理论自身的局限——一正一反,正是本册最需要分清的对照。
★★★ 完备性定理有一件副产品,看似技术、实则威力无穷:只要每一小撮公理都能被满足,整堆公理就能被同时满足。局部可行,则整体可行——这条「紧致」,是造模型的第一利器。
证明。(⇒)若 𝒜 ⊨ Γ,则 𝒜 显然满足任一有限子集。(⇐)设每个有限子集都有模型,要证 Γ 可满足。反设 Γ 不可满足,由定理 2.17 它不一致,即 Γ ⊢ ⊥。任何证明只用到有限多条前提,故存在有限子集 Γ0 ⊆ Γ 使 Γ0 ⊢ ⊥,即 Γ0 不一致;又由定理 2.17,Γ0 不可满足——与「每个有限子集有模型」矛盾。故 Γ 有模型。∎
证明的关键只有一句:证明是有限的。矛盾若要出现,必由有限多条前提促成——这条「有限性」正是「紧致」二字的来源:无穷多条件被判为整体可行,只因它的每一小块都可行。
两个连锁推论。① 「有限性」不可一阶刻画:若一组句子只在有限结构里真,则由「每个有限子集有模型」将给出无穷模型,矛盾——故不存在一阶句子集恰好刻画「论域有限」。② 无穷论域不可被单个句子锁死大小:任何有任意大有限模型的理论,必有无穷模型。这条推论的普遍形状是:紧致性把「所有有限情形都成立」自动升级为「无穷情形也成立」,代价是模型里多出「非标准」的元素。
紧致性属于「语法定理造出的语义工具」,它对本册后文的重要性无论怎样强调都不过分:§2.12 用它证明公理独立,第五章用它讨论不可判定与独立性,第六章用它构造出人意料的模型。把「有限子集」与「整体」在脑中并置,随时准备用一次紧致性完成从局部到全局的跳跃。
★★★ 数学里最常用的符号是 =。可「相等」在一阶语言里既不是常量、也不是函数或关系符号——它是逻辑符号,需要自己的公理。本节讲清相等号怎么被规则管住,以及它如何反过来帮我们造模型。
为什么替换性这么强。(E2) 说的不是「= 是个等价关系」,而是「= 在任何语境中都不可分辨」:对象一旦相等,就再也无法用语言把二者分开。这条「不可分辨者同一」的原理,是数学里把「同一个东西」写进符号的正式语法。
证明思路。把每个元素换成它所在的等价类;函数与关系在类上重新定义,相容性保证定义不依赖代表的选择(这正是「良定义」)。然后对 φ 归纳:原子公式的每个元解释都被类替换,真值不变;联结词与量词沿归纳假设平移。∎
回到完备性证明。§2.7 第五步的项模型正是本定理的一次壮丽应用:那里的 ∼ 由 (t = u) ∈ Γ* 定义,论域就是项的等价类。语法世界里的「相等」被商成了语义世界里的「同一」——这一步若不做,项模型里会出现「两个不同的项却相等」的尴尬。
方法论小结。等号在一阶逻辑里有双重身份:作为被公理管住的符号((E1)(E2)),它保证替换与推理干净;作为被商掉的冗余(定理 2.23),它让「伪模型」总能归正。两条合起来,是本章一切模型的卫生标准。
★★ 量词一旦叠起来,次序就成了门户。本节先把量词统统拧到公式最前(前束范式),再逐一清点:哪些次序可以互换、哪些一旦互换就变弱。
证明思路(一组重写规则)。① 改名:有界变元可换成不曾出现的新名,避免冲突;② 对偶:¬∀x φ ≡ ∃x ¬φ、¬∃x φ ≡ ∀x ¬φ;③ 提出量词(当 x 不在 ψ 中自由):(∀x φ) ∧ ψ ≡ ∀x(φ ∧ ψ),(∀x φ) ∨ ψ ≡ ∀x(φ ∨ ψ),(∃x φ) ∧ ψ ≡ ∃x(φ ∧ ψ),(∃x φ) ∨ ψ ≡ ∃x(φ ∨ ψ);对 → 则视方向把量词对偶地推到另一侧。反复应用,量词逐个外提,直到全部落在最前。∎
(i) 同类量词可换:∀x∀y φ ≡ ∀y∀x φ,∃x∃y φ ≡ ∃y∃x φ。
(ii) 混合量词只有单向后承:∃y∀x φ ⊨ ∀x∃y φ,但反方向不成立。
证(i)。两者都等价于「对一切 (a, b) ∈ A × A 都有 φ 成立」——由 (S5)(S6) 展开,两次全称量词只关心「每个元素各取一次」,与先后无关;存在量词同理由「有一处见证」对称。∎
证(ii)与反例。先证后承:设 ∃y∀x φ 在 𝒜 中真,则存在 b ∈ A 使 ∀x φ[y ↦ b] 真;于是对一切 a 都有 φ[x ↦ a, y ↦ b] 真,特别对每个 a 都找到同一个 b 作见证,故 ∀x∃y φ 真。反过来不行:取 𝒜 = 𝒩、φ := (x < y)。句子 ∀x∃y(x < y) 真——每个自然数都有更大的数;而 ∃y∀x(x < y) 假——没有比所有自然数都大的自然数。前者有一个见证随 x 变化,后者要求一个见证一劳永逸:这正是两种次序的全部差别。∎
记忆口令。「存在一个万能的」蕴含「各人都有各自的」,反之不然。把这句话和 §2.7 见证性质对照:Henkin 常元之所以必要,正因为 ∃x 的见证可能随机而异,不允许一个常元包打天下。
★★★ 前三章反复说「公理」「理论」「模型」,本节把话说全:评价一套公理系统,有五个标准问题。它们是元数学的仪表盘,也是本册后续所有「某某定理不可证」讨论的词汇表。
方法一:独立性的模型法。要证 A 独立于 T ∖ {A},只需造出一个模型使 T ∖ {A} 为真而 A 为假——由完备性,T ∖ {A} ⊬ A。这就是「相对一致性」:要证「A 反了也不出矛盾」,就把「¬A」摆进一个具体世界里展览。
方法二:范畴性与完备性的区别。二者极易混淆。范畴性谈「模型之间像不像」,完备性谈「句子能不能判」。一阶逻辑里,范畴性极难:由紧致性,任何有无限模型的一阶理论都有非标准模型(§2.9),故一阶理论几乎不范畴;而二阶逻辑可以做到范畴(如二阶算术的唯一模型),代价是失去完备性。这条「范畴性↔完备性」的跷跷板,是一阶逻辑设计的根本取舍。
可判定性的两个极端。命题逻辑可判定(真值表);一阶逻辑不可判定(丘奇–图灵 1936,第四章)。但个别理论仍可判定:无等号的一元关系理论可判定、实闭域理论可判定(塔斯基 1948)。语言的强弱与可判定性成反比——这条规律是第四章的中心议题。
★★★ 1899 年,希尔伯特出版,把欧几里得两千年来「看图说话」的几何,重写成一套严格的公理系统。它是一阶逻辑最早的、也是最著名的实例之一。
希尔伯特只放三个原始概念:点、直线、平面;只放三种原始关系:关联(在……上)、介于(在……之间)、合同(全等)。其余一切几何概念,都要靠这六个词与五组公理定义出来。五组如下。
三处用心,值得逐一指出。其一,原始概念被刻意「留白」:公理不给点和直线下定义,而是隐定义——任何满足这五组的对象系统都叫「几何」,点线可以不是直觉里的点线。其二,平行公理自成一组:把它换成「过外点至少两条平行线」,得到双曲几何;换成「没有平行线」,得到椭圆几何——三种几何共用其余四组公理,由模型法(§2.12)证明第五公设独立。其三,连续公理把「数」请进几何:V1 让线段可以拿整数去量,V2 保证直线上不多不少——这两条使实数模型 ℝ2 成为几何的「标准解」。
史实补注:希尔伯特的原书还含用于空间情形的关联公理 I4–I8,通常与 I1–I3 合称为「关联组」。本页按平面几何列出十六个基本条款,它已足够支撑欧氏平面几何的绝大部分定理。
★★★ 几何之外,另一套最重要的实例来自数论:把自然数的全部性质编成一阶公理,得到的系统叫皮亚诺算术(PA)。它短小、著名,且藏着本册最重要的一处陷阱。
PA 的语言只含常量 0、一元函数 S(后继)、二元函数 + 与 ·、二元关系 <。公理共七条(其中第七条是一个模式)。
陷阱就在这里。(P7) 不是一条公理,而是一族:语言里有多少个公式 φ,就有多少条归纳公理——无穷多条。因此 PA 不能被有限多条公理替换:任何有限的公理集,只要在 𝒩 中为真,就还容许非标准模型(由紧致性,§2.9)。这是「无穷公理模式」与「有限公理」的分水岭。
很多模型,一个标准。标准结构 𝒩 当然是 PA 的模型;但 §2.9 造出的非标准模型 ℳ 也是。于是 PA 不范畴(模型不同构),也不完备(存在句子在 𝒩 真而在 ℳ 假,故 PA 判不出它——这是第五章哥德尔不完备性的雏形)。𝒩 的特殊在于它是所有模型里「最小的」:它是 PA 的标准模型,其余都在它头上长出无穷大元素。
把三套实例并置,可见一阶逻辑的三种姿态:几何公理描述关系(点线关联),PA 描述运算(后继、加乘),两者都是一阶理论的实例。下一节补上第三套——塔斯基的初等欧氏几何,它把几何几乎整个装进一阶语言。
★★★ 希尔伯特把几何公理化,却仍站在集合论的台阶上;塔斯基追问更进一步的问题:几何能不能整个装进一阶逻辑——不用「点集」「子空间」,只用一阶量词?答案是可以,而且这个一阶理论既完备又可判定。
塔斯基(1926 年起,1951 年发表)的方案极其克制:论域就是「点」,原始关系只留两个——介于 β(x, y, z)(y 在 x 与 z 之间)与等距 δ(x, y, z, u)(线段 xy 与 zu 一样长)。仅此二词,就能定义线段、直线、角、全等、圆,乃至一切初等几何概念。
与希尔伯特的关键差别。希尔伯特把「连续」写成一条关于点集的公理,那是二阶的;塔斯基把它拆成无穷多条一阶模式,于是整个理论落在完备性定理的势力范围内。塔斯基 1948 年证明:初等欧氏几何是完备且可判定的——存在一台机器,对任何几何命题判定其真伪。这与 PA 的不可判定形成刺眼对比(§2.16 会解释为什么)。
实闭域模型。标准模型是平面 ℝ2:点是有序实数对,β 与 δ 按通常欧氏几何解释。更一般地,任何实闭域 K(如实数、实代数数)的 K2 都是模型。塔斯基理论的完备性,本质上是「实闭域理论完备」的几何翻译——这条翻译通道,下一节会再次走上。
★★ 把本章的三套几何实例与代数里最常见的三类结构并置,会照出一件深刻的事实:同是一阶理论,「能说什么」的差异决定了「能判定什么」。
代数与几何,两种「原始概念」。代数理论的原始符号是函数(运算),几何理论的原始符号是关系(点线的位置)。这一差别看似只是记号口味,实则决定了可处理性:函数结构允许我们把项写成一串运算,于是代数判断常能归约为解的消去;关系结构则更贴近几何,但一阶表达力也随之改变。
| 结构类型 | 原始符号 | 语言性质 | 可判定性 |
|---|---|---|---|
| 群 | ·, e, 逆 | 有限可公理化 | 字问题可判定;一般句子等式理论可判定 |
| 环 | +, ·, 0, 1 | 有限可公理化 | 一般环理论不可判定 |
| 实闭域(塔斯基几何) | +, ·, <, 0, 1 | 有量词消去 | 可判定(塔斯基 1948) |
| 一阶算术 PA | 0, S, +, · | 非有限可公理化 | 不可判定(丘奇 1936) |
一条分界线:量词消去。实闭域之所以可判定,是因为它能消去量词:理论中每个公式都等价于一个不含量词的公式(由多项式等式与不等式拼成)。一旦量词消失,真值就变成代数方程组的可解性,判定便有了算法。PA 缺的正是这个——它的量词无法被有限地消除,算术的表达力又刚好够编码「可证性」本身(§第五章),于是掉进不可判定。可判定与不可判定之间的那道墙,就立在量词能否被消去上。
历史与工程注记。群论的字问题(判定两词是否代表同一元素)由 1955 年 Novikov 与 1958 年 Boone 独立证否——存在有限呈示的群其字问题不可判定;而交换群的字问题可判定。这再次印证本节的主线:结构越「狭窄」,判定越有希望;结构越「自由」,判定越渺茫。
★★ 本章走了很长的路:从符号表到满足关系,从希尔伯特系统到完备性。收束之前,值得停下来算一笔总账:把数学塞进形式系统,究竟付出了什么、又拿回了什么?
代价之一:冗长。形式证明不允许跳过任何一步。§2.6 里「φ → φ」要写五行;怀特海与罗素《数学原理》(1910–1913)中「1 + 1 = 2」的证明要熬到第 379 页(编号 110·643),还附一句著名的评论:这个命题「偶尔有用」。形式证明的长度与人的直觉严重脱节。
代价之二:直觉被抹平。形式语言只说它能说的事。几何直觉里「两点之间直线最短」的图画感,在一阶公理中化为一段无图像的符号串;「显然」二字在形式证明里没有位置——每一步都要报出公理或规则的名字。这份迂腐,正是 §2.17 想让人亲眼看见的。
收获之一:无歧义与可检查。形式化把「这句话什么意思」的争论,换成「这串符号合不合规则」的机械核对。证明对象一旦写全,正确性就变成可被机器逐行验证的性质——这是第六章 Coq、Lean 得以存在的全部前提。
收获之二:元定理成为可能。正因为系统被写死,才能对系统本身发问并作答:本章的完备性、紧致性,以及每一个「独立」「不可判定」结论,都建立在形式化的基础上。没有形式化,就没有「某某定理不可证」这类断言——因为「可证」这个词还没有定义。
收获之三:统一。几何、算术、群环域,统统落入同一套语言与语义。公理化方法由此显形为三步:用公理隐定义概念(点线不必是直觉的点线)、用模型给公理找解释(相对一致性)、用证明论审问系统本身(独立性、完备性、可判定性)。第三步正是本册后四章的全部内容。
本章到此收束。三条主干已经立好:语义(结构与 ⊨)、语法(公理与 ⊢)、会师(完备性 —— 二者相等)。下一章把镜头对准「证明本身」:它长什么样、如何化简、与程序有何关系。在那之前,先做例题与习题,把这些机器亲手转一遍。
例题 2-1(在结构中算真值)。取标准算术结构 𝒩 = (ℕ; 0, S, +, ·, <)。判断下列句子的真值:① ∀x∃y(x < y);② ∃y∀x(x < y);③ ∀x(x < S(x))。
解。① 真。任给 x,取 y = S(x) 即得 x < x + 1。② 假。若存在 y 大于一切自然数,取 x = S(y) 便矛盾——没有最大的自然数。③ 真。对每个 x,x 小于它的后继,由 (S5) 逐点兑现。注意①②的真假相反:两者只差量词次序(§2.11)。∎
例题 2-2(判断有效式)。判断 ⊨ ∀x P(x) → P(c)(c 为常量符号)是否成立。
解。成立。设 𝒜 是任一结构、s 是任一赋值,且 𝒜 ⊨ ∀x P(x)[s]。由 (S5),对一切 a ∈ A 有 𝒜 ⊨ P(x)[s(x ↦ a)];特别地取 a = c𝒜,得 𝒜 ⊨ P(c)。因 𝒜 任意,故 ⊨ ∀x P(x) → P(c)。∎ 注:证明用到论域非空(否则 c𝒜 可能不存在);这正是定义 2.5 逼论域非空的回报。
例题 2-3(自由变元的清点)。公式 φ := ∀x(P(x) → R(x, y)) ∧ ∃y Q(y) 是句子吗?若不是,写出它的全部自由变元。
解。不是句子。逐处清点:∀x 管辖 (P(x) → R(x, y)),其中两处 x 均被约束,y 在此自由;∃y 只管辖 Q(y),其中 y 被约束。故自由变元集为 {y}(来自 R(x, y) 中的那个 y)。同名 y 一处自由、一处约束——§2.2 的管辖规则在此登场。∎
例题 2-4(有限结构上手工判真)。取论域 A = {0, 1},二元关系符号 R 解释为「不相等」:R𝒜 = {(0,1), (1,0)}。判断 ∀x∃y R(x, y) 与 ∃y∀x R(x, y) 的真值。
解。逐个元素验证。① ∀x∃y R(x, y):x = 0 时取 y = 1;x = 1 时取 y = 0——两处都有见证,故真。② ∃y∀x R(x, y):若 y = 1,需 R(1, 1) 真,但 (1,1) ∉ R𝒜,失败;若 y = 0,需 R(0, 0) 真,失败。故假。两个句子真假相反,再次印证 ∀∃ ⊭ ∃∀。∎
例题 2-5(推演:量词分配)。在希尔伯特系统中证明 Γ ⊢ ∀x Q(x),其中 Γ = {∀x(P(x) → Q(x)), ∀x P(x)}。
解。给出一行行可核对的推演(每步注明依据):
答。推演成立,Γ ⊢ ∀x Q(x)。∎ 复盘:Gen 的使用有条件——x 不得在前提中自由,否则会把「前提对某个特定的 x 成立」误抬成「对一切 x 成立」。此处前提是句子,条件满足。
例题 2-6(定理:假言三段论)。证明 ⊢ (φ → ψ) → ((ψ → χ) → (φ → χ))。
解。先用演绎定理(可由 (A1)(A2) 证明的元定理:若 Γ, φ ⊢ ψ 则 Γ ⊢ φ → ψ)。在 Γ = {(φ → ψ), (ψ → χ)}、假设 φ 下推演 χ:① φ(假设);② φ → ψ(前提);③ ψ(①② MP);④ ψ → χ(前提);⑤ χ(③④ MP)。故 (φ→ψ), (ψ→χ), φ ⊢ χ。对 φ 用一次演绎定理得 (φ→ψ), (ψ→χ) ⊢ φ → χ;对 (ψ→χ) 再用一次得 (φ→ψ) ⊢ (ψ→χ) → (φ→χ);最后对 (φ→ψ) 用一次,即得 ⊢ (φ→ψ) → ((ψ→χ) → (φ→χ))。∎
例题 2-7(紧致性的应用)。证明:不存在一组一阶句子 T,使 𝒜 ⊨ T 当且仅当 A 有限(即「有限性」不可一阶刻画)。
解。反设这样的 T 存在。对每个 n ≥ 1 令 σn 表示「至少有 n 个不同元素」:∃x1…∃xn ⋀i<j xi ≠ xj。考虑 T′ = T ∪ {σn : n ≥ 1}。任取 T′ 的有限子集,它只含有限多个 σn,取一个够大的有限结构即可同时满足 T 与这些 σn。故每个有限子集有模型,由紧致性 (定理 2.20),T′ 有模型 ℬ;但 ℬ ⊨ σn 对一切 n,故 B 无限,于是 ℬ ⊨ T 却有无限论域——与 T 只容许有限模型矛盾。∎
例题 2-8(换序的另一方向)。判断 ∃x∀y R(x, y) → ∀y∃x R(x, y) 是否有效。
解。有效。设 𝒜 ⊨ ∃x∀y R(x, y)[s],则由 (S6) 存在 a ∈ A 使 𝒜 ⊨ ∀y R(x, y)[s(x ↦ a)],即对一切 b 有 𝒜 ⊨ R(x, y)[s(x ↦ a, y ↦ b)]。于是对每个 b,取 x = a 作为见证,便有 𝒜 ⊨ ∃x R(x, y),从而 𝒜 ⊨ ∀y∃x R(x, y)[s]。因 𝒜, s 任意,故该式有效。∎ 注:换个变量名看,这正是 §2.11 的 ∃∀ ⊨ ∀∃;反方向由例题 2-4 的两个句子真假相反而失败。
习题 2-1(热身·清点变元)。指出下列公式的全部自由变元,并判定哪些是句子:① ∀x(P(x) → R(x, y));② ∃x R(x, x) ∧ ∀y S(y);③ P(x) → ∀x P(x)。
提示。① y 自由(x 被 ∀ 约束),不是句子。② 两处量词各自管住 x、y,无自由变元,是句子。③ 前半的 x 自由、后半的 x 被 ∀ 约束——量词只管到紧随的小公式,管不到前面的 P(x);故自由变元为 {x},不是句子。答案要点:先画管辖范围,再逐处标记。
习题 2-2(有限结构判真)。取论域 A = {0, 1, 2},二元关系符号 < 解释为通常的小于。判断:① ∀x∃y(x < y);② ∃x∀y(y < x ∨ y = x)。
提示。① x = 2 时找不到更大的 y,故假。② x = 2 时对 y = 0, 1, 2 都有 y < 2 ∨ y = 2,故真(2 是最大元)。答案要点:有限论域上,∀ 逐个兑现、∃ 找一个见证,必能算完。
习题 2-3(有效或反驳)。判定下列公式是否有效,有效者说明理由,无效者给出反例结构:① ∀x(P(x) ∨ Q(x)) → (∀x P(x) ∨ ∀x Q(x));② (∃x P(x) ∧ ∃x Q(x)) → ∃x(P(x) ∧ Q(x))。
提示。两者都无效,同一结构同时反驳:取 A = {0, 1}、P𝒜 = {0}、Q𝒜 = {1}。则① 前件真、后件假;② 前件真(两类各非空)、后件假(无一元素同时属于两类)。答案要点:全称对 ∨ 不分配、存在对 ∧ 不分配。
习题 2-4(次序反例)。给出一个结构使 ∀x∃y R(x, y) 真而 ∃y∀x R(x, y) 假;再判断 (∃y∀x R(x, y)) → (∀x∃y R(x, y)) 是否有效。
提示。取 𝒩 = (ℕ; <):前者每个数都有更大的数(真),后者要求一个数大过一切数(假)。第二问有效——同一个见证 b 自然可以给每个 x 用(§2.11 (ii))。答案要点:强弱只在一处——见证能否随 x 变化。
习题 2-5(翻译成可满足性)。利用「Γ ⊨ φ 当且仅当 Γ ∪ {¬φ} 不可满足」,判定 {∀x P(x)} ⊨ P(c) 是否成立。
提示。检查 Γ′ = {∀x P(x), ¬P(c)}。若 𝒜 ⊨ ∀x P(x),由 (S5) 对一切元素(含 c𝒜)都有 P 真,故 𝒜 ⊭ ¬P(c)——两个句子不可能同时满足,Γ′ 不可满足,故后承成立。答案要点:把「蕴含」翻译成「反面不可满足」,是语义证明的通用套路。
习题 2-6(推演·∀ 对 → 的分配)。在希尔伯特系统中证明 {∀x(φ → ψ)} ⊢ ∀x φ → ∀x ψ。
提示。先用 (Q1) 从前提得 φ → ψ(t = x);再证 ∀x φ ⊢ φ((Q1)),两次 MP 得 ψ,一次 Gen 得 ∀x ψ;最后用演绎定理收口。注意 Gen 要求 x 不在前提 {∀x(φ→ψ), ∀x φ} 中自由——两者皆句子,合法。答案要点:这与例题 2-5 是同一台机器,只是把 P, Q 换成一般公式。
习题 2-7(紧致性·任意大的有限模型)。证明:若一组句子 T 有任意大的有限模型(对每个 n 都有一个基数 ≥ n 的模型),则 T 有无穷模型。
提示。照抄例题 2-7 的骨架:令 σn 表示「至少 n 元」,考察 T ∪ {σn : n ≥ 1}。任一有限子集只需有限多条 σn,由一个够大的有限模型满足;紧致性给出整体模型,其论域无限。答案要点:「任意大有限」+ 紧致性 =「无穷」,这一步是造非标准模型的通用发动机。
习题 2-8(模型法·证明独立)。说明乘法交换律 ∀x∀y(x · y = y · x) 独立于其余群公理。
提示。用模型法(§2.12):找一个满足群公理但乘法不交换的结构。可取 S3(三个字母的置换群)或 2 × 2 可逆实矩阵在乘法下——它们都是群,却存在 g · h ≠ h · g。答案要点:一个反模型(交换律假、其余真)即证明独立;由完备性(定理 2.18),「证不出」等价于「有反模型」。
习题 2-9(商模型)。设伪结构论域 {a, b, c},把 = 解释为等价关系:a ∼ b、c 单独成类;关系 R 与 ∼ 相容。写出商模型 𝒜/∼ 的论域与元素个数。
提示。等价类为 [a] = {a, b} 与 [c] = {c},商论域 A/∼ = {[a], [c]},共 2 个元素。相容性保证 R 在类上良定义。答案要点:商模型把「伪相等」压成同一,元素数从 3 降到 2——正是 §2.7 项模型的微缩版。
习题 2-10(综合·非阿基米德有序域)。用紧致性证明:存在一个包含「无穷小」的有序域。
提示。取有序域公理(含 ∀x(x > 0 → ∃y(y · x = 1)) 等)并加一新常元 c,公理集 T = 有序域公理 ∪ {0 < c} ∪ {c < n : n 为正整数}(n 指 1 + 1 + … + 1)。任一有限子集在有理数域 ℚ 中取 c = 1/(nmax + 1) 即可满足;紧致性给出整体模型 ℳ,其中 c 正且小于一切正「整数」——一个无穷小。答案要点:把「无穷小」写成一族不等式,再用紧致性一次性满足全部。
本章十六节不是平铺的清单,而是一条「符号 → 语义 → 语法 → 会师 → 实例」的链路。本页把依赖关系画出来:箭头 U → V 读作「V 的定义或证明要用到 U」。
通向外部的接口。① 完备性与紧致性 → 第五章(不可判定与独立性的论证工具);② 证明与规则 → 第三章(证明论:相继式、切割消除);③ 有效式的判定 → 第四章(丘奇–图灵:一阶逻辑不可判定);④ 三套公理系统 → 第六章(证明助手里的形式化几何与算术)。章内链路是自足的;读完本章,后续四章的每一步都能在此找到根系。
本页任务。把语义线(§2.1–2.5)压成四张随身卡片;语法线在小结(下)。
三个必背实例。① 𝒩 = (ℕ; 0, S, +, ·, <)——标准算术;② ℛ = (ℝ; 0, 1, +, ·, <)——实闭域,几何的算术后台;③ 𝒢 = (V; E)——图结构,最小的关系结构。三者的共同点:都是一阶语言的结构;不同点:可判定性命运各异(§2.16)。
本页任务。把语法线(§2.6–2.17)与三套实例压成卡片与一张总表。
| 比较项 | 语义侧 | 语法侧 |
|---|---|---|
| 核心记法 | ⊨(满足 / 后承) | ⊢(可证) |
| 核心对象 | 结构 𝒜 与赋值 s | 证明(有限公式序列) |
| 奠基定理 | 塔斯基满足定义(1933) | 希尔伯特公理系统 |
| 会师 | 哥德尔完备性(1929):⊨ φ ⟺ ⊢ φ | |
| 首要推论 | 紧致性(造模型) | 一致性(⊬ ⊥) |
易错三坑。① 把 ∀∃ 与 ∃∀ 混为可交换(§2.11 反例就在 𝒩 里);② 忘记论域非空(否则 (Q1) 与例 2.11 失效);③ 把本章的完备性(语言对世界完备)与第五章的不完备性(理论对真理不完备)混为一谈——前者是正面定理,后者是局限结论。下一步:衔接讲义把「证明」本身摆上解剖台。
本章最深的一课,是把两个日常词锻造成算子。一个是「如果」:它本是因果、建议、承诺的语气词,一阶逻辑却把它钉成一个真值算子 →——只要前件假或后件真,整个蕴涵就为真,语气与语境一概不论。另一个是「对一切」与「存在」:它们不再停留在修辞的强调,而是两个逐步的算子 ∀ 与 ∃,在论域上逐点兑现、或指名找一个见证(§2.4 的 (S5)(S6))。这一步一旦迈出,一句话的真假就不再依靠说话人的口吻,而能被一台机器按结构逐条核对。
把词变成算子的收益,本章已经结清两笔。语义侧,符号表 → 项 → 公式 → 结构 → 满足,塔斯基的递归定义把「真」一层层定义到底(§2.1–2.5);有效式与逻辑后承,都是在这个定义上继续分层。语法侧,几条公理模式加两条规则 MP、Gen,就把「推得出」写成一份可检查的有限序列(§2.6)。两条线本来各走各路,却在完备性定理处会师:Γ ⊨ φ 当且仅当 Γ ⊢ φ(§2.7–2.8)。会师之所以可能,正因为「如果」是可以被规则搬运的算子——它的每一次搬运都写得下来、查得清楚。这道会师把「真」从一个悬在半空的名词,变成一条可以两头对照的等式。
会师还留下一件副产品:紧致性(§2.9)。局部可行则整体可行,这句话背后的道理很朴素——证明是有限的,所以矛盾也只能由有限多条前提促成。非标准模型、有限性不可一阶刻画,都是从这台「有限 ⇒ 无穷」的升格机里长出来的。它提示:会师不是两条线偶然重合,而是「词被算子化」之后必然的收束。但也应看清代价:「如果」压成 →,丢掉了因果与模态;「对一切」压成 ∀,丢掉了「实际上」「大致上」这类颗粒更细的量化。换回来的,是可判定、可检查、可交给机器执行。
留下的自问:把「如果」压成算子、把「对一切」压成 ∀,究竟失去了什么,又挽回了什么?数学用近一百年回答了前半——失去的是语用,挽回的是确定;但后半仍未封口:当机器判断真假,它判断的是哪一种「真」?带着这一问往下读,第三章会把「证明」本身摆上解剖台,看清算子与证明之间那台更深的机器。
任务。用一阶语言 L = {P, L, I}(P(x) 读作「x 是点」,L(x) 读作「x 是线」,I(x, y) 读作「x 在 y 上」)写一组公理,刻画射影平面的关联结构;再把它改造成仿射平面;最后讨论这套语言说不了什么。这是本章三套公理系统(§2.13–§2.15)的一次亲手复演。
第一步:写公理。射影平面的经典刻画只需三条:P1 任意两个不同的点恰在一条公共线上;P2 任意两条不同的线恰有一个公共点;P3 存在四个点,其中任何三个都不共线。难点在「恰」字:它要拆成「存在」加「唯一」。例如 P1 逐一译成符号是
仿此把 P2、P3 也写全。P3 是存在句,它排除了「只有一条线」「只有两个点」之类的退化模型——没有它,前两条会退化地成立。
第二步:找模型。验证 Fano 平面(七点七线,见第一章 §1.6)满足 P1–P3:它是最小的射影平面,阶数 n = 2。再验证 PG(2,3)(十三点十三线,见第一章)也满足。两处模型落定,公理集就不是空谈。
第三步:改造成仿射平面。在射影平面里删去一条线 ℓ 以及它上面的点,剩下的结构就是仿射平面:任意两条线要么交于一点,要么平行(即它们在 ℓ 上的交点被删掉了)。出对应公理:A1 两点定一线;A2 过线外一点恰有一条平行线——这正是欧氏平行公设;A3 存在三点不共线。
第四步:找边界(最关键的一步)。试问:能不能用一句话要求「平面是有限的」?不能。一阶逻辑若有任意大的有限模型,就必有无限模型(紧致性,§2.9)。于是「存在 n 阶射影平面」只能对每个 n 单独写一条公理,无法一网打尽。更进一步:「n 阶射影平面存在」对大 n 至今是著名的开放问题——公理写得出,问题答不上,这条落差正是逻辑的分寸感。
加分题。① 改用塔斯基(§2.15)的两关系语言 β(介于)与 δ(等距)重写平面几何,比较「关联语言」与「介于/等距语言」在表达力上的差别;② 把希尔伯特几何(§2.13)五组公理中的平行公设与射影平面 P2(任意两线必交)并置,指出二者如何在同一条线上走向相反;③ 想一想,为什么「有限性」不可一阶刻画,却能借希尔伯特的连续公理(二阶)来写。
实验目的。用三套彼此独立的「判定机器」——真值表(语义)、归结(证明论)、希尔伯特证明核验(语法)——对同一批公式分别判定,检验它们结论完全一致;另用一台塔斯基语义机在有限结构上直接求值,复现量词次序的不可交换。脚本见 qa/exp_c2_f.py,运行结果存于 qa/exp_c2_f_out.txt。
核心代码(机器一:真值表判定)。
def ev(f, env): # 按真假给公式求值
op = f[0]
if op == 'v': return bool(env[f[1]])
if op == '~': return not ev(f[1], env)
if op == '&': return ev(f[1], env) and ev(f[2], env)
if op == '|': return ev(f[1], env) or ev(f[2], env)
if op == '>': return (not ev(f[1], env)) or ev(f[2], env)
def is_taut(f, vs): # 枚举全部赋值,全真即重言
return all(ev(f, env) for env in all_assign(vs))
核心代码(机器二:归结消解)。先把公式的否定推成否定范式、再分配成 CNF,然后两两归结、直到出现空子句(即「否定不可满足」,等价于原式为重言)。
def cnf(f): # NNF 上把 ∨ 分配到 ∧
...
if f[0] == '&': return cnf(f[1]) + cnf(f[2])
if f[0] == '|': return [a | b for a in cnf(f[1]) for b in cnf(f[2])]
def resolve(clauses): # 反复两两归结
...
if not resolvent: # 推出空子句
return True, steps
核心代码(机器四:塔斯基语义求值)。量词在有限论域上被逐一兑现——全称遍历每个元素、存在找一个见证,这正是 (S5)(S6) 的代码版。
def fo_eval(f, dom, interp, env):
...
if f[0] == 'A': # ∀x ψ:对论域每个元素都真
return all(fo_eval(f[2], dom, interp, dict(env, **{f[1]: d})) for d in dom)
if f[0] == 'E': # ∃x ψ:存在一个见证
return any(fo_eval(f[2], dom, interp, dict(env, **{f[1]: d})) for d in dom)
对拍结果摘要(qa/exp_c2_f_out.txt)。命题层七条公式中,p → p、p → (q → p)、A2 实例、排中律 p ∨ ¬p、(p ∧ q) → p、德摩根式六条被真值表判为重言,同时其否定被归结推出空子句;对照组 p → q 被判非重言,归结饱和而不出空子句——三机结论逐条吻合。语法层,核验器逐行确认「φ → (ψ → φ)」单行公理证明合法,并确认 φ → φ 的五行证明(同 §2.6 例 2.15)合法;故意改坏末行后,核验器立即拦截。一阶层,在论域 {0, 1, 2}、R = {(0,1), (1,0), (2,2)} 上,∀x∃y R(x, y) 求值为真,∃y∀x R(x, y) 求值为假,于是 ∃∀ → ∀∃ 为真而反方向不成立——量词次序的落差被现场复现。
实验报告要求。① 贴出脚本三段输出(对拍表、证明核验、一阶求值);② 自拟三条公式(至少含一条非重言式)替换测试组,重跑并解释每一条的一致性;③ 回答:若把归结换成一种不完全的消解策略,三机会不会出现结论分歧?为什么这说明「完备性」是判定机器的关键指标?(提示:不完全方法可能把「不可满足」误判为「可满足」。)
两套「推理学」的先后起步。公元前四世纪,亚里士多德在《前分析篇》里给出三段论:从两个前提经共同词项推出结论,论证的有效性只取决于形式,与内容无关。几乎同一片时间轴上,《墨子·大取》写下另一句纲领:「夫辞以故生,以理长,以类行者也」——一句话把论证拆成三件:故(理由)、理(规则)、类(类推)。墨家由此建立「名、辞、说」的分析框架:名当概念,辞当判断,说当推理。两条传统都发现了「推理要讲形式」这件事,只是着手的入口不同:希腊从「形式即保真」入手,把有效与事实分开;墨辩从「如何把人说服、如何指出对方的错」入手,把类比与举证放在中心。本章把「如果」锻造成算子 →、把「对一切」锻造成算子 ∀,走的正是前一条入口。
名家的辩术与因明的三支。与墨家相映的是名家:惠施的「历物十事」、公孙龙的《白马论》《坚白论》,都在拆解「名」与「实」的对应——「白马非马」不是诡辩,而是对概念外延的一次精确操作演示。再看佛教因明:约六世纪的印度论师陈那(Dignāga)把古因明改造为「三支作法」,用宗(命题)、因(理由)、喻(例证)三段来立论;七世纪玄奘将因明译介到中国,弟子窥基撰《因明入正理论疏》加以发挥。三支作法与三段论形似而神不同:它更强调「因」的成立条件(即「因三相」),把论证的可靠性锚定在理由与实例上,而不是纯粹的形式推演。中国的名辩与印度的因明都发展出了论证的规则,只是没有像希腊那样把「有效形式」单独抽出来公理化。
这一步差别为何重要。把「有效形式」抽象成公理系统,是现代逻辑的起点:只有形式被单独拿出来,才谈得上完备性、一致性、可判定性这些元数学问题(本章 §2.7–§2.12、第四章与第五章的全部议题)。名辩传统长在语言与论辩的土壤里,擅于辨析概念、提出反例、组织说服,却没有走到「把推理规则本身当成数学对象」这一步。这不必被读成缺失,而是另一种生长方式:墨辩关心「说得对不对、服不服人」,希腊逻辑关心「推得动不动、保不保真」。前者更近于今天所说的「论证理论」与「非形式逻辑」,后者才是数理逻辑的直系祖先。本册反复调用的「形式化」「可检查」,正是后一种传统的当代形态。
札记的注脚。本册把「可检查」当作主线的标准,是站在希腊传统的延长线上说话;但记住另一条线:在不同文明里,「怎样才算讲理」都曾被认真追问,且答案各具匠心。数理逻辑的独特之处,不在于它垄断了「理」,而在于它找到了一种可以被机器执行的写「理」的方式——这或许才是这门学问最独特的贡献。
| 条目 | 内容 | 出处 § |
|---|---|---|
| 符号表与项 | 逻辑符号 + 非逻辑符号(常量/函数/关系);项=名字,递归生成 | §2.1 |
| 公式 · 变元 | 原子式叠联结词与量词;自由/约束;无自由变元者=句子 | §2.2 |
| 结构 𝒜 与赋值 | 𝒜 = (A; …);常量落元素、函数落映射、关系落有序组集合 | §2.3 |
| 满足 ⊨(塔斯基) | (S1) 原子归结为属于;(S5) ∀ 逐点兑现;(S6) ∃ 找一见证 | §2.4 |
| 有效式 ⊨ φ | 一切结构皆真;可满足=至少一个结构为真 | §2.5 |
| 逻辑后承 Γ ⊨ φ | 使 Γ 全真的结构必使 φ 真 | §2.5 |
| 后承翻译 | Γ ⊨ φ ⟺ Γ ∪ {¬φ} 不可满足 | §2.5 |
| 公理模式 | (A1)(A2)(A3) 命题骨架;(Q1)(Q2) 量词 | §2.6 |
| 推理规则 | MP(由 φ、φ→ψ 得 ψ);Gen(由 φ 得 ∀x φ) | §2.6 |
| 可证 ⊢ | 证明=有限公式序列;每行是公理/前提/经规则所得 | §2.6 |
| 可靠性 | ⊢ φ ⟹ ⊨ φ(语法不越界) | §2.7–2.8 |
| 完备性(1929) | Γ 一致 ⟹ Γ 有模型;等价 Γ ⊨ φ ⟺ Γ ⊢ φ | §2.7 |
| 证明路线 | 加 Henkin 常元 → 极大一致集 → 项按 = 分类 → 项模型 → 真值引理 | §2.7 |
| 一致 ⟺ 可满足 | 元定理:语法不矛盾,语义住得下 | §2.8 |
| 紧致性 | Γ 有模型 ⟺ 每个有限子集有模型;关键只用「证明有限」 | §2.9 |
| 非标准模型 | PA ∪ {c > n}:紧致性造出的无穷大元素 | §2.9 |
| 等词与商模型 | (E1)(E2) 等号公理;项按 = 分类得商模型 | §2.10 |
| 前束范式 · 交换律 | 量词前移;∃∀ ⊨ ∀∃ 而反之不成立(§2.4 例 2.12 反例) | §2.11 |
| 元数学五概念 | 一致 · 独立(用模型)· 完备 · 范畴 · 可判定 | §2.12 |
| 希尔伯特几何 | 五组:关联 · 顺序 · 合同 · 平行 · 连续(1899) | §2.13 |
| 一阶算术 PA | 0、S、+、· 的公理,含归纳模式(无穷多条) | §2.14 |
| 塔斯基几何 | 原语 β(介于)、δ(等距);实闭域模型;完备且可判定(1948) | §2.15 |
| 群 · 环 · 域 | 代数以函数为语汇;分界线在「量词能否消去」 | §2.16 |
| 形式化收支 | 付:冗长与直觉被抹平;收:无歧义、可检查、元定理可证 | §2.17 |
符号卡。⊨ 满足/后承;⊢ 可证;𝒜, ℬ, ℳ 结构;ℕ, ℝ 标准算术与实数;β 介于、δ 等距(塔斯基几何);σn 「至少 n 元」的句子;Γ* 极大一致集。
定理卡(一句话)。① 可靠性:⊢ φ ⟹ ⊨ φ;② 完备性(哥德尔 1929):Γ ⊨ φ ⟺ Γ ⊢ φ;③ 一致 ⟺ 可满足(定理 2.17);④ 紧致性(定理 2.20):每个有限子集有模型 ⟹ 整体有模型;⑤ 量词交换:∃∀ ⊨ ∀∃,反之不成立。
易错三坑。① 把本章的完备性(语言对世界完备)与第五章的不完备性(理论对真理不完备)混为一谈——前者是正面定理,后者是局限结论;② 忘记论域非空(否则 (Q1) 与 ∀x φ → ∃x φ 失效);③ 把 ∀∃ 与 ∃∀ 当成可交换(§2.11 的反例就在 𝒩 里)。
转场。本章把「真」与「可证」两条线接成一条;下一章把镜头对准「证明本身」——它长什么样、如何化简、与程序有何关系。定理卡已在手,把它们带进第三章。
前两章把「真」讲透了:第一章的命题逻辑把真假摊成一张真值表,第二章的一阶逻辑把「在所有结构里都真」写成了完备性定理。一条推理是不是保真的,答案已经可以逐行核对。但每核对一次,手里的东西仍然是语义——公式被解释成结构上的关系,证明只是语义结论的附庸。本章要换一个视角:把证明从「结论合法性的旁证」升格为独立的第一等对象,问一些真值表问不出的问题——一个证明能不能被纯粹机械地检查?它能不能被化简?化简之后还剩什么?系统的强度用什么量来标度?这些问题的总称叫证明论,它是数理逻辑在 1930 年代从希尔伯特纲领的废墟上长出的最坚韧的一枝。
本章的行进路线分为五级台阶。
第一阶(§3.1–3.3)——证明的语法。先把「可证」写成与「真」平行的关系,再引入 Gentzen 1934 年的自然演绎:每条联结词配一进一出两条规则,并证明证明可以被「正则化」——把绕圈子的推理抹平。这一步给出证明论的第一件看家本领:证明是有形状的、可被化简的。
第二阶(§3.4–3.6)——相继式与切割消除。换一种记账方式:相继式演算 LK 把「从 Γ 推出 Δ」整体当成一个对象;本章的核心定理——切割消除(Gentzen 主定理)——断言任何证明都可以改写成不用切割的证明。完整证明思路在本章给出(§3.5),它是全章的技术顶点。
第三阶(§3.7–3.10)——构造性与资源。切掉排中律就得到直觉主义逻辑,证明随之带上「构造」的含义(BHK 解释);再经由库里–霍华德对应,命题变类型、证明变程序——逻辑与计算从此同构。Girard 的线性逻辑则把「资源」也搬进证明,为计算机科学开了一扇门。
第四阶(§3.11–3.13)——算术的一致性。Gentzen 1936 年用 ε0 上的超限归纳证明了皮亚诺算术的一致性,直接回应希尔伯特第二问题;由此引出「证明论序数」这把衡量理论强度的尺子,以及「最短证明有多长」的复杂度问题。
第五阶(§3.14–3.17)——机器证明。从吴文俊 1978 年的几何定理机器证明,到归结原理、可判定片段、证明助手——本章收在「形式化的工程学」,为第四章「什么能机械地算」与第六章「证明助手」埋下接口。
随身行李只有三件:一点点形式化的耐心、对「树」这种结构的亲切感、以及一个愿意把熟悉的重言式重新证一遍的好奇心。——行李齐备时,先随本章换一副眼镜:把「什么为真」暂时放下,只问「什么可证」。
★★ 同一句话可以有两个问题:「它是不是真的?」和「它能不能被证出来?」第一章的真值表回答了前者,本节要立起后者——并说明两者并非一回事。
两种语义,两个记号。第二章的完备性定理已经建立了等价的桥梁:Γ ⊨ φ(凡使 Γ 全真的结构都使 φ 真)当且仅当 Γ ⊢ φ(从 Γ 出发按规则能推出 φ)。就「结论」而言两个记号给出同一批公式。但就「过程」而言,它们截然不同:⊨ 是落在模型上的关系,需要遍历(往往是无穷多的)结构;⊢ 是落在纸面上的关系,只依赖符号的形状与规则的应用次序——一台只认得字形的机器就能检查。
注意定义 3.1 的三处刻意设计。其一,「公式」在规则层面只是字符串,不携带任何含义——检查一个公式是否合式、一步是否合规则,都是纯字形的操作。其二,公理集必须可判定:给定一个字符串,机器要有办法在有限步内判定它是不是公理。其三,「有限序列」四个字保证了每个证明都是有限的书写对象——可证明性因此是一个「有限可核查」的性质。
「为真」还是「可证」,差别在哪?在命题逻辑与一阶逻辑里(有完备性定理),两者殊途同归。差别在更强的系统里现形:算术中「φ 为真」常有意义,而「φ 可证」却可能既不真也不假地悬空——第五章的哥德尔定理正是靠分离这两个概念而成立。本章要先备好「可证」这一侧的全部器械:既然 ⊢ 是字形操作,就值得问它长什么样。
转向的收益从下一节起逐页兑现。先记住两句话:证明是可检查的(有限、按规则、无跳跃),可证不等于为真(但在一阶逻辑里两者恰好重合)。
★★ 希尔伯特式的公理化系统用一大堆公理模式加一条分离规则(modus ponens)堆出证明;证明短则短,可惜毫无结构可言。Gentzen 1934 年提出自然演绎(natural deduction),换一种哲学:每个联结词配一进一出两条规则,规则本身揭示联结词的意义。
核心思想:意义来自用法。说「φ ∧ ψ 成立」是什么意思?意思是「有办法从更基本的东西造出它」,并且「一旦有了它,就能取用它的两个部分」。这两句分别对应合取的引入规则与消去规则:
「证明树」是自然演绎的天然载体:叶片是假设,每个内部节点是一次规则应用,树根是结论。→I 与 ∨E 是仅有的两条会解除假设的规则——被解除的假设用方括号标出,恰如数学证明里「设 φ……故 φ → ψ」的收束。
两条规则值得单独提。其一是爆炸规则 ⊥E:从矛盾 ⊥ 可导出任何公式 φ;其二是直觉主义的 ¬ 的处理:由「假设 φ 引出矛盾」得 ¬φ(¬I),但不允许从 ¬¬φ 反推 φ——经典逻辑要额外加一条双重否定消去(或等价地加排中律)。这道分岔的整页讨论留到 §3.7,此处只记下:自然演绎有两种口味,去掉那一条就是直觉主义的。
自然演绎的美感在于它忠实于人的推理形态;代价是规则的应用次序几乎不受约束,一个结论可以有形状极其不同的证明。有形状,就必然有「形状的好坏」——下一节正是为此而来。
★★★ 自然演绎的证明树里藏着一类明显多余的模式:先引入再消去同一个联结词。这样的绕圈子(detour)可以被抹平,且抹平过程会终止——这就是正则化(normalization),证明论里第一次「把证明当成可计算对象」的胜利。
三种基本消峰。局部峰的消去是「就地改写」:
可以把「假设—代入」这一步想成替换:把 →I 解除的假设视为一个「洞」,→E 提供的证明填补这个洞。于是消峰等价于「把洞填上」,证明树因此变短。
为什么终止?归约每次都在「降低局部峰的复杂度」——用一个不严格的度量:给每个联结词按嵌套深度配一个权,局部峰的权严格大于替换后新产生的一切局部峰的权(总权下降),故不可能无限下降。这个「加权 + 良基序」的模式是证明论终止性论证的通用引擎,§3.5 的切割消除与 §3.11 的 ε0 归纳都是它的变体。
正则化的意义不止于「让证明好看」。正则形满足子公式性质(证明只用结论的子公式),这直接给出一致性的语法证明:若 ⊥ 可证,其正则形根为 ⊥,而 ⊥ 没有任何引入规则——正则形不可能是 ⊥ 的证明,矛盾。同一思想在相继式演算里以「切割消除」的面貌重现,下一站就是它。
★★★ 自然演绎的缺点是规则次序凌乱。Gentzen 的第二种系统——相继式演算——换一种记账法:不再问「公式怎么来」,而是把「从一列假设推出一列结论」整条判断当作对象。
LK 的规则分三类。第一类是结构规则,管理多重集的进出与重复:
第二类是逻辑规则,每个联结词各有一条左规则(作用于前件)与一条右规则(作用于后件)。左右之分正是 LK 的精髓:右规则在「造出」联结词,左规则在「消费」联结词——它与自然演绎的引入/消去遥相呼应,但更整齐:
∧R:由 Γ ⟹ Δ, φ 与 Γ ⟹ Δ, ψ 得 Γ ⟹ Δ, φ ∧ ψ。∧L:由 φ, Γ ⟹ Δ 得 φ ∧ ψ, Γ ⟹ Δ(或由 ψ, Γ ⟹ Δ)。
→R:由 φ, Γ ⟹ Δ, ψ 得 Γ ⟹ Δ, φ → ψ(假设移入前件!)。→L:由 Γ ⟹ Δ, φ 与 ψ, Γ ⟹ Δ 得 φ → ψ, Γ ⟹ Δ(即分离规则的相继式版)。
∨R:由 Γ ⟹ Δ, φ 得 Γ ⟹ Δ, φ ∨ ψ(或由 ψ 一侧)。∨L:由 φ, Γ ⟹ Δ 与 ψ, Γ ⟹ Δ 得 φ ∨ ψ, Γ ⟹ Δ(两种情形都要证)。
第三类只有一条规则,却是全章的种子:切割规则(cut)。它允许「先证一个引理,再用它」:
Γ ⟹ Δ, φ φ, Γ ⟹ ΔΓ ⟹ Δ (cut)
读法:若能从不含 φ 的前件推出 φ(或 Δ 中别的),又能从 φ 加前件推出 Δ,则直接从原前件推出 Δ——中间的 φ 被「切掉」。φ 叫切割公式。切割是数学里引进引理、分情形讨论、换元化简的通用形式;LK 有它才「好用」。而全章最重要的定理恰恰是:切割可以不用。
把自然演绎的证明翻译成 LK 的证明(或反之)是标准练习:∧I ↔ ∧R、→I ↔ →R、→E 则由 →L 加一次 cut 复现。可见 LK = 自然演绎 + 显式的结构规则 + 显式的切割。多说一句:切割之所以昂贵,是因为切割公式 φ 可以比结论复杂得多——它是「引理」可以任意深奥的原因,也是下一节要连根拔起的目标。
★★★★ 本节是全章的技术顶点。结论只有一句:LK 里所有用切割写出的证明,都能改写成不用切割的证明。它的证明不算长,但需要两个精细的度量,并且要把「切掉顶层联结词」这一步单独照料。
证明(双重归纳)。主归纳对切割秩 ρ 进行,次归纳对切割高度进行。两个度量都在良基的自然数上,归纳就是合法的。
放下笔回望这一步证明的两个设计:秩负责「整体变浅」,高度负责「局部变小」,二者一纵一横,把无穷种可能的证明形状压成有限的下降链。下一节看它能换来什么。
★★★ 切割消除定理之所以被称为「主定理」,是因为它一句话就放出一串重要推论。本页逐个收取:子公式性质、一致性、插值定理,外加一条给量词用的「中序」定理。
为什么对?无切证明里,除公理 φ ⟹ φ 外,每条规则的结论公式都由前提中的公式「拼装」而成:右规则把子公式合成大公式,左规则把大公式拆成子公式。故自上而下追一遍,证明中任何公式都嵌在终点相继式的公式里。∎ 这条性质有个漂亮的几何读法:无切证明像一棵向下生长的树,一切材料都来自种子里已有的一切,绝不凭空冒出新的、更复杂的公式。
证明。设 ⟹ φ ∧ ¬φ 可证,由推论 3.9 取无切证明。它的根是 ∧R,需要子证明证出 ⟹ φ 与 ⟹ ¬φ;后者由 ¬R 归结为 φ ⟹(空后件)。一个无切证明的叶子只能是公理 ψ ⟹ ψ,它两侧同一个公式、后件非空,绝不可能以 φ ⟹(后件为空)或 ⟹ φ(前件为空)的形态收尾——前件后件都空的相继式则根本不是公理。矛盾。∎ 这是希尔伯特纲领最想要的那种一致性证明:纯语法、不诉诸模型、可以用有限手段检查。哥德尔第二不完备定理日后会指出:这条语法通道证得了逻辑系统本身,却证不出足够强的算术系统自己的(见 §3.11 用超限归纳的迂回)。
证明思路。取 φ → ψ 的某个具体证明并化为无切形。沿证明树做归纳:对每个相继式 Γ ⟹ Δ,构造一个「分离公式」θ,其符号只取自 Γ 与 Δ 的公共符号。子公式性质保证这个构造总能完成(每个公式都来自终点)。插值是「证明中信息不能凭空产生」的精确表述:结论里的新符号,必在某处从公共符号中析出。∎(完整细节留下按 §3.5 的思路补全。)
中序定理把一阶证明的「命题内核」与「量词调度」一刀切开,是自动化定理证明(§3.16 的 Herbrand 思路)的理论支柱:先证出命题骨架,再统一安置量词实例。
把三条推论摆在一起看:它们都是「无切 = 信息守恒」的不同侧面。子公式性质说物质守恒,一致性说物质里没有自毁的成分,插值说两种物质之间必有可共用的接口。下一次页把这条守恒律挪到直觉主义世界里,看看去掉排中律会失去什么、又会得到什么。
★★★ 至今为止的 LK 是经典逻辑:它证明 φ ∨ ¬φ(排中律)、证明 ¬¬φ → φ(双重否定消去)。把这两条收走,留下的是直觉主义逻辑——它在构造性数学里有不可替代的地位。
为什么「≤ 1」就砍掉了排中律?先看经典逻辑怎么证排中律。在 LK 里,公理 φ ⟹ φ 经 →R 得 ⟹ φ, ¬φ,再经 ∨R 得 ⟹ φ ∨ ¬φ——只用了右规则,但这里后件同时含 φ 与 ¬φ 两个公式。LJ 禁止后件含两个公式,这一步就被封死。证明 ¬¬φ → φ 也需要同样地把后件「摊成两个」,因而在 LJ 中不可证。反过来,反证法(欲证 φ,先设 ¬φ 导出矛盾)在直觉主义里保留:它就是 ¬R 后再做一次对 ⊥ 的消去,后件始终不超过一个。被拒绝的是从「¬¬φ」跳到「φ」,而不是矛盾的使用。
直觉主义逻辑的「弱」是它的「准」:它拒绝的公式,在构造性数学里本来就不该无条件成立。经典数学说「必有一个素数同时满足 P,虽然算不出是哪一个」;直觉主义要求「若断言存在,就要能给出构造」。排中律的代价是允许非构造性的存在,直觉主义选择把这份便利退回。
还有一处必须记下的技术后果:直觉主义逻辑有析取性质与存在性质——若 ⊢ φ ∨ ψ,则 ⊢ φ 或 ⊢ ψ;若 ⊢ ∃x φ(x),则存在一个项 t 使 ⊢ φ(t)。经典逻辑没有这条性质(排中律让「或」可以非构造地成立)。这两条性质正是「证明即构造」的语法化身,下一节从语义侧把它讲透。
★★★ 直觉主义逻辑有一条非形式但极富启发的语义:BHK 解释(Brouwer 提出直觉、Heyting 给出规则、Kolmogorov 补全解释,1930 年代)。它不说「φ 为真」,而说「什么算作 φ 的一个证明」——把证明当成需要被构造出来的对象。
这套解释把「证明」翻译成了「数据与算法的语言」。几处对照:「φ → ψ 的证明」恰好是一个函数;「∃ 的证明」必然携带见证;「∨ 的证明」必然标明是哪一侧。§3.7 里那两条神秘的「析取/存在性质」,在 BHK 里成了定义的一部分——因为一个 ∨ 或 ∃ 的证明必须指明一侧或给出见证,否则它根本不成其为证明。
BHK 尚有一个含糊处:「算法」被当作原始概念。要让它严格,就得给「算法」一个数学模型——恰好就是第四章的 λ 演算与递归函数。而这一对严格化的工作,就是下一节的库里–霍华德对应。
★★★★ 1969 年,Howard 把 BHK 的直觉算术化:每个公式配一个类型,每个证明配一个程序,消去局部峰配一次求值。逻辑与计算从此是同一件事看两遍——这就是库里–霍华德对应(Curry–Howard correspondence,亦称命题即类型、证明即程序)。
把直觉主义自然演绎的证明逐行翻译成类型判断,会看到一张严丝合缝的对照表:假设就是「变量有类型」,→I 就是「抽象 λ」(把假设变成函数的参数),→E 就是「应用」(把函数作用到实参),而消去局部峰(→ 峰)就是 β 归约 (λx. t) u ↦ t[u/x]。证明树的形状与项的语法树在翻译下逐点重合。
| 逻辑侧(证明论) | 计算侧(类型论) |
|---|---|
| 命题 φ | 类型 σ |
| 证明 π : φ | 程序 t : σ |
| 假设「设 φ」 | 变量 x : σ |
| →I(解除假设) | 抽象 λx. t |
| →E(modus ponens) | 应用 t u |
| ∧I / ∧E | 配对 / 投影(积类型) |
| ∨I / ∨E | 注入 / 匹配(和类型) |
| ⊥(矛盾) | 空类型(无居民) |
| 局部峰 →E∘→I | β 可归约式 (λx.t)u |
| 正则化(消峰) | β 求值(计算) |
| 正则形 / 子公式性质 | 范式 / 类型保持 |
这张表不是修辞,而是定理级别的同一。它一次性地解释了两件事。其一,为什么正则化会终止:它就是类型化 λ 演算的强规范化定理,即每一个有类型的程序都会停机——这条把「证明化简必停」与「带类型的程序无死循环」焊在一起。其二,为什么切割消除对应程序求值:§3.5 里「切掉顶层联结词」的改写,在 λ 演算里正是把 (λx. t) u 代换求值;切得动,就算得动。
有了这张对应,前三节的语法技艺顿时有了第二份用途:证明论的工具立即可以翻译成程序语言理论与编译器技术。Girard 正是在这条线上再走一步,把「证明用了几次假设」也纳入类型,得到线性逻辑——下一节的入口。
★★★★ 自然演绎与 LK 有一个共同的疏忽:假设可以用几次、要不要用,规则不管。弱化说「多余的假设可以白白扔掉」,收缩说「同一假设可以用很多遍」。1987 年 Girard 指出,这种疏忽让逻辑丢失了对资源的敏感——而资源恰恰是计算的核心。线性逻辑(linear logic)就是重新计入资源账的逻辑。
两种「与」的分野。日常写 φ ∧ ψ 时,两种读法被混为一谈:其一是「我既有 φ 又有 ψ,两样都能随便用」;其二是「我只有一份资源,它同时满足 φ 与 ψ」。线性逻辑把他们拆成两个联结词:加性合取 &(两种都备着、任取其一)与乘性合取 ⊗(把两份资源并起来用)。类似地,「或」也分成加法性的 ⊕(我选一侧)与乘法性的 ⅋(两边都要用)。
这样一来,弱化与收缩不再是「普适的廉价操作」,而是「只有 ! 才能换来的特权」。普通的经典/直觉主义逻辑,本质上就是「把所有公式都当成 ! 包裹过的」线性逻辑——一个漂亮的还原:经典逻辑 = 线性逻辑 + 全面复制。
线性逻辑的意义远在逻辑内部之外。它天然适配并发计算(两份资源可以并行使用、互不干扰)、内存管理(一次性的资源恰对应「线性使用」的引用)与协议验证(消息发一次就没了)。库里–霍华德对应也随之升级:线性逻辑的证明对应线性 λ 演算的项,其中每个变量恰好出现一次——这类语言今天被用来写有资源约束的系统程序。证明论这一步「把假设当资源」的转弯,落到了工程上。
★★★★★ 希尔伯特第二问题要求:用有限的手段证明算术系统的一致性。1931 年哥德尔第二不完备定理宣布:任何足够强、可判定、一致的系统中,Con(T)(该系统一致性)本身不可证。纲领似乎被将死。1936 年 Gentzen 给出了回答——换一件工具,就能证。
证明思路(切割消除 + 序数赋值)。① 先把 PA 的证明整理到相继式演算里,其归纳法对应一条 ω 规则式的无穷前提(或用「归纳公理模式」。② 对每个证明 𝒟,按 §3.5 的思路做切割消除;但算术的归纳让切割消除不能单靠自然数度量保证终止——必须给每个证明指派一个 ε0 之下的序数 |𝒟|,使每次消切割都严格降低这个序数。③ 关键引理(Gentzen 的「归约引理」):若 𝒟 的末步是归纳或切割,则存在 𝒟′ 使 |𝒟′| < |𝒟| 且 𝒟′ 与 𝒟 结论相同。④ 假设 PA 不一致,则有一个证明以空相继式 ⟹ 结尾。不断归约,序数严格下降,因 ε0 良基,必在有限步停下,得到无切的无矛盾证明;而无切证明的末步不可能是空相继式(叶只能是公理 φ ⟹ φ,前后件同空不可能)。矛盾。故 Con(PA)。∎(思路版)
为什么这不违反第二不完备定理?因为 TI(ε0) 不是 PA 能证的定理——PA 的归纳只到自然数的结构序型 ω 层面,够不到 ε0。于是 Gentzen 的定理恰是第二不完备定理的精确补集:系统内证不了自己的一致性,用比它「稍强」的序数工具从系统外证得了。希尔伯特「有限手段」的原始要求被迫放宽为「超限归纳到某个序数」——这个序数的大小,反过来量出了理论的强度。这就把话题引向下一节。
★★★★ Gentzen 那一手给出了一把尺子的雏形:如果一个理论 T 的一致性可以用「到序数 α 的超限归纳」证出,而 α 已是最好的下界,就把 α 叫做 T 的证明论序数(|T|)。它衡量理论「能证多深的良基性」,因而成为理论强度的天然刻度。
| 理论 T | 证明论序数 |T| | 说明 |
|---|---|---|
| 命题逻辑 / Q | ω | 结构简单,只到自然数层面 |
| PRA(原始递归算术) | ωω | Gentzen 1936 的元理论工具 |
| PA / HA(一阶算术) | ε0 | Gentzen 1936 / 1935 |
| ID1(一层归纳定义) | εε0 | 比 PA 的递归能力再上一阶 |
| ACA0(算术理解公理) | εε0 | 二阶算术的弱基座 |
| 二阶算术(强) | 远超 εε0 | 证明论序数进入不可递归标度 |
| ZFC(集合论) | 极大(依标度而定) | 远超一切算术理论 |
读这张表有三个要点。第一,序数即强度。两个理论若证明论序数不同,就有一条强度式的分隔:序数大的系统能证序数小的系统的一致性,反之不能(Gentzen 定理的推广)。第二,序数差是非零的「翻译篱笆」。PA 与 ACA0 之间隔着 ε0 到 εε0 的一大段,这段距离对应「PA 证不出、ACA0 证得出」的一整批数学定理(如实数完备性的某些形式)。第三,序数不因形式化风格而变。PA 不论用希尔伯特公理式、自然演绎还是相继式写,序数都是 ε0——它是理论的内在强度,不是书写方式的花样。
这把尺子把「数学理论有多强」从模糊的直觉变成了一个可比较、可排序的序数。下一节换个方向:不比较理论的强度,而追究同一个定理的最短证明能有多短——强度管「能不能证」,复杂度管「要证多久」。
★★★★ 切割消除给了「证明的质量」一个保证(无切证明结构好),但质量是有价的:无切证明可能长得多。本节把「证明的长度」本身当成研究对象,看切割的代价、加速定理与归结的下界。
先看清切割的代价。§3.5 把带切证明改写成无切证明,改写时「一条 ∧ 切割换一条子公式切割」——看似只是把切割推高、推散,实则可能让证明指数膨胀。结构上:把一次切割的结论「复制」到多处使用,正是切割的省力之处;一旦禁止复制,就得在每处重新证一遍。于是有:
加速定理。下界说的是「有些证明删不得切割」,加速定理说的方向更强:
加速定理揭穿了「证明长度」的相对性,也点出一个实践事实:数学家的证明靠的是定理复用(切割);若严禁复用、每处从零开始,现代数学几乎无法写成。
Haken 的结果是证明复杂度作为独立领域的奠基作品之一:它说明「可判定 ≠ 实际可判」,某些简单的组合重言式在归结里天然难证。这直接解释了为何现代 SAT 求解器要靠大量启发式,也划出了「归结够用」与「必须换更聪明的系统」的界线(延拓归结、DPLL、CDCL 等等)。
三个定理合起来给出一幅完整的图景:证明长度是一个有结构的量,切割消除、加速、下界三者互相制衡。这套语言后来长成独立学科「证明复杂度」,并与计算复杂度里的 P vs NP 问题直接相连(若存在短证明的多项式长度下界能证,就能分离复杂度类)。本章的技术在第四节会以新面貌回归:自动化证明必须权衡「系统强度」与「搜索代价」,下一节先从几何定理说起。
★★★ 逻辑的机械化梦想最早的落地,是几何。Tarski 说过:判定一个初等几何命题,原则上只要用他的量词消去算法。可这算法慢得离谱。真正的突破来自一位中国数学家:吴文俊 1978 年的几何定理机器证明,用特征列法让大批经典几何定理真正在机器上被证了。
把几何翻译成代数。平面几何若采用坐标,则「点在线上」「两线段相等」「两直线平行」都化为多项式方程与不等式。一个典型几何命题形如:已知条件 h1 = 0, …, hr = 0(假设多项式组),求证结论 g = 0。于是「证几何」化为代数问题:由 h1 = ⋯ = hr = 0 能否推出 g = 0?
吴方法的魅力在于三步都可由机器执行:坐标化(把命题写成多项式)、消元(求特征列)、判零(伪除取余)。它把「证明」变成了「算」,与中国传统数学重「算」的气质遥相呼应(第五节札记再论)。
另一条路:Gröbner 基。Buchberger 1965 年提出 Gröbner 基,用一个良序(单项式序)把理想约化为规范形式的生成基。要证 g 落在假设生成的理想 ⟨H⟩ 中,只需算出 ⟨H⟩ 的 Gröbner 基,再做一次约化看 g 是否约到零。吴方法与 Gröbner 基是同一枚硬币的两面:都在做消元与理想归属判定,只是一个用特征列、一个用单项式序的规范基。
机器证明也暴露了形式化的代价:坐标化会引入大量辅助变量、退化的几何位置(如三点重合)会让结论失效,算法必须显式排除这些情形——「一般位置成立」与「处处成立」之间隔着一段工程。这一课在下一节延伸到更广的问题:究竟哪些理论能被自动判定?
★★★ 「有一台机器能证明所有定理」是空想:第四章会说明一阶逻辑的有效性不可判定。但若把话说小一点——某些片段是能全面自动化的。本节列一张「可判定地图」,这也是所有定理证明器划地盘的依据。
五块可判定的地。
把两块地摆一起,可判定性的边界就清楚了:去掉乘法,加法算术可判定;加回乘法,立刻不可判定。这道界恰好落在「乘法能表达哥德尔编码」这一点上——可编码性带来了自指,自指带来了不可判定。§3.14 的几何定理可判定,正因为它的多项式系统落在 RCF 这块可判定的地里。
实践中的定理证明器各自认领一块地:SAT 求解器在命题逻辑里,Presburger 工具在加法算术里,Wu 方法/CAD 在实闭域里。下一节讲它们的共同引擎——归结原理。
★★★★ 一台定理证明器不能「靠灵感」。它靠的是一条极简的规则:归结(resolution,Robinson 1965)。归结把逻辑推理化成对子句集合的操作,至今仍是 SAT 求解器、Prolog、自动定理证明器的共同内核。
归结的推理不用公理、不用引入/消去,只用一条「消去互补文字」的规则。要证 ⊨ φ,就把 ¬φ 化为子句集,反复归结,若推出空子句 □(矛盾),则 φ 得证——这叫反驳法(refutation)。
统一(unification)是关键加速。在一阶情形,子句里含有变量。归结前需先做统一:找到一个代入,使两个文字「形状相同」(如 P(x, f(a)) 与 ¬P(g(y), z) 需要 x ↦ g(y)、z ↦ f(a) 一类的最一般合一)。有了统一,一条归结可以「一次性」覆盖无数命题实例,机器人不必穷举个体——这是自动定理证明效率的源头。
重写系统:另一条引擎。若把等式当作「朝一个方向化简」的规则(如 x + 0 → x、x · 1 → x),就得到项重写系统。若规则集合流(confluent),则化简结果唯一,可作为判定两个项是否相等的算法;Knuth–Bendix 1965 的完备化算法能自动把一组等式补成合流重写系统。许多证明器(如 Isabelle 的 simp、Lean 的 simp)日常就在跑重写。
归结与重写是一台机器证明器的两只手:归结负责「发现矛盾」,重写负责「化简与判定相等」。前者完备但搜索空间大,后者高效但适用面窄,工程上常把它们混合。下一节转入把这些碎片组装成可用系统的工程学。
★★★ 有了切割消除与归结,理论问题解决了;把数学真正搬进机器,却是工程问题。本节讲证明助手(proof assistant)如何把本章的语法世界落成可运行的软件,也点出形式化的代价与收益。
把 de Bruijn 判据与本章的工具对读,会发现它正是切割消除的工程化:内核只认无切的、逐条规则的证明项(对应 LK 的无切证明或类型论的正则项);所有「引理复用」「快速证明脚本」都是外层的语法糖,最终被展开成内核能验的原始形态。库里–霍华德对应(§3.9)则给出另一层便利:证明项同时就是有类型的程序,因此内核检查证明 = 内核做类型检查。
三件工程装备。
形式化的收益不止「防止错误」。它逼使陈述精确到没有含糊的余地,迫使证明补全所有默认步骤,也让数学知识变成机器可复用、可检索、可自动组合的资源——第六章将把这条路走到当下。本章的技术之旅至此走完,接下来两页用例题把语义与语法两侧各练一遍。
例 3-1(真值表判重言式)。用真值表判定 (p → q) ∨ (q → p) 是不是重言式。
解。两变量共四行。p = T, q = T:p → q = T,析取为 T。p = T, q = F:p → q = F,但 q → p = T(前件假),析取为 T。p = F, q = T:p → q = T,析取为 T。p = F, q = F:p → q = T,析取为 T。四行全 T,是重言式。∎
例 3-2(语义蕴含的反例搜索)。判断 {p → q, ¬q} ⊨ ¬p 是否成立。
解。用反证法:设存在赋值使前提全真而结论假。结论 ¬p 假即 p = T;前提 ¬q 真即 q = F。代入 p → q = T → F = F——与前提「p → q 真」矛盾。故不存在反例,蕴含成立(这正是自然演绎里的 →I:由 ¬q 与 p 得 ⊥,再 ¬I 得 ¬p)。∎
例 3-3(等值判定)。证明 p → (q ∧ r) 与 (p → q) ∧ (p → r) 逻辑等值。
解。两式在 p = F 时同为 T。当 p = T 时,左式 = q ∧ r,右式 = q ∧ r,相等。故所有赋值都同真同假,等值。这条等值律在 LK 里体现为 ∧R 与 →R 的配合,是「→ 对 ∧ 分配」的语法版本。∎
例 3-4(预判可判定性与否)。下列问题各属于可以自动判定的片段吗?① 命题 p ∧ (q ∨ ¬p) 是否可满足;② 语句「每个大于 1 的自然数都有素因子」;③ 只含 +, < 的自然数语句「∀x ∃y (y > x + x)」是否成立。
解。① 可判定——命题逻辑,真值表查即可(本式可满足:p = T, q = T)。② 不可判定——「素因子」需要乘法与整除,落在 PA 的不可判定地里。③ 可判定——只含加法,属 Presburger 算术;且事实上为真(取 y = x + x + 1)。三问分别踩在「命题逻辑/含乘法算术/加法算术」三块地上,正对应 §3.15 的可判定地图。∎
复盘。本页四例示范了语义侧的标准动作:穷举真值表、构造反例、逐赋值比对、按片段的判定性分类。下一例题课转到语法侧,把同样的四个问题用证明树与相继式再解一遍。
例 3-5(自然演绎:三段论的复合)。在自然演绎中给出 p → q, q → r ⊢ p → r 的证明树。
解。假设 p;由 p → q 与 p 经 →E 得 q;由 q → r 与 q 经 →E 得 r;解除假设 p,经 →I 得 p → r。写成树:
[p]1 p → qq q → r ⟹ ⋮ rp → r(→I1)
本证明树不含任何局部峰(每次引入都发生在相应消去之前、且未经由该联结词消去),已是正则形。∎
例 3-6(相继式:∧ 的交换律)。给出 φ ∧ ψ ⟹ ψ ∧ φ 的 LK 证明。
解。从公理出发:φ ⟹ φ 与 ψ ⟹ ψ。对前者用 ∧L(把 φ ∧ ψ 放进前件):φ ∧ ψ ⟹ φ;对后者同样:φ ∧ ψ ⟹ ψ。两条前提经 ∧R 合并:φ ∧ ψ ⟹ ψ ∧ φ。全树只用左、右规则与公理,不含切割——一个「本来对称、无需引理」的证明。∎
例 3-7(归结反驳)。用归结证明 (p ∨ q) ∧ (¬p ∨ r) → (q ∨ r)。
解。否定结论并化子句:{p ∨ q, ¬p ∨ r, ¬q, ¬r}。归结:p ∨ q 与 ¬p ∨ r 在 p 上归出 q ∨ r;q ∨ r 与 ¬q 归出 r;r 与 ¬r 归出空子句 □。反驳成功。∎(这也是「归结是切割的受限形式」的一个小例子:一次归结恰对应一次不含结构规则的切割。)
例 3-8(切割消除的局部实操)。给定一个含「∧ 峰」的证明,说明如何消除它。
解。∧ 峰形如:先由 φ 的证明与 ψ 的证明经 ∧I 得 φ ∧ ψ,紧接经 ∧E 取回 φ。消除办法:直接删去 ∧I 与 ∧E,留下原来那份 φ 的证明。证明变短,且结论不变。反复消峰即得正则形(§3.3);对应的 LK 版本就是把一次 ∧ 切割换成子公式切割(§3.5 情形三)。∎
复盘。四例覆盖了本章的四种推演形态:自然演绎树、相继式树、归结反驳、消峰改写。它们从不同角度说同一件事:证明是被构造出来的对象,可以写、可以查、可以化简、也可以交给机器。至此本章的讲义结束,后面进入习题、地图、小结与专题页。
习题 3-1(热身:联结词语义)。对 p ↔ q(记作 (p → q) ∧ (q → p))写出完整真值表,并说明 p ↔ q 与 ¬p ↔ ¬q 是否等值。
提示。四行真值表,双条件在 p, q 同真值时为 T。两式的真值表逐行相同,故等值——这是「逆否等价」的一层推广。
习题 3-2(重言式判定)。判定下列公式是否重言式:① (p → q) → (¬q → ¬p);② (p ∨ q) → r 与 (p → r) ∨ (q → r) 是否等值;③ ¬(p → q) → p。
提示。① 是(逆否律)。② 不等值:取 p = T, q = F, r = F,左式 T(p ∨ q = T、→ r 为 F?细算左式为 F),逐行对比可找出反例赋值;结论是「→ 不对 ∨ 分配」。③ 是重言式——它其实是 ¬E 的语义版(由 ¬(p → q) 可推出 p)。
习题 3-3(语义蕴含)。判断是否成立:① {p ∨ q, ¬p} ⊨ q;② {p → q, q → r, ¬r} ⊨ ¬p;③ {(p ∧ q) → r} ⊨ p → (q → r)。
提示。均用「设前提真、结论假」找反例。① 前提真时 p = F,故 q = T——成立。② 由 ¬r 与 q → r 得 ¬q,再由 p → q 得 ¬p——成立。③ 成立,且是 LK 里 →R/∧L 的一次组合。
习题 3-4(语义与语法的接口)。用完备性定理说明:{φ} ⊨ ψ 当且仅当 {φ} ⊢ ψ;再举一个「语义上显然、语法上需证」的例子。
提示。对 φ → ψ 用完备性(第二章);「语义显然」的例子如 φ ∧ ψ ⊨ φ,其语法证明要动 ∧E(自然演绎)或 ∧L(LK)。
习题 3-5(可判定性分类)。判断下列语句分属哪块「可判定地」:① 命题重言式;② 只含 +, < 的语句;③ 含 +, · 的算术语句;④ 实数的初等语句。给出各自的判定手段(真值表/量词消去/Wu 方法/不可判定)。
提示。① 命题逻辑(真值表,NP 完全);② Presburger(量词消去,双指数);③ PA(不可判定,因含乘法);④ 实闭域(Tarski 量词消去/Wu 方法,双指数下界)。
习题 3-6(自然演绎证明)。在自然演绎中证明:① (p → q) → (p → r) ⊢ p → (q → r) 是否成立?② p ∧ q ⊢ q ∧ p。
提示。① 不成立(前件信息不足以定两端);找反例:p = T, q = T, r = F 时前件 (p → q) → (p → r) = T → F = F……逐行核验后确认不可证。② 假设 p ∧ q,∧E 取 q、再 ∧E 取 p,∧I 得 q ∧ p。
习题 3-7(相继式证明)。给出下列 LK 证明:① ⟹ φ → φ;② φ → ψ, ψ → χ ⟹ φ → χ(提示:需要一次切割,再说明切割消除定理保证存在无切版本)。
提示。① 公理 φ ⟹ φ 经 →R 即得。② 先用 →R 把结论变成 φ, φ → ψ, ψ → χ ⟹ χ,再用 →L 两次分离;切割用在中间 ψ 上;无切版本由 §3.5 保证存在。
习题 3-8(切割消除的推论)。① 为什么「无切证明的叶只能是公理」能推出子公式性质?② 用一致性推论说明:直觉主义逻辑 LJ 也不能证明 φ ∧ ¬φ。
提示。① 无切证明每个内部节点的公式由前提公式拼装或拆解,而公理前后件相同;自上而下追,一切公式都嵌在终点公式里。② LJ 满足切割消除与子公式性质,同样论证成立:空后件或空前件的相继式不可能从 ψ ⟹ ψ 形态的公理收尾。
习题 3-9(库里–霍华德)。把命题 (φ → ψ) → (φ → φ) 的证明翻译成一个类型化 λ 项,并说明它为什么退化。
提示。翻译为 λf: σ → τ. λx: σ. x——常函数,参数 f 未被使用。这正对应 §3.10 线性逻辑的观察:一般逻辑允许「浪费」假设(弱化)。
习题 3-10(选做·强度刻度)。查证并解释:为何 TI(ε0) 不在 PA 中可证,从而 Gentzen 的证明不违反哥德尔第二不完备定理?
提示。若 PA 能证 TI(ε0),则结合 TI(ε0) → Con(PA)(PRA 内可证)便得 PA 证 Con(PA),与第二不完备定理冲突。故 TI(ε0) 必在 PA 之外——它恰是「超出 PA 的那一步」。
本章 17 节的概念不是平行的,而是一条「语法主干 + 两条支流」的河。本页把它画成依赖图:箭头 A → B 表示「B 的定义或证明需要 A」。主干的顺序是:形式系统 → 自然演绎 → 正则化 → 相继式 LK → 切割消除 → 推论。
本图的读法。① 自然演绎与 LK 是同一件事的两种写法(§3.4 末指出可互相翻译),正则化与切割消除也是同一件事的两种写法(消局部峰 vs 消切割);图上对称的两列正是这对「双胞胎」。② 子公式性质是枢纽:它既是一致性、插值的公共来源,又是库里–霍华德对应在计算侧的表现(类型保持)。③ 两条支流互相独立却又汇合:构造与资源支流(§3.7–3.10)给出「证明即程序」,强度与代价支流(§3.11–3.13)给出「证明可度量」;二者在 §3.14 之后的机器证明里合流——程序要跑,度量要省。
通向外部的接口。① 正则化/切割消除的终止性 ⇄ 第四章的 λ 演算与递归;② ε0 与证明论序数 ⇄ 第五章的不完备性;③ 归结与重写 ⇄ 第六章的证明助手与自动推理;④ 库里–霍华德对应 ⇄ 第六章的依赖类型与证明即程序。四条线各通向后续章,本章是它们的公共发源地。
一条备考建议。若只求抓住主线,务必记住三个名字与三件事:Gentzen(自然演绎、LK、切割消除、ε0)、切割消除(子公式性质 ⇒ 一致性)、库里–霍华德(证明即程序)。三者串起来,本章就活了。
本页任务。把本章涉及的语义线索收成一张卡片。证明论虽然讲语法,却始终在与语义对话:语义告诉我们「什么叫保真」,也告诉我们「哪些问题能判定」。
可判定性的语义侧总结。语义侧最实用的一件产物是可判定地图(§3.15):一个语句落在哪块地,决定了它能否被机器判定。命题逻辑可判定(真值表);加法算术可判定(Presburger,双指数);实闭域可判定(Tarski/Wu 方法);含乘法的一阶算术不可判定。这张地图之所以成立,全赖语义刻画与模型论工具(量词消去、范畴性)。
| 语义对象 | 用途 | 出处 |
|---|---|---|
| 真值赋值 / 真值表 | 命题逻辑判定、反例搜索 | §3.15 / 例题课(一) |
| 结构满足 ⊨ | 一阶蕴含、完备性接口 | 第二章 / §3.15 |
| BHK 解释 | 直觉主义语义、构造性 | §3.8 |
| Kripke / Heyting 代数 | 直觉主义反例与新性质 | §3.7(延伸) |
| 可判定片段 | 自动化定理证明的地盘 | §3.15 |
一句提醒。不要因为本章重心在语法,就轻视语义。恰恰相反:语义说明「目标是什么」,语法说明「怎么走到」——库里–霍华德对应之所以能用「类型」解释「命题」,前提正是语义与语法早已对齐。下页把语法侧收成卡片。
本页任务。把本章全部语法装备压缩成六张卡片。这是本章的正身,也是后续各章反复调用的工具库。
三个必须能独立复述的证明。① 自然演绎 →I 与 →E 成对的语义依据(对应 BHK 的函数解释);② LK 切割消除的「情形三」如何降秩;③ 由子公式性质推出一致性。三个证完,本章的内核即牢固。
与后续章节的接口。① 正则化终止性 → 第四章 λ 演算与递归函数;② 切割消除与一致性 → 第五章不完备性(Con(PA) 的语法地位);③ 归结与证明助手 → 第六章自动推理与形式化数学。三处接口在综合站的总图上会再度汇合。
本章最深的一课,其实只藏在两个字符里:→。日常语言里的「如果……那么……」背着太多行李——因果、时间先后、反事实、说话人的态度。「如果下雨,地就湿」讲的是因果;「如果秦始皇多活十年」是反事实;「如果愿意,尽可跳过本节」甚至不是判断,只是一句客套。逻辑的第一次清洗,是把这些行李统统卸下,只留下一个能被规则摆布的算子:→。
卸干净之后,「如果」露出三重身份。其一是真值函数:p → q 与 ¬p ∨ q 同真同假,它只在「前件真而后件假」这一种情形取假。其二是规则对:→I 从「假设 p 能推出 q」得到 p → q,→E 从 p → q 与 p 得到 q;一进一出,假设被解除又被使用。其三是类型构造子:在库里–霍华德对应下,p → q 是一族函数,把 p 的证明喂进去,就吐出 q 的证明。三个身份不是三样东西,而是同一个 → 被三种语言分别描摹。
直觉主义给「如果」添上最后一块砝码:→ 的证明就是一个函数,蕴含因此携带构造信息。正因如此,排中律 p ∨ ¬p 在直觉主义里不可证——凭空断言「要么有、要么没有」,等于索要一个不可能存在的函数:既没拿到 p 的构造,也没拿到 ¬p 的构造,却要交出一个站得住脚的答案。切割消除与正则化,则对应着把这族函数算到底:一处「引入紧跟消去」的局部峰,正是一次没有被真正执行的函数调用。
留下一个自问:既然逻辑的 → 只关心真值与规则,那么日常语言里那些「说不清」的如果——反事实的、带情绪的、依赖语境的——究竟是逻辑遗落了它们,还是它们本来就算不上能押上真假的东西?下一章换一个角度追问「可算」:若连「算」都有边界,那么「如果」所能承载的算法,边界又画在哪里。
任务。选一种几何,用一阶语言写出它的公理系统,使「由公理推出定理」成为可机械检查的推理。可挑其一:射影平面、仿射平面、有序仿射平面,或初等欧氏平面(Tarski 系统)。要求给出语言(排序或谓词)、约八到十五条公理、说明它的模型,并判断该理论是否可判定。
为什么这件事值得做。第二章已经见过希尔伯特 1899 年的:五组公理(关联、顺序、合同、平行、连续)把欧氏几何整理成一套演绎系统。本章的证明论再往前推一步——把公理写成符号串,使「每两点恰有一条直线」这样的话成为可形式处理的句子。几何因此成了检验自动证明的最佳试验场,也正是 §3.14 吴方法的用武之地。
参考路标。① 希尔伯特1899 年的五组公理;② Tarski 的初等欧氏几何(一阶、完备、可判定,1951);③ 关联几何与相干几何的模型论——Desargues、Pappus 与坐标域的三段论;④ §3.14 的吴方法:几何题代数化后,用特征列法消元判零,是可判定性落到工程上的样子。
加分题。① 写出「凡 Desargues 平面皆可坐标化」的证明路线,指出「斜域」与「域」的分界究竟由哪一条公理划定;② 用一阶语句表达「平面恰有 n 个点」,并说明为什么射影平面公理族在有穷语义下不能由有限条公理刻画;③ 把结论对到 §3.15:为什么只含加乘序的实闭域可判定,而含完整连续公理的希尔伯特几何不可判定?(提示:连续性需要二阶量词,或无穷多条一阶公理的图式。)
实验目的。用两套互相独立的判据去回答同一个问题——一个子句集是否矛盾:语义侧用真值表逐行穷举,语法侧用归结反驳导出空子句。按命题逻辑的健全性与完备性,两条路必须永远给出同一结论。再把鸽笼式 PHP(n + 1, n) 的归结步数数出来,亲手体检「切割的代价」(§3.13)。全部代码可运行于任何 Python 3 环境,无需第三方库。
实验一:两条判据对拍。核心代码(完整脚本见 qa/30_c3_f_exp.py):
from itertools import product
def neg(a): # 文字取反:'p' → '~p'
return a[1:] if a.startswith('~') else '~' + a
def resolvents(c1, c2): # 两个子句的全部归结式
out = set()
for a in c1:
if neg(a) in c2:
out.add(frozenset((c1 - {a}) | (c2 - {neg(a)})))
return out
def truth_unsat(cls): # 判据一:真值表逐行穷举
vs = sorted({a.lstrip('~') for c in cls for a in c})
for vals in product([False, True], repeat=len(vs)):
env = dict(zip(vs, vals))
if all(any(env[a.lstrip('~')] == (not a.startswith('~'))
for a in c) for c in cls):
return False # 有一行全真 ⇒ 可满足
return True # 一行都没有 ⇒ 不可满足
def refute(cls, cap=50000): # 判据二:归结反驳
S = {frozenset(c) for c in cls}
S = {c for c in S if not any(d < c for d in S)} # 去包含
steps = 0
while True:
cur, add = list(S), set()
for i in range(len(cur)):
for j in range(i + 1, len(cur)):
for r in resolvents(cur[i], cur[j]):
steps += 1
if steps > cap:
return None, steps
if not r: # 空子句 □
return True, steps
if (r not in S and not any(s <= r for s in S)
and not any(s <= r for s in add)):
add.add(r)
if not add:
return False, steps
S |= add
S = {c for c in S if not any(d < c for d in S)}
# 对拍:(p→q)∧(q→r)→(p→r) 的否定子句集
cls = [['p'], ['~r'], ['~p', 'q'], ['~q', 'r']]
print('真值表-不可满足 =', truth_unsat(cls))
print('归结-反驳 =', refute(cls)[0])
运行结果(对拍)。四条样例,两条路结论处处一致:
| 样例(结论的否定,已化为子句集) | 真值表:不可满足 | 归结:反驳成功 | 归结步数 | 一致 |
|---|---|---|---|---|
| (p → q) ∧ (q → r) → (p → r) 的否定 | 是 | 是 | 4 | 一致 |
| (p ∨ q) ∧ (¬p ∨ r) → (q ∨ r) 的否定 | 是 | 是 | 6 | 一致 |
| 可满足样例(本就不该反驳成功) | 否 | 否 | 2 | 一致 |
| 不矛盾样例(三项互相咬合) | 是 | 是 | 3 | 一致 |
实验二:鸽笼式的代价。PHP(n + 1, n) 说的是「n + 1 只鸽子住进 n 个洞,每洞至多一只」——它显然矛盾,但归结要绕很远才能发现。程序统计如下:
| 鸽笼式 | 子句数 | 结论 | 归结步数 | 活动子句数 |
|---|---|---|---|---|
| PHP(2, 1) | 3 | 反驳成功 | 3 | 4 |
| PHP(3, 2) | 9 | 反驳成功 | 559 | 12 |
| PHP(4, 3) | 22 | 预算耗尽 | 50001 | 1484 |
实验报告要求。① 贴出对拍结果表,并说明两条判据为何必然一致(归结健全 ⇒ 归出空子句必真矛盾;归结反驳完备 ⇒ 真矛盾必能归出空子句,§3.16);② 给出鸽笼式步数随 n 的增长,解释为什么增长得这么快;③ 回答:若把预算上限调大,PHP(4, 3) 最终会回报「反驳成功」吗?(会——但代价随 n 指数级膨胀,这正是 Haken 关于鸽笼式归结下界的结论,也解释了 §3.13 所说的切割代价为何不可免。)④ 自行改一条样例(例如把某个子句的文字取反),观察两条路的结论是否仍处处一致。
希腊:从辩论术到公理演绎。西方推理之学的起点常被定在亚里士多德的《前分析篇》(约公元前 350 年),那里第一次把「三段论」提成形式:由两个前提的形式,不看出格内容,就能断定结论必真。随后的欧几里得《几何原本》(约公元前 300 年)把公理演绎推成典范——从寥寥数条公设出发,一步一证地织出整部几何。这条线两千年不绝:到弗雷格《概念文字》(1879)把推理彻底符号化,再到 Gentzen 1934/1935 年给出自然演绎与相继式演算,正是本章的主角。证明论追问的「证明本身是什么、能否被机械检查」,是这条公理化传统最深的延伸。
印度:因明的「宗、因、喻」。东方并非没有对推理形式的系统追问。公元 6 世纪,陈那(Dignāga)在《因明正理门论》中确立「三支作法」:宗(要立的命题)、因(理由)、喻(同喻与异喻的实例),三者须满足「因三相」才算成立的论式。这套格式与三段论可作对照——宗近于结论,因近于小前提,喻则是大前提连同例证。玄奘于 645 年归国后译出商羯罗主的《因明入正理论》,因明之学遂在唐代盛行一时。陈那的「九句因」逐格审查因与宗的同品、异品关系,实质上是对「推理形式有效性」的一次系统划分。
中国:名辩的「辟、侔、援、推」。先秦的名辩之学同样在追问「怎样推得对」。《墨子》的《大取》《小取》(战国)提出四种论式——辟(比喻)、侔(比辞并列)、援(援引对方之言)、推(由已知推未知),并原则性地指出「以类取,以类予」:推理的合法,全系于「类」的同异。公孙龙的「白马非马」(战国)则把「是」的多义与外延的层次摊开——「马」言形、「白马」言形兼色,二者不可混一,这是极早的语义分析。到《荀子·正名》,更有「名、辞、说辩」的三级结构。只是这条线索后来更偏向「算」与「表」:《九章算术》以「术」为纲,长于程序化的计算,而未发展出把推理本身写成符号、交给机器逐字核验的系统。
札记的注脚。中国传统之所长,在「算」与「表」——九章之术、天元之设,都是具体算式上的程序化操作;希腊传统之所长,在「证」——从公设出发的一步一证。本章的相继式演算恰好把两股传统拧成一股绳:它像「证」,处处要求逐条规则可核对;又像「算」,把一份证明当成可以逐步化简、可以交给机器执行的字形对象。把「正确推理」从一件依赖人的洞察的事,变成一件依赖字形与规则的事——这正是证明论的现代姿态,也是三条传统共同追问的回响。
本表把第三章的语法装备压成一页。查证时先看「条目」,再顺「内容」回顾要点,末列的 §号可回到讲义页核对细节。
| 条目 | 内容 | 出处 |
|---|---|---|
| 自然演绎 | 每个联结词配引入/消去两条规则,成对出现;证明是树,→I 与 ∨E 解除假设 | §3.2 |
| 正则化 | 消去「引入紧跟消去」的局部峰,逐个消峰必终止,正则形满足子公式性质 | §3.3 |
| 相继式 LK | 相继式 Γ ⟹ Δ 整体为对象;结构规则+左右成对的逻辑规则 | §3.4 |
| 切割规则 | 对应「引用引理」:先有一公式 φ 的证与「由 φ 导出」的两段,再合流 | §3.4–3.5 |
| 切割消除 | 对切割秩与切割高度作双重归纳;情形三把顶层切割换成子公式切割,秩必降 | §3.5 |
| 子公式性质 | 无切证明中每个公式都是终点公式的子公式 | §3.6 |
| 一致性 | 由子公式性质推出:空后件或空前件的相继式无人可达,故系统无矛盾 | §3.6 |
| Craig 插值 | 由无切证明抽出中间公式,只含两端的公共语言 | §3.6 |
| 直觉主义 LJ | 后件限一个公式;砍掉排中律与双重否定消去 | §3.7 |
| BHK 解释 | 证明即构造:对子、带标签的一侧、函数、见证;⊥ 无证明 | §3.8 |
| 库里–霍华德 | 命题↔类型、证明↔程序、消峰↔求值、切割消除↔强规范化 | §3.9 |
| 线性逻辑 | 假设是资源;! 才能复制或丢弃,弱化与收缩受控 | §3.10 |
| ε0 归纳 | Gentzen 1936 用 TI(ε0) 证 Con(PA),回应希尔伯特第二问题 | §3.11 |
| 证明论序数 | 理论的强度刻度:|PA| = ε0,序数越大理论越强 | §3.12 |
| 证明复杂度 | 切割消除以长度换透明:Statman 下界、Gödel 加速、Haken 鸽笼式下界 | §3.13 |
| 几何机器证明 | 吴文俊 1978 特征列法;Gröbner 基;Tarski 的实闭域判定 | §3.14 |
| 可判定片段 | 命题逻辑、Presburger 加法算术、实闭域 RCF、稠密线性序 DLO 均可判定 | §3.15 |
| 归结原理 | Robinson 1965:消去互补文字,导出空子句即反驳;配合统一实现一阶归结 | §3.16 |
| 重写系统 | 把等式定向为化简规则;Knuth–Bendix 完备化得合流系统,可判项相等 | §3.16 |
| 证明助手 | de Bruijn 判据:内核小到可人工复核;Coq、Lean、Isabelle、HOL | §3.17 |
符号小卡。把本章的关键记号放在一起,随时对照:
三张必须能独立复述的证明。① 自然演绎 →I 与 →E 成对的语义依据(对应 BHK 的函数解释);② LK 切割消除的「情形三」如何降秩;③ 由子公式性质推出一致性。三者串起本章的语法内核;再往前一章,第六章会把这些装备送进真实的证明助手与自动推理系统。
前三章把「推理」写成了符号,又让「证明」成为可检查的对象。可有一件事始终悬着:这些操作到底能不能全交给一台机器?给一台只懂读写、移动与印字的笨机器一张纸带,它能不能算出人类用笔能算的一切?更进一步——有些问题,机器是不是永远算不出?
本章的一条主线,就是把「算」这个动词精确化,然后诚实地面对它划出的边界。整章分四级台阶:
第一级(§4.1–4.4)——把「机械地算」写成定义。先回到希尔伯特 1900 年的问题清单:判定问题与第十问题都想「让数学一劳永逸地被机械解决」。图灵 1936 年给出的回答是把「机械」这件事本身形式化——纸带、读写头、状态、转移函数。四条腿(图灵机、λ 演算、递归函数、Post 系统)各自独立地长出来,却支撑同一头象,这就是丘奇–图灵论题的底气。
第二级(§4.5–4.9)——不可判定的诞生。先造一台通用图灵机:它读入任何一台机器的编码,就能模拟它的运行——机器第一次学会「运行程序」。有了自模拟,对角化便势如破竹:停机问题不可判定。再学会归约这件「放大器」,一个停机问题就繁殖出成百上千个不可判定的问题;Rice 定理则一次性宣判一整类语义问题的命运。
第三级(§4.10–4.14)——从能不能算到算得多快。Church–Turing 把不可判定性移植进一阶逻辑;随后转入复杂性:P 与 NP、NP 完全、Cook–Levin 定理,以及 P vs NP 为何如此难证(相对化与自然证明两道屏障)。
第四级(§4.15–4.17)——边界与普遍性。计算能不能超出图灵机(超计算)?元胞自动机凭什么做到「普遍计算」?最后一页把全章的判定版图铺成一张地图。
常驻嘉宾:二进制后继机。一台只有三四个状态的图灵机,读一串 0-1 纸带,把末尾加一——它将在 §4.2 当第一台标本、在 §4.5 被通用机模拟、在实验页被真跑。小到可以手画状态图,又足以演示「机械」的全部要素。
读本章只需带两件行李:把函数看成「输入到输出的对应」,以及一点对角化的胆量——康托尔 1891 年用来证明实数不可数的那招,会在停机问题处再次亮剑。行李齐备,直接上第一级台阶。
★★ 二十世纪的逻辑学有一个奇特的起点:它先立下一个过于乐观的纲领,再用二十年把这个纲领一半推翻、一半抢救。本章要讲的「机械地算」,正是从这场纲领的崩塌处长出来的。
希尔伯特之梦。1928 年,希尔伯特与阿克曼把「数学能否被机械地解决」提成三个尖锐的问题:一阶逻辑是否完备(真即证得出)?是否一致(证不出矛盾)?是否可判定(是否存在一个通用算法,对任意一阶语句判定其真假)?前两个问题由哥德尔 1929、1931 年先后作答(完备而不可自证一致),第三个问题——判定问题(Entscheidungsproblem)——则要等到 1936 年。
在同一个梦里,还有一个更早、更具体的版本。希尔伯特第十问题(1900 年巴黎国际数学家大会):给定一个整系数丢番图方程 P(x1, …, xn) = 0,是否存在一个算法,判定它有没有整数解?
两条否定答案的证明路线很不一样。丘奇用的是自创的 λ 演算,图灵用的是图灵机——两台引擎各造各的,结论却严丝合缝。这是逻辑史上罕见的「双重独立确认」:两条完全不同的形式化道路撞上同一堵墙,墙的真实性由此变得可信。
为什么「不可判定」不是坏消息。一个不可判定的结论,说的是「不存在一个对所有输入都停机并给正确答案的算法」,并不禁止我们对许多具体输入求得答案。它宣判的是「万能判官」不存在,却把「哪些子类可判定」变成了一个丰饶的研究纲领——本章 §4.11 与第五章都将回到这条支线上。
还有一个方法论的礼物:要证明某种「算法」不存在,先得把「算法」这个词精确化——否则「不存在」无从谈起。判定问题的不可判定性,因此逼出了本章第一节要造的那台机器。
★★★ 图灵 1936 年设计的机器,比任何真实的计算机都更简陋:一条无限长的纸带、一个读写头、一叠有限的状态。简陋到可以画在纸上,却精确到能定义「机械地算」的全部含义。
格局:机器的「快照」。要描述机器在某一步的全部信息,只需三样:纸带上的字符串、读写头的位置、当前状态。这三样合称一个格局(configuration),通常写成 u q v,其中 q 左侧是头左边的纸带、右侧是头右边的纸带(含头正读的那个符号)。一步转移把格局变成下一个格局;机器从初始格局 q0w 出发(w 是输入串),不断作格局替换,直到落入接受或拒绝格局——或者永远走下去。
计算与接受。图灵机对输入 w 的三种命运,是本章一切结论的根:接受(停机于 qacc)、拒绝(停机于 qrej)、永不停机(既不接受也不拒绝,一直走下去)。一台机器若对所有输入都在这种意义下「要么接受要么拒绝」,称它判定(decides)某语言;若只保证「接受的输入必被接受、不接受的输入永不停机」,则称它识别(recognizes)某语言。判定强于识别——这一字之差,就是 §4.9 三分法的全部由来。
加法机、乘法机、字符串比对机都能照此设计,只是状态数会膨胀。重要的不是手搓每一台,而是承认:凡能用有限条明确规则描述的操作,都能装进这七个格子里。这条信念将在 §4.3 升格为一个论题。
★★★ 上一节给了「图灵机」一个精确定义,但它凭什么代表「一切机械地算」?图灵机只是一个很偶然的模型——也许换个模型就能算得更多。本节说明:不会。
注意「论题」二字的分量:它不是定理。定理可以有证明,论题只可能有证据。理由很微妙——「有效可计算」是一个前形式化的直觉概念(人类用笔和纸、按明确规则一步步算),「图灵机」是一个形式对象。要证明二者相等,就得先把直觉概念形式化;可一旦形式化,它就不再是原来那个直觉概念了。论题说的是:这个形式模型恰当地抓住了那个直觉。
证据一:多个独立模型彼此等价。1930 年代,至少有四个模型被各自独立地提出,用来刻画「可计算」:
四个模型的「硬件」天差地别,却被逐一证明两两等价:一台图灵机能算的,一个 λ 项也能算,反之亦然。这才是论题最强的证据——如果「可计算」依赖于某个具体模型,这么多种毫不相干的模型不该给出同一个答案。
证据二:模型再升级也不越界。此后八十年,人们又造了无数更强的模型:寄存器机、随机存取机、带多条纸带的图灵机、非确定性图灵机、甚至允许任意并行——只要计算规则仍是有限的、确定作用的,其「能算的函数集合」都不超出图灵机。丘奇–图灵论题因此被一次次加固:它像一个受过反复考验的经验定律,越来越难被推翻,却始终不是定理。
证据三:物理世界的默认。今天任何一台真实计算机,都是图灵机的物理实现(有穷内存、有限步操作);反过来,没有一种已知物理过程被证明能计算图灵机算不出的函数。§4.15 会把这个话题推到物理边界。
论题的用途,是把「不存在算法」的证明合法化:只要说明某个问题若可解就会让图灵机算出不可算的函数,即可宣布它无算法。§4.6 的停机问题正是这句话的第一个实例。
★★★ 图灵机是「机器的视角」;本节补上另外两个视角——数论家的递归函数与逻辑学家的 λ 演算。三视角合一,才配得上一句「丘奇–图灵论题」。
加、乘、幂、阶乘、前驱、绝对值差、最大公约数——数论里绝大多数初等函数都是原始递归的。原始递归的「递归」二字名副其实:它按自然数的结构归纳定义,定义本身就保证了函数处处停机(每一步的 y 都在减小)。
原始递归不够用:Ackermann 的警告。有一类显然「可计算」的函数——例如 Ackermann 函数 A(m, n)(定义见下)——却不是原始递归的:它增长得比任何原始递归函数都快。这说明原始递归画不出「可计算」的完整疆域,必须再加一样武器。
μ 算子的代价与收获都写在同一句话里:「搜索最小的 y」——这正是机器「不妨一个个试下去」的动作,也第一次允许了「试到天荒地老也不停」的可能性。停机问题的阴影,在定义里就已埋下:μ-递归允许无定义的输入,而不收敛正是图灵机的「永不停机」。
三个定义、三套语言、三种直觉,划出同一个函数类。这不是数学的巧合,而是「机械地算」这个概念本身的稳定性——它不因用纸带、用递归式还是用函数记号来写而改变。丘奇–图灵论题说的正是这件事:这个稳定的类,就是「可计算」的全部。
★★★ 从 §4.2 的后继机到现在,每台图灵机都只会做一件事。本节要造的机器不同:它读入别的机器的编码,然后照着运行——这是「存储程序计算机」的思想原型,也是停机问题证明的技术前提。
第一步:把机器写成字符串。一台图灵机的七元组是有限对象,因而可以用有限串完整描述。取定一套编码方案:先把状态 q0, q1, …, qk 与纸带符号编号,再把每条转移规则 δ(qi, a) = (qj, b, D) 写成一段二进制串(用分隔符把「源状态、读符号、目标状态、写符号、方向」五个数串起来)。所有规则按字典序拼接,得到机器 M 的编码,记 ⟨M⟩。
证明思路(构造)。U 用自己的一条纸带存储三样东西:被模拟机器的编码,被模拟机器的当前纸带内容,以及被模拟机器的当前状态与头位置。U 的主循环是:① 从编码里查出当前 (状态, 读到的符号) 对应的规则;② 在被模拟纸带上改写符号、移动标记;③ 更新状态。每一步是有限的机械操作,故 U 本身是一台合法的图灵机。它的状态数远多于被模拟机,但并不依赖被模拟机的规模——这正是「通用」二字的技术含义。∎(思路)
两个技术推论。由通用机的存在,可立刻得到两条在不可判定性证明里反复使用的工具:
s-m-n 定理的直觉是「部分求值/柯里化」:把二元函数固定第一个参数 x,剩下的 y ↦ φ(x, y) 仍是一个可计算函数,其「程序编号」s(x) 可机械地从 x 算出。这一条看似平凡,却是归约论证的发动引擎:它让我们能「机械地造出」一台新机器,专门解决手头这个问题。
一张可枚举的机器表、一台会自模拟的通用机——两件武器就位,下一节的对角化有了舞台。
★★★★ 本节是第四章的心脏,也是整册逻辑论证的顶点之一:证明「机器会不会停」这件事,机器自己永远判不了。证明只用一把刀——对角化——但刀刃要磨得极快。
证明(对角化,完整)。反设 H 可判定,即存在一台图灵机 Halt,对任意输入 ⟨M, w⟩ 都在有限步内停机,且
Halt(⟨M, w⟩) = 接受 ⟺ M 在 w 上停机; Halt(⟨M, w⟩) = 拒绝 ⟺ M 在 w 上不停机。
读证明的三把钥匙。其一,自指是合法的:机器可以被编码成串,串可以是机器的输入,所以「机器问自己」不是文字游戏,而是编码方案的自然结果。其二,对角化是康托尔 1891 年老招的新用场:那里否定的是「实数可数」,这里否定的是「停机可判」。其三,唯一用到的性质是「Halt 总停机」:正因为 D 敢放心调用 Halt 并等它的答案,矛盾才成立。若 Halt 自己都可能不停,这场反调就唱不成。
最后一个提醒:定理说的是「不存在判定 H 的机器」,不是「H 里的问题都无解」。对许多具体机器,我们完全能算出它停不停——不可判定性拦住的只是「一个算法管全部」。
★★★ 停机问题是一座海拔很高的孤峰。归约是把这座峰降落到别处的手艺——它让「一个不可判定」繁殖成「成百上千个不可判定」,是本章最实用的一件工具。
读法:「若会解 B,就会解 A」——把 A 的输入 x 机械地翻译成 B 的输入 f(x),然后调用 B 的判定器。f 必须处处停机(否则翻译本身就可能卡住),翻译的正确性正是「x ∈ A ⟺ f(x) ∈ B」。
(一)的证明。设 f 把 A 归约到 B,g 把 B 归约到 C,二者皆处处停机。令 h = g ∘ f:h 是可计算函数的复合,故处处停机可计算;且 x ∈ A ⟺ f(x) ∈ B ⟺ g(f(x)) ∈ C,即 h 把 A 归约到 C。∎
(二)的证明。反设 B 可判定,设其判定器为 MB。构造 A 的判定器:输入 x,先算 f(x),再问 MB 是否 f(x) ∈ B,原样输出。由归约的定义,此判定器答「是」当且仅当 x ∈ A,且处处停机——与 A 不可判定矛盾。∎
把停机问题当模板。有了 (二),只要把 H 归约到新问题 B,B 立刻不可判定。两个经典例子:
方向别搞反(最常见的错)。要证 B 不可判定,必须把已知不可判定的问题归约到 B(H ≤m B),而不是反过来。直觉地说:把难问题翻译成 B 的实例,说明 B 至少和难问题一样难。把简单的 A 归约到难问题,什么也说明不了——任何问题都能「归约」到停机问题(用 Halt 之后照答即可)。
下一节把归约用到极致:不是逐个问题地杀,而是一次宣判一整类语义问题。
★★★★ 停机问题只宣判了一个问题。Rice 定理(1953)把它升级成一条元定理:程序的一切非平凡语义性质都不可判定。这条定理让「我们写个工具自动检查程序有没有 bug」这类幻想,在一般情况下被彻底堵死。
证明思路(归约 H ≤m 之)。不妨设空函数 ∅(处处无定义的函数)不满足 P(若满足,改对补性质 ¬P 论证,非平凡保证二者必有其一)。由非平凡性,存在一个程序 M1 使 φ(M1 计算的函数)满足 P。归约函数 f 如下:
推论 4.24。以下问题全部不可判定:① 程序对输入 0 是否停机;② 程序的输出值域是否有限;③ 程序是否恒输出 0;④ 两个程序是否计算同一函数(即例 4.21 的 Eq);⑤ 程序所算函数是否单调递增。凡是问「这段代码算出的是什么」的问题,几乎都落入 Rice 的射程。
为什么这条定理重要。软件工程里最诱人的目标是「全自动验证程序正确性」。Rice 定理说:不存在一个通用工具,能对所有程序判定「这个程序是否满足某条非平凡规格」。这不是工程的暂时落后,而是逻辑的永久天花板——任何实际的验证工具,都必须要么限制程序语言(牺牲通用性),要么要求人工给出断言与不变量(牺牲全自动),要么只做不完备的检查(牺牲确定性)。第六章的证明助手,正是这三条路的第一条的伟大实践。
注意定理的边界。Rice 管的是全局语义性质。具体到某一个固定程序,它是否满足 P,往往可以判定(跑一跑、证一证)。定理说的是「对所有程序一律裁决」不可能,与「逐个分析可行」并不冲突。
★★★ 「可判定」是一条硬线,但硬线只有两档不够用。本节把问题分成三档,并补齐中间那档的主要成员——半可判定。三分法让不可判定不再是一个笼统的黑洞,而有了层次。
三分法由此成形:可判定 ⊊ 半可判定 ⊊ 全部语言。左端严格:停机问题 H 半可判定却不可判定——给 ⟨M, w⟩ 就派一台通用机去真跑,停了就答「是」,不停就永远等;它从不撒谎,代价是可能永不作答。右端严格:由康托尔对角线,字符串的全体语言不可数,而图灵机只有可数多台,故必有语言连半可判定都不是。
证明。(⇒)判定器立即可改造成两台识别器,故可判定 ⇒ 双方半可判定。(⇐)设 M1 识别 L、M2 识别 Lc。构造 L 的判定器:对输入 x,并行跑 M1 与 M2(交替走一步,用「时间片轮转」模拟并行)。因 x 或属于 L、或属于 Lc,两台机器中必有一台最终接受;届时输出对应答案并停机。∎(此证也说明:可判定 = 半可判定 ∧ 补半可判定。)
推论 4.27。停机问题 H 的补 Hc = {⟨M, w⟩ : M 在 w 上不停机} 不是半可判定的。否则 H 与其补都半可判定,由定理 4.26 得 H 可判定,矛盾。
Post 对应问题(PCP)。半可判定与不可判定的分界还有一个著名的「瓷砖游戏」:给定有限个「骨牌」(ai, bi),每张是一对字符串;问能否选出有限多张(可重复)首尾相接,使上方拼出的串与下方拼出的串完全相同。
证明思路。把任意图灵机的运行历史「编码」成一串骨牌:一张骨牌代表一个格局的片段,拼接过程精确模拟计算的一步;若机器停机,则存在一次拼接使上下两串相等。由于停机问题可归约到 PCP(H ≤m PCP),PCP 不可判定。∎(思路)PCP 的迷人之处在于:它只问「能不能把两串字符拼得一样长」,就这一个小小的组合问题,已经足够承载整个图灵机的计算力。
三分法的意义。有了这三层,面对一个新问题,第一步不再是问「有没有算法」,而是问「它落在哪一层」:能判定的,我们造算法;只能半可判定的,我们接受「答『是』可靠、答『否』无限等待」的代价;连半可判定都不是的,则连「枚举验证」都不给。下一章证明一阶逻辑的有效式集合半可判定(枚举证明即可)却不可判定,正落在这条线上。
★★★★ 第二章证明了完备性:凡有效的语句都证得出。完备性让人误以为「有效性」唾手可得——既然证明能被枚举,那有效式当然能被枚举。可枚举不等于可判定:把「证得出」变成「判得出」,中间隔着一道 1936 年才被看清的深渊。
第一步:有效性是半可判定的。由完备性定理,⊨ φ 当且仅当存在一个从空前提推出的证明。把所有证明按长度(或编码序)枚举出来,逐个检查:但凡出现一个以 φ 为结论的证明,就接受。这台机器对有效式一定停机并接受;对无效式则永远搜下去、永不出声。于是 Val 半可判定。
第二步:有效性不可判定。把停机问题归约到 Val。给定 ⟨M, w⟩,机械地构造一个一阶语句 φM,w,使
M 在 w 上停机 ⟺ φM,w 无效(即 ¬φM,w 有效)。
构造思路(编码计算)。取一个只含二元关系符号的语言,把「机器运行史」写进模型:用有穷后继关系的元素序列表示时刻 0, 1, 2, …,用像「纸带在第 t 步第 p 格是符号 a」这样的谓词记录纸带内容,用「第 t 步处于状态 q、头在第 p 格」记录格局。再把转移函数逐条翻译成公理:这些小公理要求「后一时刻的格局恰是前一时刻格局按 δ 走一步的结果」。最后让 ¬φM,w 断言「存在一段符合上述一切约束的有穷运行史,其起点是初始格局、终点是接受格局」。若 M 在 w 上停机,这段运行史真实存在,取该模型即验证 ¬φ,故 φ 有不成立的模型、即 φ 无效;若不停机,则任何模型里都不存在这样的有穷史,φ 处处成立、有效。翻译 ⟨M, w⟩ → φM,w 是机械的、处处停机的,故 H ≤m {φ : φ 无效} = Valc。因 H 不可判定,Valc 不可判定;又因 Val 半可判定(第一步),若 Val 可判定则 Valc 亦可判定(取补即可)——矛盾。故 Val 不可判定。∎
两个补充。其一,有效性半可判定但不可判定——这正是定理 4.26 的活样本:有效式能枚举(答「是」可靠),无效式不能枚举(答「否」可能永不作答)。其二,Trakhtenbrot 1950:即使只问「φ 在有穷模型中是否可满足」,也不可判定;反过来,这恰好说明「有限」这个词在一阶逻辑里无法被公理化——「模型是有限的」写不成一个一阶语句,否则它会把可满足性问题变成可枚举的两重叠加。
对希尔伯特纲领的合围。到此,纲领的三根支柱倒了两根:不可自证一致(哥德尔第二,第五章),不可判定(Church–Turing,本页)。剩下的完备性只是「证得出一切真式」的安慰奖——它保证逻辑不错,却不保证逻辑快、更不保证逻辑遍及一切。逻辑是一台永不撒谎的机器,但它会沉默、会慢、会答不完。
★★★ 全量的一阶逻辑不可判定,这个判决不是终点而是分水岭:往左走,是「砍掉多少表达力才换回可判定」;往右走,是「保留多少表达力却接受不可判定、改用半判定或不完备的检查」。本节盘点最有用的几块可判定飞地。
为什么砍掉「多」就回来了。秘诀几乎总是一句话:限制语言能「同时说话」的对象数目。一元谓词逻辑里每个谓词只吃一个变元,无法表达「x 与 y 的关系」,于是整棵搜索树塌成有限的形状——判定过程本质上是枚举「哪些一元谓词的组合是可同时满足的」。Presburger 算术只留加法与顺序,去掉了乘法,恰好绕开「用乘法编码配对、再用配对编码图灵机」这条通向不可判定的暗道;一旦把乘法请回来(Peano 算术 (ℕ, +, ×)),第五章会看到它连完备都做不到。Tarski 的实闭域判定则更神奇:实数的序结构约束强到让判定过程收敛——正是这种可判定性,让计算机能对几何命题作真判定。
三段小实验的直觉。① 一元谓词逻辑:把每个一元谓词的「真值模式」压成一个有限类型的检验,可判定性来自「类型只有有限多种」。② Presburger:判定过程叫「量词消去」——把每个含全称或存在的语句对「下一个数」展开,逐层消去量词,最终化为无变量的算术真值判断;这个过程总终止,因为加法不产生新的「可数结构」。③ 实闭域:Tarski 的量词消去更强,能在多项式符号运算里消掉一切量词——代价是复杂度极高(原始算法的下界是双指数 22n 量级),可判定却昂贵。
工程意义。今天的自动化推理,几乎全部工作在这些飞地里:命题逻辑用 SAT 求解器(见 §4.12),带等词与未解释函数的一阶片段用 SMT,算术片段用 Presburger 或线性算术决策过程。当工具的输入一超出飞地,工具就退化为「给出一个模型即证明可满足,搜不到就老实说不知道」的不完备检查——Rice 定理与 Church–Turing 不是工具的技术缺陷,而是工具必须绕开的墙。
本页留下的线索,下一节将转向另一半:不可判定性之外,还有一个更精细的问题——即使判定得了,要花多少时间?
★★★ 截止到这里,本章只关心「能不能算」。一旦承认某问题能算,下一个问题就是「多贵」。复杂性理论把「贵」精确成资源:时间步数与纸带格子数。这条支线诞生了理论计算机科学最著名的悬案。
两种说法的等价,是 NP 这一定义的关键:非确定性图灵机可以「猜」一个凭证 c(沿一条幸运的分支走),确定性验证器则把同一件事改写成「存在一个够短的凭证、且核验够快」。猜与验,是同一枚硬币的两面。P ⊆ NP 显然,因为确定性机器是可忽略猜测的特殊非确定性机器。
证明思路。SAT ∈ NP 显然(给一组赋值,逐子句检验即可)。关键是 SAT 是「最难的 NP 问题」:对任意非确定性图灵机 M 与多项式时间界 nk,把「M 在 nk 步内接受 x」这件事翻译成一个布尔公式 φM,x:用布尔变元表示「第 t 步第 p 格是符号 a」「第 t 步处于状态 q、头在第 p 格」;用子句约束「每一步只有一个状态」「相邻格局按 δ 转移」「首行是初始格局」「末行出现接受状态」。整张表的规模是 n2k 级别的多项式,翻译本身多项式时间可做。于是 x ∈ L(M) ⟺ φM,x 可满足。∎(思路)
NP 完全的实例花园。Cook–Levin 给了第一块多米诺骨牌 SAT,随后 Karp 1972 一口气证明 21 个问题是 NP 完全的。几个重要成员:3-SAT(每子句恰三个文字的 SAT,比 SAT 更规整,做归约的万金油);团问题(图中是否存在 k 个两两相邻的点);顶点覆盖;Hamilton 回路(是否存在经过每个点恰一次的圈);子集和、旅行商。它们之间用多项式归约串成一张网:SAT ≤p 3-SAT ≤p 团 ≤p 顶点覆盖 ≤p …,任一条变短,网就整体收紧。
P vs NP。克雷数学研究所的七个千禧年问题之一,也是最朴素的一个:「凡是能快速检验答案的问题,是否都能快速找到答案?」直觉说不是(找到一个解往往比核对一个解难得多),但七十年的努力没有一个人能证明二者不等——甚至没人能排除它们相等。下一节专门讲:为什么这道题这么难。
★★★★ P vs NP 不是一道没人攻的题,而是一道很多人攻过、却留下一串「为什么攻不下」的定理的题。这些定理合称屏障(barriers):它们不回答 P vs NP,却精确地指出「某一大类证明方法注定失败」。
定理的含义要以反证的方式读。任何由「模拟、对角化、改机器、比较步数」这类对机器内部结构不敏感的步骤拼成的证明,都可以原封不动地搬到任何谕示之下——因而若此法能证明 P ≠ NP,同一段推理也会证明对一切谕示都有 PO ≠ NPO;可定理 4.36 给的 A 恰好反着来。矛盾。故一切相对化的证明方法都不可能解决 P vs NP。这不只是给 P vs NP 设限:停机问题本身恰恰是相对化的典型产物(它能被对角线一类的相对化论证证明),这正是「同一把刀能切停机问题、却切不动 P vs NP」的技术解释。
与「独立性」的关系。还有一条更耐人寻味的可能性:P vs NP 会不会像连续统假设那样,在常用的公理系统(如 ZFC 或 PA)内既不可证也不可否证?研究者确实发现了这类迹象的影子——例如某些较弱的复杂性分离(如「P ≠ NP 之类的语句不能被某类有界算术证明」),以及 Ben-David–Halevi 一系关于「某些 P vs NP 型语句与预言的独立」的结果。但要说清一件事:目前没有证明 P vs NP 独立于 ZFC,这类结果多针对更弱的公理系统或更强的命题。正确态度是把它当作一种尚未排除的、需要认真对待的可能性,而非既定结论。
屏障的正面价值。BGS 与 RR 不是悲观文件,而是研究指南:它们把「哪种证明范式已被堵死」写成了定理,逼着后来者练新招。今天复杂性理论的活跃前沿——代数化下界、几何复杂性论、证明复杂性——正是在屏障的缝隙里长出来的。第五章会看到,哥德尔不完备性也是一种同类的屏障:它不否定真理,只否定「用本系统证本系统一致性」这一类方法。
★★★ 前面的机器都是确定性的:同样的输入,同样的输出。可现实里的优秀算法常常「抛硬币」——随机取数、随机走一步。随机性真能算得更多吗?本节说明:多半不能,但要说清「多半」需要一套精巧的工具。
2/3 这个常数并不神圣:反复独立跑 k 次、取多数票,错误率降到 (1/3)k 指数小。BPP 的哲学含义是:允许算法掷骰子,但要求它几乎总是对的。显然 P ⊆ BPP ⊆ PSPACE。
去随机化如何可能。随机算法之所以有效,多是因为它的错误来自「恰好抽到坏样本」。若能造一台伪随机生成器,用少量真随机的种子 s 拉出一长串「看起来随机」的位,并且保证任何多项式时间算法都分不清它与真随机——那么把随机算法里的硬币全部换成这串位,错误率不变。枚举全部种子(种子只有多项式多个),对每个种子跑一遍算法,取多数票:这就得到一台确定的多项式算法。这条链把「随机性是否有用」归结为一个困难性假设:随机性可以被确定性交换,代价是交换的合法性依赖于存在难问题——复杂性的东西,往往彼此是同一件事的不同侧面。
另一侧:随机性也有好处。去随机化的前提是困难性假设,而我们并不知道它是否成立。在它不成立的世界里,随机性可能真的更强(BPP ≠ P)。此外,随机算法常给出更简洁的代码与更好的常数——即便理论上可去随机化,实践中「先随机、后优化」仍是主流工程策略。PCP 定理(第五章将简介)与交互式证明系统,更是把随机性变成了刻画 NP 的工具:随机性在这里不是计算手段,而是证明概念本身的一部分。
本节的定位。随机性把 §4.12 的 P 与 NP 地图又添了一层:真实算法世界的地图不是几个方框,而是 P、BPP、NP、PSPACE 交错的多层结构,层与层之间用归约、模拟、伪随机性缝合。下一节离开纯数学,走向一个更狂野的问题:物理世界能不能超越图灵机?
★★★★ 丘奇–图灵论题说的是「一切机械地算 = 图灵机可算」。可「机械」终究长在物理世界里:纸笔、齿轮、电子、光子。如果换一种物理,机器能算得更多吗?本节把论题推到它唯一的边界处——物理。
支持它的三个观察。① 已知物理定律都「图灵友好」:经典力学、电磁学、广义相对论下的演化方程,都被证明可在图灵机框架内做任意精度模拟(Churches 型结果)。② 量子计算不越界:量子图灵机是确定性的推广,其能判定的语言类仍含于可计算语言之内,只是可能更快(BQP);量子计算改变的是复杂性版图(例如 Shor 1994 让大数分解进入量子多项式时间),不是可计算性版图。③ 没有反例:至今没有任何已知物理过程被证明能判定停机问题。
挑战它的三个思想实验。下面三个都是「若把物理允许到极限,图灵机会不会被超越」的认真提案:
为什么这件事值得认真对待。因为它把论题从「数学约定」提升为「关于世界的断言」。若某天造出了一台能判定停机问题的物理装置,丘奇–图灵论题(乃至整个可计算性理论对物理的适用性)就要重写。历史给出的答案是稳妥的:八十年过去,每一次「新物理 = 新计算力」的期待,最终都落回第二层——变快而不变强。
本页的立场是谨慎的:把物理丘奇–图灵论题当作一条高度可靠的经验定律,而不是不可动摇的定理。它配得上被当作定理使用(就像我们日常用「随机性是伪随机」一样),但只要有一天物理跳出了第二层,我们就该修改论题,而不是修改世界。
★★★ 「普遍计算」是本章最有野心的一句话:只要一条规则足够精巧,任何足够大的系统都能模拟任何图灵机。本节让看见这句话最直观的两个证据——一维的 Rule 110 与二维的「生命游戏」。
「普遍性」的三种等价读法。说一个系统普遍可计算,可以有三种说法:① 它能模拟任意图灵机;② 它能判定自身演化的某些性质(如「某图案是否最终出现」)而这些问题编码了停机问题;③ 它内部能构造出通用图灵机的「硬件」。三者本质相同,是「系统足够强」这一件事的三张面孔。
普遍性的震撼之处。把普遍性放回物理,一件事忽然清晰起来:「计算」不是硅片或电线独有的属性,而是「受有限局部规则支配的系统」在足够大时的普遍能力。涌流(水流、沙堆、化学振荡)中为什么总能找到计算?答案是:只要局部规则足够「别扭」到能编码条件分支,计算就会自发长出来。
与不可判定性的交汇。Rule 110 与生命游戏的普遍性,让「初态演化问题」继承了停机问题的不可判定性:不存在算法对任意初始图案判定「它最终会不会出现某个子图案」。这给「仿真」这门通用技术划了一道底线:任何足够强的仿真系统,都会继承不可判定性。没有一劳永逸的「预告机」,只能真跑——一如 §4.6 的纸带。
★★ 本章走了很远:从希尔伯特之梦的破碎,到图灵机的七元组;从停机问题的对角化,到 NP 完全与两道屏障。本页把全章结论收成一张地图,并说明它如何决定今日算法工程的能力边界。
三条主结论,三句话。第一,可计算性有确定的内涵:图灵机、λ 演算、递归函数四个模型彼此等价,丘奇–图灵论题把「机械地算」锁定为一个稳定的类。第二,这个类有确定的疆域,且有洞:停机问题、一阶逻辑有效性、Post 对应问题、程序等价性都是不可判定的;Rice 定理更一次性宣判一切非平凡语义性质不可判定。第三,疆域之内还有三等公民:可判定、半可判定、连半可判定都不是——三分法让「不可判定」不再是一个黑洞,而有层次、有结构。
地图如何指导实践。算法工程师的日常,几乎全部活在这张地图的投影里:
| 领域 | 落在哪一层 | 工程应对 |
|---|---|---|
| 命题可满足性(SAT) | 可判定(NP 完全) | SAT 求解器:CDCL、启发式,指数最坏但实用飞快 |
| 线性算术(Presburger) | 可判定(但昂贵) | SMT 中的算术决策过程,规模受控 |
| 程序终止性证明 | 不可判定(平均情形可近似) | 人工不变量 + 不完备工具,永远不会全自动 |
| 「这段代码有没有 bug」 | 不可判定(Rice) | 抽象解释、类型系统、测试——都是不完备或受限 |
| 一阶逻辑定理证明 | 半可判定 | 搜索证明:找到即证毕,搜不到则未知 |
地图的地图:「能算什么」与「算什么快」是两个正交的问题。注意右上与右下两块的差别:不可判定说的是「没有算法」,NP 完全说的是「算法也许有、但我们不知道它快不快」。前者是逻辑的墙,后者是复杂性之谜。把这两件事混为一谈,是初学本章最常见的误解。同时也要记住 §4.11 的反面:不可判定的问题,往往有可判定的片段;NP 完全的问题,往往在特定实例族上飞快——理论与工程的正确姿势,永远是「先把边界说清,再把手伸进边界内」。
下一站。本章的「能算到哪」与第二章的「一阶逻辑是什么样的」在此汇流;第五章的哥德尔不完备性将以同样的技巧(编码 + 对角化 + 归约)回答「一个系统能证到哪」。停机问题与不完备定理是同一枚硬币:一个说机器停不下来的地方,另一个说系统证不下去的地方——而两块地方是同一块。
例 4-1(手推一台后继机)。图灵机 Msucc 的规则为 δ(q0, 1) = (q0, 0, L)、δ(q0, 0) = (qacc, 1, R)、δ(q0, ␣) = (qacc, 1, R)。读写头从输入串最右端起步。求输入 101 与 111 的输出。
解。输入 101:头停在最右符号 1 → 翻 0、左移,得格局带 10(0)、状态 q0;下一格是 0 → 翻 1、右移、接受,得带 1(1)0,即 110(十进制 6 = 5 + 1)。输入 111:右端 1 → 0 左移;再 1 → 0 左移;再 1 → 0 左移;此时头落到左端空白 ␣ → 改 1、右移、接受,得带 (1)000,即 1000(8 = 7 + 1)。答:101 → 110,111 → 1000。(这正演示了二进制「逢二进一」的机械版。)
例 4-2(用真值表判命题可判定性)。为什么命题逻辑可判定,而一阶逻辑不可判定?给出一句话的分界判据,并说明真值表法的复杂度。
解。命题逻辑里只有有限多个命题变元,任何语句的真假完全由这有限多个变元的取值决定,故「枚举全部 2n 行赋值」就是判定过程——可判定性的来源是「有限的模型空间」。真值表法需要 O(2n) 行,指数级时间但有限,故可靠且完备。一阶逻辑的模型空间无穷(个体域可任意大),无法穷举,于是由 §4.10,有效性不可判定。分界判据一句话:可控有限即判定,无穷无界即失守。这正是 §4.11 那架天平的第一块砝码。
例 4-3(哪个是语义性质)。下列性质哪些落在 Rice 定理的射程内(即不可判定)?① 程序的状态数不超过 5;② 程序对输入 1 停机;③ 程序计算出的函数是常数函数;④ 程序源码不超过 100 个字符。
解。① 语法性质:只看写法,可判定(数一数即可)。② 语义性质且非平凡:涉及「算出什么/停不停」,由 §4.8 的归约不可判定。③ 语义性质且非平凡:由 Rice 定理不可判定。④ 语法性质:可直接检查,可判定。答:②③ 不可判定,①④ 可判定。判据:性质依赖「程序怎么写」还是「程序算出什么」;后者的非平凡者几乎全落在 Rice 的射程内。
例 4-4(归约的方向判断题)。学生这样论证:「已知停机问题 H 不可判定;又显然 H ≤m H0(空白带停机)且 H0 的任何实例都能作为 H 的实例,故 H0 ≤m H,再由传递性得结论」。这段论证的哪一步冗余、哪一步必要?
解。冗余的是「互归」的那一步:要证 H0 不可判定,只需要 H ≤m H0 加归约律(二),反方向完全用不上。必要的是 H ≤m H0 这一步的归约函数要可计算且处处停机——把 w 硬写进机器再模拟,正是由 s-m-n 定理保证的。教训:证明不可判定性时,反方向归约(把易问题归约到难问题)永远不能作为证据,因为它对任何问题都成立,不含信息——这是 §4.7 反复强调的方向纪律。
例 4-5(把停机问题的证明写完整)。完整重述停机问题不可判定的证明,并指出自指与对角化各在哪一步出场。
解(五步)。① 定义 H = {⟨M, w⟩ : M 在 w 上停机};反设存在判定器 Halt。② 构造 D:输入 ⟨M⟩,调用 Halt(⟨M⟩, ⟨M⟩);若答「停」则 D 死循环,若答「不停」则 D 停机。(自指出场:M 的输入是它自己的编码。)③ 把 D 喂给自己:问 D 在 ⟨D⟩ 上停不停。④ 若停,则按其构造它只在该机器不停时才停——矛盾;若不停,则 Halt 答「不停」,构造要它停——矛盾。(对角化出场:第 ⟨D⟩ 列的取值被强制与全表反号。)⑤ 停与不停穷尽,故 Halt 不存在,H 不可判定。∎
例 4-6(用停机问题归约证明新问题不可判定)。令 Z = {⟨M⟩ : M 对某种输入输出 0}(机器 有时 会输出 0)。证明 Z 不可判定。
解。构造归约 f : ⟨M, w⟩ ↦ ⟨M′⟩:机器 M′ 对任意输入 y 先忽略 y、模拟 M 于 w;若该模拟终止,则 M′ 输出 0;若永不终止,则 M′ 永不输出。由 s-m-n 定理,f 可计算且处处停机;只要 M 在 w 上停,M′ 就在某输入(实际上任何输入)上输出 0,即 ⟨M′⟩ ∈ Z;若永不停,则 M′ 从不输出,⟨M′⟩ ∉ Z。于是 H ≤m Z,由归约律 (二) 与 H 不可判定,Z 不可判定。(这也可看作 Rice 定理的一个特例:「值域含 0」是非平凡语义性质。)∎
例 4-7(SAT 与 3-SAT 的归约感受)。把公式 φ = (x1 ∨ x2 ∨ x3 ∨ x4) 化归为等可满足的 3-SAT 公式。
解。引入新变元 y,令 φ′ = (x1 ∨ x2 ∨ y) ∧ (¬y ∨ x3 ∨ x4)。核对:若 φ 可满足,取 y 为使两个三文字子句都真的值(若 x1 ∨ x2 真则取 y 假、否则取 y 真,第二子句随之真),φ′ 可满足;若 φ′ 可满足,则任何赋值下 (x1 ∨ x2 ∨ y) 与 (¬y ∨ x3 ∨ x4) 中至少一个的「非 y 部分」为真,即 (x1 ∨ x2) ∨ (x3 ∨ x4) 真,故 φ 可满足。一般做法:把长度 k > 3 的子句用 k − 3 个新变元「链式拆开」,子句数与长度都只放大多项式倍——这就是 SAT ≤p 3-SAT 的归约。
例 4-8(复杂度直觉)。为什么「3-SAT 是 NP 完全的」会让「P = NP」的证明变得异常困难?
解。NP 完全的定义是「NP 中最难」,其严格含义是「每个 NP 问题都能多项式归约到它」。于是若某个 NP 完全问题(如 3-SAT)落进 P,则一切 NP 问题都落进 P——一个下界的突破会引发整类问题的塌缩。更要命的是 §4.13 的两道屏障:证「3-SAT 不在 P」需要非相对化、非自然的证明技巧,而过去七十年所有成熟工具恰好都在这两道屏障之内。故问题之难,不在找不到证明,而在找不到不被屏障挡住的证明范式。(下一章的 PCP 定理将说明,可满足性的「近似难度」同样深不见底。)
习题 4-1(手推图灵机)。设计一台图灵机,输入是形如 1m0n 的串(m 个 1 后跟 n 个 0),输出为 1m+n(把 0 全部改写为 1)。画出状态转移图并说明头如何移动。
提示。两个状态足够:q0 向右扫描,「读到 1 就右移」,读到 0 就改写成 1 并继续右移(δ(q0, 1) = (q0, 1, R)、δ(q0, 0) = (q0, 1, R)),碰到空白则接受(δ(q0, ␣) = (qacc, ␣, R))。关键点:改写成 1 后不回头,一路扫到底;它演示了「单向扫描 = 逐格替换」这个最基本的机械动作。核实:输入 110 → 输出 111。
习题 4-2(把函数写成递归式)。用原始递归的复合与原始递归手段,写出「减法截断」Sub(x, y) = max(x − y, 0) 的递归定义,并说明为何它是原始递归的。
提示。先用前驱 Pred(0) = 0、Pred(y+1) = y(本身是原始递归),再 Sub(x, 0) = x、Sub(x, y+1) = Pred(Sub(x, y))。它是原始递归的,因为定义中每一步的第二个参数都在严格减小——原始递归天然保证处处停机。对照 §4.4:真正需要 μ-算子的,是「不知道要搜多少步」的那种搜索。
习题 4-3(判定问题的分层练习)。把下列问题分别归入「可判定/半可判定不可判定/可算但难」:① 一个给定的命题逻辑公式是否可满足;② 一个给定的一阶语句是否有效;③ 一台给定的机器在给定输入上是否停机;④ 一个给定的图是否存在 Hamilton 回路。
提示。① 可判定(真值表,O(2n),NP 完全但不是不可判定);② 半可判定不可判定(完备性保证枚举证明,§4.10 保证无判定器);③ 半可判定不可判定(真跑即可识别停机,§4.6 保证不可判定);④ 可算但难(NP 完全,多项式判定未知,但有限搜索必停)。要点:「NP 完全」与「不可判定」是两回事——前者有算法只是怕慢,后者没有算法。
习题 4-4(语法还是语义)。对每个性质判断它是否可由 Rice 定理判为不可判定:① 程序恰好含 3 个状态;② 程序在输入 0 上是否输出 1;③ 程序的值域是否为全集;④ 程序的转移函数是否为单值(确定性)。
提示。判据是「依赖写法还是依赖行为」。① 语法:数状态即可,可判定。② 语义、非平凡:由归约不可判定(可仿例 4-6 造机器)。③ 语义、非平凡:不可判定(值域是全集的非平凡语义性质)。④ 语法:检查转移表即可,可判定。规律:凡是问「这段程序算出什么」,基本都在 Rice 射程内;凡问「它长什么样」,基本可判定。
习题 4-5(论题的应用)。某函数 f 的定义是「把输入串 w 里第一个 0 之前的所有 1 的个数输出为一进制串」。说明它可由图灵机计算,并论证若改成「输出 w 中 1 的总个数」,函数仍可计算但实现策略有何不同。
提示。两个函数都是「有限次扫描 = 可计算」的实例,符合丘奇–图灵论题。第一个只需读表、找到第一个 0 即停(短路);第二个必须扫完整个串(全扫描)。这道题的目的是:可计算性只问「存在有限规则」,不问规则快慢——两者都在可计算类里,尽管工程上一个可能快得多。把这层区分记住,是区分解 §4.12 的前提。
习题 4-6(完整归约)。令 E = {⟨M⟩ : M 在输入 0 上停机}。证明 E 不可判定。
提示。构造归约 f(⟨M, w⟩) = ⟨M′⟩:M′ 忽略自己的输入,先模拟 M 于 w,若终止则停机。由 s-m-n 定理 f 可计算且处处停机;⟨M, w⟩ ∈ H ⟺ ⟨M′⟩ ∈ E。故 H ≤m E,E 不可判定。注意方向:必须 H ≤m E,不能反。
习题 4-7(Post 定理的应用)。已知停机问题 H 半可判定、Hc 不半可判定。由此证明:H 不可判定,且「不停机问题」不可判定。
提示。若 H 可判定,则其补 Hc 可判定,因而可被半可判定——与「Hc 不半可判定」矛盾,故 H 不可判定。「不停机」即 Hc,已知不半可判定,当然不可判定。本题巩固定理 4.26:可判定 = 两方向都能半可判定;一个方向若明显不行,另一方向就不敢乐观。
习题 4-8(Rice 定理的应用)。证明:「程序 M 所计算的函数是否是全函数(对所有输入都有定义)」这个性质不可判定。
提示。「是全函数」显然是语义性质(只看输入-输出对应)。非平凡性:常数零函数 φ ≡ 0 是全函数;处处无定义函数 ∅ 不是。故由 Rice 定理 4.23,{e : φe 是全函数} 不可判定。这道题顺带道出一个深刻事实:「这是不是一个永不卡住的程序」无法被自动判定——静态分析器永远只能给出「可能不安全」而不是「保证不卡」。
习题 4-9(复杂性的入门证明)。证明「团问题 ∈ NP」:给定图 G 与整数 k,验证「G 含 k 点完全子图」的凭证是什么?验证需要多少时间?
提示。凭证 c = k 个顶点的名单(长度 O(k log n),多项式)。验证:检查这 k 个顶点两两相邻——共 C(k,2) 对,每对查一次邻接矩阵,时间 O(k2),多项式。故团问题 ∈ NP。要证它 NP 完全,需再给一个 3-SAT ≤p 团的归约(把每个子句化成一个三角形,冲突的子句边之间连「不许同时选」的边)。
习题 4-10(屏障的理解题)。用一个具体例子说明「相对化论证不能证明 P ≠ NP」的含义:构造两个谕示 A, B(描述它们即可),使 PA = NPA 而 PB ≠ NPB,并解释为何这挡住了「模拟 + 对角化」型证明。
提示。取 B 为「停机问题的谕示」:此时 NPB 含一个 PB 判不了的语言(用对角化造),得 PB ≠ NPB;取 A 为「极强的谕示」(如 PSPACE 完全集,一步答一切 PSPACE 问题),则 PA = NPA。关键:相对化证明的每一步都不依赖机器的内部结构,故对任何谕示都不变;若它能证 P ≠ NP,也会证对所有谕示 PO ≠ NPO——与 A 矛盾。这解释了为什么 P vs NP 需要「看得见机器结构」的新证明技术。
本章 17 节结成一张网,但有清晰的骨架。本页把它画出来:箭头 A → B 表示「B 的定义、证明或结论需要 A」。
三条推理主线。① 对角化线:康托尔(1891)→ 通用机(§4.5)→ 停机问题(§4.6)→ 一阶逻辑不可判定(§4.10)→ 哥德尔不完备(第五章)。这条线只用一把刀,从实数不可数一路切到真理不可尽证。② 归约线:停机问题(§4.6)→ 归约与传递性(§4.7)→ Rice(§4.8)→ Post 对应(§4.9)→ 程序等价。这条线把孤峰繁殖成山脉。③ 资源线:图灵机(§4.2)→ 时间/空间复杂性(§4.12)→ P/NP/NPC(§4.12)→ 屏障(§4.13)→ 随机性(§4.14)。这条线把「能不能」换成「多贵」。
通向外部的接口。① 停机问题的对角化 → 第五章哥德尔第一、第二定理的同一手法;② 一阶逻辑不可判定(§4.10)与第二章完备性互为表里——完备性给半可判定,不可判定性给上界;③ 可判定片段(§4.11)→ 第六章证明助手的可判定内核;④ SAT 求解器(§4.12)→ 工业界的自动推理;⑤ 生命游戏普遍性(§4.16)→ 复杂系统与涌现计算。
一句话复盘。先把「算」写成机器,再把机器写成字符串,最后让机器读自己——三步走完,不可判定性就从字符串里长出来了。本章的技术内核,就是这三步。
本页任务。把 §4.1–4.9 的「什么能算、什么算不出」浓缩成随身卡片;复杂性、边界与普遍性在下一页。
五个必背实例。① 二进制后继机:两状态三规则;② 通用机 U:读 ⟨M, w⟩ 模拟 M——程序即数据;③ 停机问题 H:不可判定,半可判定,Hc 不半可判定;④ 空带停机 H0:由 H ≤m H0 不可判定;⑤ Post 对应问题 PCP:不可判定,半可判定。
最易混淆的三对。① 「可判定」vs「可计算」:判定针对语言(回答是/否),可计算针对函数(输出值);问题 L 可判定 ⟺ 其特征函数可计算。② 「不可判定」vs「不可计算」:同一件事的两种说法,前者用于问题、后者用于函数。③ 「不可判定」vs「半可判定」:不可判定只否定「两向都停」;半可判定肯定「一向可靠」——区分它们,等于区分「永远不知道」与「答案可能是『是』、也可能永远不出」。把这三对理清,本章上半部的地基就稳了。
本页任务。把 §4.10–4.17 的「算得多快、边界在哪、能普遍到什么程度」浓缩成三张卡片,外加方法论的封印。
| 工具 | 典型产出 | 成本/门槛 | 失效/边界 |
|---|---|---|---|
| 对角化 | 停机不可判定 | 一次构造 | 对谕示不敏感(相对化) |
| 归约 ≤m | 传播不可判定性 | 造翻译器 + 核对 | 方向必须从难到易 |
| Rice 定理 | 整类语义性质 | 一次套用 | 只覆盖非平凡语义性质 |
| 归约 ≤p | NP 完全性 | 多项式翻译 | 受两道屏障约束 |
| 去随机化 | BPP = P | 需困难性假设 | 假设本身未证 |
方法论的封印。本章全部证明只动用四种动作:编码(把机器/运行史写成串或公式)、对角化(让对象与全表作对)、归约(把难问题翻译成待测问题)、计数与构造(复杂性分类、CA 规则设计)。四个动作的调用顺序永远是:先编码(让对象成为可操作的数据),再对角化或归约(产生或搬运矛盾),最后定位(把问题放到判定地图的某一格)。这个「编码 → 对角化 → 定位」的三拍节奏,是本章乃至全册方法论的心跳。
与全书的接口总表。停机问题(§4.6)→ 第五章哥德尔不完备(同一把对角化的刀);一阶逻辑不可判定(§4.10)→ 第二章完备性的反面;可判定片段(§4.11)→ 第六章证明助手的可判定内核;SAT 与 NP 完全(§4.12)→ 自动推理与现代求解器;细胞自动机普遍性(§4.16)→ 涌现计算与复杂系统。一张地图读完,六个方向各自出发——下一站:一个系统能证到哪(第五章)。
本章最深的一课,藏在两个最常见的字里:「如果」。第一章已经把它锻成一个真值算子——只要真值表上填得干净,「如果下雨,就带伞」便与「并且」「或者」一样可以被计算。第四章往更深处推了一步:把「如果」当成机器里的控制算子。一旦写作「若读到 1 就左移,否则改写为 0 并停」,纸带上的推导就成了可以逐格执行的动作——「如果」从一句判断,变成一条指令。
控制算子一落地,两件大事同时发生。第一件是普遍性。既然「如果」能被写进状态转移表,而状态转移表又能被编码成字符串,那么同一台机器就能读出另一台机器的规则、照着执行,通用图灵机(§4.5)由此诞生。程序变成数据,「算一切可算之物」的机器不再需要为每个任务重新接线。这一步的全部秘密,只是让「如果」的判据由数据来提供。
第二件是不可判定。同一枚算子,也让机器可以把「如果」用在自己身上:「如果这台机器在自身编码上停机,那么……」——自指从此出现,对角化随之启动(§4.6)。停机问题之所以啃不动,正因为它问的是一台机器在含自身的情形下的命运,而这类追问恰好长在「如果」的裂缝里。「如果」既是计算得以起飞的原因,也是计算撞上墙壁的原因。
留下的自问:当「如果」被彻底算子化,得到了什么,又失去了什么?机器能忠实执行任何给定的规则,却无法对自己在一切情形(尤其含自身的情形)上的行为给出预告;它能算出答案,却不能替自己担保「一定会算出」。这条自问的下一站是第五章的哥德尔——那里,「可证」与「真」的分野同样长在自指之上;而两者的技术内核,都是本章那三步:编码、对角化、定位。
一句话记住本章:机器能执行任何被写下的规则,却写不出关于自己的那张完整命运表——能算与会算,是两件事。
任务。第二章参观过希尔伯特几何、一阶算术与 Tarski 初等欧氏几何三套公理系统;本章 §4.11 又给出一架天平——表达力越强,判定性越弱。本页把这架天平搬进图纸:亲手为一种几何写一组一阶公理,再追问它落在天平哪一端。这是一次「设计公理系统」的手艺演练,也是一次判定性的实测。
第一步:挑语言,等于挑命运。设计公理系统的第一件事不是写公理,而是选语言。语言选得「瘦」,判定性有救;选得「胖」,麻烦立刻上门。两条路线。路线 A(实闭域语言):个体域是实数,非逻辑符号只有 <、+、·、0、1,公理取「有序域」加「每个奇次多项式有根」再加初等连续公理模式。路线 B(宽语言):在路线 A 的符号里再塞进一个谓词 N(x),规定它恰好在 0, 1, 2, … 上取真。
第二步:写公理(路线 A)。把「初等平面几何」翻译进路线 A 的语言:点即实数对 (x, y),直线即一次方程 ax + by = c(a, b 不同时为零),「点 P 在直线 ℓ 上」即代入后等式成立,「A 介于 B, C 之间」「AB = CD」也都化为实数上的多项式等式与不等式。于是整套初等欧氏几何成了实闭域理论的「外套」——几何命题的真假,被翻译成实数语句的真假。
第三步:追问判定性(最关键的一步)。Tarski(1948)证明:实闭域理论有量词消去,因而完备且可判定——给任一阶语句,存在算法在有限步内判定它在实数结构中为真还是为假。由于翻译保持真假,初等欧氏几何也落在可判定的一格。这是一座出人意料的飞地:一阶逻辑整体不可判定(§4.10),可这片子理论却完全可判。对照 §4.11 的天平,路线 A 之所以站得稳,正因为语言被死死限制在「<, +, ·, 0, 1」这五个符号上。
第四步:找边界(把天平踩翻)。现在换路线 B——语言里只多加一个谓词 N(x),公理里规定它恰在 0, 1, 2, … 上真。这一步看似无害,却足以让理论重新编码自然数连同加法与乘法,从而解释 PA,进而继承 §4.10 的不可判定。教训:判定性不是「几何」这个主题自带的,而是「语言有多省」给的;每多加一点表达力,都要付出判定性的代价。
进阶(选做)。① 删去平行公设,只留关联与次序公理(绝对几何),判定性还在吗?② 保留全部欧氏公理,但把个体域换成「点集」并允许对集合作二阶量化(「存在一个点集使……」),判定性会发生什么变化?(提示:二阶逻辑没有完备的有限判定系统。)这两问没有现成答案可背,需要自己摆天平、动手权衡——把边界说清,比背下一句结论更有价值。
实验目的。丘奇–图灵论题说「有效可计算 = 图灵机可算」,它不是定理,靠的是多种模型彼此等价这条经验证据。本实验把证据跑出来:用三套彼此独立的计算模型——图灵机(纸带 + 状态表)、递归函数(原始递归的加与乘)、λ 演算(丘奇数的加与乘)——对同一批函数分别求值,检验结论是否完全一致;再加一组「通用图灵机读 ⟨M⟩ 自模拟」的对拍。脚本见 qa/exp_c4_f.py,输出见 qa/exp_c4_f_out.txt。
核心代码(图灵机模拟与递归加法)。
BLANK = '_'
def tape_to_str(tape): # 纸带渲染成字符串
lo, hi = min(tape), max(tape)
return ''.join(tape.get(i, BLANK) for i in range(lo, hi + 1)).strip(BLANK) or BLANK
class TM:
def __init__(self, rules, q0, qacc): # 规则:(状态,读符)->(新状态,写符,'L'/'R')
self.rules, self.q0, self.qacc = rules, q0, qacc
def run(self, tape_str, max_steps=100000):
tape = {i: c for i, c in enumerate(tape_str)} # 稀疏纸带:下标->符号
head, state = 0, self.q0
for step in range(max_steps + 1):
if state == self.qacc:
return '接受', tape_to_str(tape), step
sym = tape.get(head, BLANK)
if (state, sym) not in self.rules: # 无规则可用=停机
return '停机', tape_to_str(tape), step
ns, wsym, move = self.rules[(state, sym)]
tape[head] = wsym
head += 1 if move == 'R' else -1
state = ns
# 一元加法机:输入 1a 0 1b,输出 1a+b
ADD_TM = TM({('q0','1'):('q0','1','R'), ('q0','0'):('q1','1','R'),
('q1','1'):('q1','1','R'), ('q1',BLANK):('q2',BLANK,'L'),
('q2','1'):('qacc',BLANK,'L')}, 'q0', 'qacc')
def add(x, y): # 递归式 add(x,y+1)=S(add(x,y))
for _ in range(y):
x = x + 1
return x
核心代码(λ 演算的归约与丘奇加法)。
def subst(t, name, repl): # 捕获规避的替换 t[name:=repl]
if t[0] == 'v':
return repl if t[1] == name else t
if t[0] == 'l':
y, body = t[1], t[2]
if y == name: return t
if y in free(repl): # 变量名冲突则改名,再替换
y2 = fresh(y)
body = subst(body, y, ('v', y2))
y = y2
return ('l', y, subst(body, name, repl))
return ('a', subst(t[1], name, repl), subst(t[2], name, repl))
def normalize(t, budget=[200000]): # 最左最外(normal order)归约
if t[0] == 'v': return t
if t[0] == 'l': return ('l', t[1], normalize(t[2], budget))
f = normalize(t[1], budget)
if f[0] == 'l': # β-归约:(λx.b) a --> b[x:=a]
return normalize(subst(f[2], f[1], t[2]), budget)
return ('a', f, normalize(t[2], budget))
PLUS = ('l','m',('l','n',('l','f',('l','x',
('a',('a',('v','m'),('v','f')),('a',('a',('v','n'),('v','f')),('v','x')))))))
对拍结果摘要。对拍一(加法,三模型):六组 (n, m) 全部一致,例如 (3, 2) → 5、(4, 4) → 8、(6, 7) → 13,图灵机、递归函数、λ 演算三者答案逐格相同。对拍二(乘法,递归 vs λ):(5, 4) → 20、(6, 6) → 36,两模型一致。对拍三(通用机 vs 直跑):把加法机编码成 Q=q0;F=qacc;q0|0|q1|1|R;…,通用机读 ⟨M⟩ 后对输入 111011 输出 11111,与直接跑机器完全相同——解释执行不改变结果,程序真的成了数据。
实验报告要求。① 自拟三组 (n, m)(含 0 与较大值),重跑对拍并解释每一组的一致性。② 说明为何三模型一致只是论题的经验证据而非证明:一致说明这些模型互相可模拟,但「一切有效可计算」是全称断言,无法被有限次实验证成。③ 把 λ 演算的归约顺序从 normal order 换成 applicative order(先归约实参),讨论丘奇数乘法会不会卡住(提示:会——求值策略会影响终止性,但可计算类不因策略而改变,这正说明「可计算」是与策略无关的概念)。
两套「照步骤就能算」的传统。公元前三百年左右,欧几里得《几何原本》卷七给出「辗转相除」:反复以较小数除较大数取余,直到余数为零,即得最大公约数,这是人类最早被完整写下的算法之一。约公元一世纪成书的《九章算术》则在「方田」章记下「更相减损术」:反复用大数减小数,直至两数相等,所得即最大公约数——与辗转相除同一件事,只是用减法写成。同类「术」遍布全书:刘徽(三国魏,263 年注《九章算术》)用「割圆术」倍增圆内接正多边形的边数,把圆周率逼近到精确分数;贾宪(北宋,约十一世纪)的「增乘开方法」把开方化成一套可反复执行的程序;秦九韶《数书九章》(南宋,1247 年)的「大衍总数术」给出求解一次同余方程组的一般算法。它们共同的名字是「术」——给定既定的操作序列,照做即得结果。
「术」与「算法」是同一件事的两个名字。把《九章》的一条「术」摊开来看,它有输入、有确定的每一步、有终止条件,几乎就是一台图灵机的说明书:算筹在案上游走,等价于读写头在纸带上移动。西方这条线到近代汇成三段:莱布尼茨(1673 年的计算器、1679 年关于二进制的思考)把「算计」与「推理」联系起来;巴贝奇(1822 年差分机)第一次让机械执行整套求值步骤;霍尔瑞斯(1890 年打孔卡制表机)把数据与「指令」都记在卡片上。1936 年,图灵把这一切收束成一台抽象机器。中国算法传统与之相映:算筹(战国已见)与算盘(宋元普及),都是把「术」落在手边工具上的努力。
为什么这一步差别值得记住。两支传统都把推理与计算推到了能执行的田地,差别在于是否把「算法」本身也当作一个可研究的对象。西方的形式化一路走到「推理本身成为数学对象」,于是才有把「步骤」抽象成状态表、递归式、λ 项的可能——也才有可能追问「停机问题」「可判定性」「复杂度」这类元问题。本章的技术内核,正是这条「形式化—自省」线的延长。而中国算学的贡献落在另一面:它把「算得出」当作理所当然的工程能力,《九章》式的「术」提醒我们,可计算性理论关心的从来不是某一个具体算法,而是「全体算法」的边界。
札记的注脚。本册选择站在「可检查、可执行」这条线上说话,是接着希腊与近代欧洲的传统往下讲;但记住另一条更古老的经验:在不同文明里,「照步骤就能算出」都被实践了上千年。数理逻辑的独特贡献,不在于它发明了「按步骤算」,而在于它找到了把「步骤」本身写成既能被机器执行、也能被机器追问的方式。
| 条目 | 内容 | 出处 § |
|---|---|---|
| 判定问题 Entscheidungsproblem | Hilbert 1928 提出:是否存在算法判定任一阶语句的有效性;1936 Church–Turing 给出否定 | §4.1 |
| 希尔伯特第十问题 | 丢番图方程是否有整数解;1970 Matiyasevich(承 Davis–Putnam–Robinson)给出否定 | §4.1 |
| 图灵机七元组 | (Q, Σ, Γ, δ, q0, qacc, qrej) | §4.2 |
| 格局 | u q v = 纸带 + 头位置 + 状态;三种命运:接受 / 拒绝 / 永不停机 | §4.2 |
| 丘奇–图灵论题 | 有效可计算 = 图灵机可算(论题,非定理;证据为多模型等价) | §4.3 |
| 原始递归 / μ-递归 | 复合 + 原始递归;μ-算子引入最小化(可能不停,故外包一层「是否停机」的检查) | §4.4 |
| λ 演算 | Church 1936;β-归约、丘奇数;与图灵机等价(Church–Turing) | §4.4 |
| 通用图灵机 | 读 ⟨M⟩ 自模拟;程序即数据 | §4.5 |
| 枚举定理 / s-m-n | φe 的枚举与参数化;归约函数「可计算且处处停机」的合法性来源 | §4.5 |
| 停机问题 H | {⟨M, w⟩ : M 在 w 上停机};不可判定(对角线),半可判定;Hc 不半可判定 | §4.6 |
| 归约 ≤m | A ≤m B:会解 B 就会解 A;传递;A 不可判定 ∧ A ≤m B ⇒ B 不可判定 | §4.7 |
| Rice 定理 | 关于可计算函数的任一非平凡语义性质不可判定 | §4.8 |
| 三分法 | 可判定 ⊊ 半可判定(r.e.)⊊ 全部语言 | §4.9 |
| Post 定理 | L 可判定 ⟺ L 与 Lc 都半可判定(1944) | §4.9 |
| Post 对应问题 PCP | 骨牌拼接问题;不可判定、半可判定 | §4.9 |
| 一阶逻辑不可判定 | Val 半可判定(完备性)却不可判定(Church–Turing 1936) | §4.10 |
| 可判定片段 | 命题逻辑、一元谓词逻辑(Löwenheim 1915)、Presburger 算术(1929)、实闭域(Tarski 1948,故初等欧氏几何可判定)、∃*∀* 前缀类 | §4.11 |
| P / NP | 确定性多项式时间 / 多项式时间验证器 + 多项式长度凭证 | §4.12 |
| NP 完全 | NP 中最难;对 ≤p 归约封闭 | §4.12 |
| Cook–Levin 1971 | SAT 是 NP 完全的 | §4.12 |
| NPC 实例链 | SAT ≤p 3-SAT ≤p 团 ≤p 顶点覆盖 ≤p Hamilton 回路 | §4.12 |
| 相对化屏障 | Baker–Gill–Solovay 1975:存在谕示使 P = NP,也存在谕示使 P ≠ NP | §4.13 |
| 自然证明屏障 | Razborov–Rudich 1997:构造且有用的电路下界会与伪随机性冲突 | §4.13 |
| 去随机化 | BPP;在困难性假设下 BPP = P | §4.14 |
| 物理丘奇–图灵论题 | 物理可实现的「计算」不越图灵机;谕示、闭合类时曲线(Deutsch 1991)、BSS 理想实数 | §4.15 |
| 元胞自动机 | Rule 110(Cook 2004)与生命游戏(Conway 1970)皆图灵完备 | §4.16 |
| 判定地图 | 可判定 / 半可判定 / 不可判定 / 复杂性的四格定位 | §4.17 |
符号卡。⟨M⟩ 机器编码;≤m 多一归约;≤p 多项式归约;r.e. 递归可枚举;H 停机问题;H0 空带停机;Val 有效式集合;NPC NP 完全;BPP 有界错误概率多项式时间;δ 转移函数;␣ 空白符。
定理卡(一句话)。① 停机问题不可判定(对角线法,§4.6)。② Rice:一切非平凡语义性质不可判定(§4.8)。③ Post:L 可判定 ⟺ L 与 Lc 都半可判定(§4.9)。④ 一阶逻辑有效性不可判定,但可判定片段丛生(§4.10–4.11)。⑤ Cook–Levin:SAT 是 NP 完全的(§4.12)。
易错三坑。① 把「NP 完全」当成「不可判定」——前者有算法、只是可能太慢,后者没有算法(§4.12 与 §4.6 不能混)。② 把丘奇–图灵论题当成定理——它是论题,靠多模型等价的证据支撑(§4.3)。③ 把「不可判定」当成「无意义」——不可判定是相对于某套规则的事实,其可判定片段往往就在旁边(§4.11)。
下一步。本章的刀已经磨好:编码、对角化、归约、定位。第五章的哥德尔将以同一套动作回答另一个问题——「一个足够强的形式系统能证到哪」,那里,停机问题的裂缝会以「系统证不了自己的一致性」的面貌再出现一次。
前四章铺出一条从「真假」到「可计算」的路:命题的真假被真值表摊平(第一章);一阶语言的推理被完备性定理担保——凡有效的都证得出(第二章);证明本身成了可被切割消除的机械对象(第三章);而「什么能被机器算出来」被图灵机划定了疆界(第四章)。本章把这四件事拧成一个问题:当一个形式系统强到足以谈论自己的句子与证明时,它能证出多少真理?哥德尔 1931 年的判决是:不足——永远有一条真句子,系统既证不出它,也证不出它的否定。
本章的路线是一条自我指涉的上升阶梯,每一级都踩在前一级的编码之上:
第一阶(§5.1–5.2)——形式算术的骨架。把自然数的加法与乘法写成公理,得到皮亚诺算术 PA 与它的精简版罗宾逊 Q;再确认一切「可计算的数论函数」都能在这套语言里被表示。这是全章的地基:没有可表示性,后面的编码无从谈起。
第二阶(§5.3–5.5)——算术化。哥德尔的天才一步:把符号、公式、证明序列统统翻译成自然数。语法由此成为算术的一部分,「证明」变成一道数论判定,「某句可证」变成「存在一个数 p 使某原始递归关系成立」。再配上对角线引理,系统便获得了谈论自己的能力。
第三阶(§5.6–5.9)——两条定理。造出哥德尔句 G(「本句不可证」):一致的 PA 证不出 G,ω-一致的 PA 也证不出 ¬G;罗塞尔 1936 用更精巧的对角句把条件降为只需一致性;第二定理进一步宣布 Con(PA) 自身不可证——希尔伯特纲领的原始形式就此终结。
第四阶(§5.10–5.17)——边界与独立。反转视线:并非所有理论都不完备(实闭域、Presburger 算术既完备又可判定);真与可证判然两分(Tarski 不可定义性);独立性有很多面孔,最著名的一张是连续统假设——哥德尔 1938/1940 用可构造宇宙 L、科恩 1963 用力迫法,两路合璧把它判为独立于 ZFC。这一阶还清点误用、Chaitin 的 Ω 与 Diophantus 方程。
读本章只需带三件随身行李:初等数论(整除、素数、同余)、一阶逻辑的语法与语义(第二章)、以及一点「把程序当数学对象」的耐心(第四章)。行李齐备时,直接上第一级台阶——不过在开工前,先认识两位常驻嘉宾。
常驻嘉宾甲:哥德尔句 G。它是本章的主角,一句「照镜子」的算术命题。它将在 §5.5 被造出来,在 §5.6 展示「既证不出也证不出否定」的全套证明,在 §5.8 转而充当第二定理的引信,在 §5.11 与 Tarski 的真谓词狭路相逢。它的构造只用一次自指,却贯穿全章。常驻嘉宾乙:连续统假设 CH。它不属算术,而属集合论;但它与哥德尔定理共享同一种命运——独立。它将在 §5.12 亮相,在 §5.13 迎来哥德尔与科恩的联合判决。
★★ 要让「算术能谈论自己」,先得把算术本身写成一套形式系统。本节给出皮亚诺算术 PA 的语言与公理,并把「加法乘法从公理推出」这件事重演一遍——这是哥德尔编码的舞台。
罗宾逊 Q。七条「开天辟地」式的公理就足以启动一切(罗宾逊 1950):
Q1 ∀x (Sx ≠ 0);Q2 ∀x∀y (Sx = Sy → x = y);Q3 ∀x (x ≠ 0 → ∃y (x = Sy));Q4 ∀x (x + 0 = x);Q5 ∀x∀y (x + Sy = S(x + y));Q6 ∀x (x · 0 = 0);Q7 ∀x∀y (x · Sy = x · y + x)。
Q1、Q2 说 0 不是后继、后继是单射,Q3 说 0 之外的每个数都是某个数的后继——这三条刻画了 ℕ 的「链式」骨架;Q4–Q7 是加法与乘法的递归定义式。注意:Q 极弱,它甚至证不出 ∀x (x + 0 = 0 + x) 这类交换律;但它已强到足以表示一切可计算函数(§5.2),因而足以承载哥德尔论证。
[ φ(0, ȳ) ∧ ∀x (φ(x, ȳ) → φ(Sx, ȳ)) ] → ∀x φ(x, ȳ).
归纳模式是一条模式(无穷多条公理,每个公式一条),不是单条公理——这正是 PA 与「二阶算术」的分水岭。加上归纳,交换律、分配律、乃至一切初等数论定理都可逐步推出。
为什么还要看非标准模型。紧致性定理(第二章)保证:PA 除了标准模型 ℕ,还有非标准模型——它们含「无穷大」的元,且不可与 ℕ 同构。这一步很关键:哥德尔句 G 在 ℕ 中为真,却可能在某些非标准模型中被可证性谓词「误判」;两条定理的精细差别正藏在这里。
本节的一句话总结:PA 是「把自然数写死成符号」的最小足够强的系统。足够强,是为了让编码跑得动;足够形式,是为了让「证明」本身变成可以计算的字符串。下一节把「可计算」这一侧补齐:原始递归函数。
★★★ 哥德尔论证的发动机是一类特殊的数论函数:原始递归函数。它们只靠「迭代」生成,却已覆盖绝大多数可计算的数论函数;而每一个原始递归函数都能被 PA 的公式「逐点算准」。本节把这两件事立成定理。
f(x̄, 0) = g(x̄), f(x̄, Sy) = h(x̄, y, f(x̄, y)).
第二式是全部魔力的来源:它让 f(x̄, n) 由 n 步迭代唯一确定。加、乘、幂、前驱、截断减法、阶乘、素数序列、整除判定……逐一都能写成这种「先算 0,再拿前一步的结果算下一步」的形式。甚至连「有界递归」「有界求和」「有界最小化」都保持原始递归性:只要量词被一个已算出的数封顶,就不会丢失可计算性。
原始递归函数类对复合、原始递归、有界求和 Σi ≤ n f(x̄, i)、有界乘积、有界最小化 µi ≤ n[f = 0]、以及分段定义均封闭。此外由 ∃i ≤ n、∀i ≤ n 表达的「有界判定」其指示函数仍原始递归。
设 f 是原始递归函数。(a) 存在公式 φf(x̄, y) 使对一切 n̄:f(n̄) = m 蕴含 Q ⊢ ∀y(φf(n̄, y) ↔ y = m)——即 PA(乃至 Q)能把 f 的值「算准且算唯一」。(b) 取 φf 为 Σ1 形,则每个真正为真的 Σ1 句子都在 Q 中可证(Σ1-完全性);对 Δ0 句子,真与可证一一对应。
证明思路(归纳于构造)。初始函数显然可表示。复合直接拼装;原始递归用归纳模式证明「∃! y 使 φ(x̄, y, n)」随 n 归纳成立。(b) 的关键是 Δ0-完全性:一个有界量词句子可真假「机械地」逐点核验,PA 能逐步复演这套核验,故真的 Δ0 句子可证、假的其否定可证;再给 Σ1 的外层存在量词配上一个具体见证数即可。∎
本节的收获可以浓缩成一句操作口号:凡是「一步步能算出来」的东西,PA 都能「一步步证出来」。下一节把这句话用在语法自己身上——符号、公式、证明都是有限字符串,因而都是可计算的对象。
★★★★ 算术要谈论自己,第一步得让「符号串」变成「数」。哥德尔的方案朴素而彻底:给每个符号配一个编号,再把有限的符号串编成单个自然数。本节写全这套算术化。
编号本身没有魔力,关键是复合:一串符号 s1s2⋯sk 编成一个数,且能反解。哥德尔用素数幂:
取前 k 个素数 p1 = 2, p2 = 3, p3 = 5, …,令
⌜s1s2⋯sk⌝ = p1#s1 · p2#s2 · … · pk#sk.
由算术基本定理,这个分解唯一,故编与解都是可逆的原始递归操作。框架内的句子因此各得一个自然数,记作 ⌜φ⌝。
素数幂法美中不足:数长得太快(一个八符号公式可到 1055 量级),且「变长序列」不便做统一运算。哥德尔另辟一条定长的路——用一个二元函数把任意长序列压成一对数:
定义 β(b, c, i) = b mod (1 + (i+1)c)。β 引理:对任意有限序列 a0, …, ak,存在 b, c 使 β(b, c, i) = ai 对一切 i ≤ k 成立。
证明。取 c 为 (k+1)! 的倍数且大于 maxi ai。则各模数 di = 1 + (i+1)c 两两互素(若素数 q 同时整除 di 与 dj,i < j,则 q | (j−i)c;又 q ∤ c,于是 q | (j−i) < k+1,从而 q | c,矛盾)。由中国剩余定理,方程组 b ≡ ai (mod di) 有解 b,且 ai < di 保证余数正确。∎
β 引理的意义:「一列数」与「一对数」之间可双向翻译,且翻译过程原始递归。于是证明序列(一列公式编码)也能压成一对数 (b, c),再压成单个数。语法对象的「可计算操作」(拼接、代入、提取第 i 项)全部落在原始递归函数的范围内——这正是下一节判定谓词得以存在的原因。
一个必须澄清的误会。编码不是「把逻辑翻译成算术」,而是「给逻辑对象编号,使逻辑操作成为算术操作」。编号是人为的、任意的,但只要固定一张编号表,「是不是公式」「是不是证明」这类问题就变成了确定的算术问题。下一节把这类问题写成谓词。
★★★★ 编码就位后,本节把「这段符号串是证明」与「这个公式可证」写成 PA 的公式。秘诀仍是上一节的口号:凡是可逐步核验的,都可写成原始递归(进而 Σ1)谓词。
由编码与原始递归性,下列谓词都用 Δ0 或 Σ1 公式表示:Term(x)「x 编码一个项」;Form(x)「x 编码一个公式」;Ax(x)「x 编码一条逻辑公理或 PA 非归纳公理」;AxI(x)「x 编码一条归纳公理」;以及代入函数 Sub(x, v, y)「把编号 x 的公式中编号 v 的变元代入项 y」——它由「逐符号查找替换」实现,是原始递归的。
现在到了枢纽:把「p 编码一个以 x 结尾的合法证明」写成公式。设 p 经 β 解码给出证明序列 (δ1, …, δn),则条件为:末项 δn = x,且每一 δi 要么是公理(Ax ∨ AxI),要么由更早的项经推理规则(分离规则与概括)得到。
「p 是 x 的一个证明」记作 Proof(p, x),它是一个 Δ0 公式(所有量词有界,因为序列长度与各项都不超过 p)。由此定义
Prov(x) :≡ ∃p Proof(p, x), Con(PA) :≡ ¬Prov(⌜0 = 1⌝).
Prov(x) 是 Σ1 公式;它读作「编号为 x 的公式可证」。注意 ¬Prov(⌜φ⌝)(不可证)已是 Π1,而 Π1 句子的真一般不等于可证——这正是哥德尔句的温床。
可证性的三条形式律。Prov 并非任意谓词,它满足三条可推导的性质(Hilbert–Bernays–Löb 条件),§5.8 证明第二定理时全靠它们:
三条律的证明都是「具体操作的算术化」:把拼接、加尾巴、再编码这些动作写成原始递归函数,再用可表示性(定理 5.6)在 PA 内验证。形式上繁琐,思想上却只有一句话——对一个证明做机械加工,还是在制造证明。
本节收尾留一个预告:既然 ¬Prov(x) 是可写出的公式,那么只要能用自指把它「喂给自己」,就能造出「本句不可证」的句子。把公式喂给自己,靠的是下一节的对角线引理。
★★★★ 上一节把「可证」写成了算术谓词 Prov(x),它一只手伸向语法、一只手伸向算术。现在要让它「照镜子」:让一个公式拿到它自己的编号当输入。完成这一步的机器叫对角线引理,又称不动点引理,是全章最精巧、也最容易被误读的一环。
先说清楚要造什么。给定任意一个含单自由变元的公式 φ(x),希望有一个句子 σ,使 PA 内可证 σ ↔ φ(⌜σ⌝):「σ 成立」与「φ 作用在 σ 的编号上成立」彼此等值。当 φ 取 ¬Prov(不可证)时,这把「本句不可证」的自指句子就直接送到手上。
对任意只含单自由变元的公式 φ(x),存在句子 σ 使
PA ⊢ σ ↔ φ(⌜σ⌝).
这里的 σ 称为 φ 的不动点:不动点方程 x = φ(x) 在「公式的世界」里的对应物。
证明。三步走:把对角化写进语言,让公式吃下自己的编号,再把表示性质代入。
这里必须拆掉一个普遍的误会:σ 并不「包含自己」。语法上 σ 是一个长度固定的有限符号串;所谓自指,只是「σ 的编号」作为一项出现在 σ 内部——代号进得去,字面进不去。这正是编码换来的自由:语法对象一旦成为数,就能被算术函项搬运、替换、再回投。自指因此不是诡辩,而是一步合法的算术运算。
把对角线引理当作一台「自指发生器」:投进去任意一个单变元公式 φ,出来一个句子 σ,它断言自己满足 φ。§5.6 投进 ¬Prov 得到「本句不可证」,§5.8 投进 Prov(x) → ψ 得到第二定理的钥匙。同一台机器,反复使用。
下一节就要开机。把 φ(x) :≡ ¬Prov(x) 投入对角线引理,得到的 G 便是全章的主角;证明它「既不可证、也不可否证」,就是哥德尔第一不完备定理。
★★★★★ 万事俱备。本节把第一不完备定理完整证一遍:构造哥德尔句,证明它不可证;再证明它的否定也不可证。全程只用两条元假设——一致性与 ω-一致性,以及上一节备好的对角线引理与可证性三律。
PA ⊢ G ↔ ¬Prov(⌜G⌝).
把 Prov(⌜G⌝) 读作「存在一个证明,其末项是编号 ⌜G⌝ 的公式」,则 G 说的正是:「本句没有证明」——一句不折不扣的「本句不可证」。
设 PA 一致。则 (a) PA ⊬ G;若 PA 还 ω-一致,则 (b) PA ⊬ ¬G。于是 G 在 PA 中既不可证也不可否证:PA 不完备。
证明。两个方向分开做。
G 是真的。用元语言看:若 G 为假,则 Prov(⌜G⌝) 真,即 G 有证明,于是 PA 证出一个假句——与 PA 的可靠性(soundness,真公理只推真句)冲突。故 G 在标准模型 ℕ 中为真。合起来即第一定理的不朽结论:存在真的、却不可证的算术句子——真理多于可证。
推广到一切「足够强」的系统。以上论证只用到三样东西:公理集可递归枚举、系统能表示原始递归函数、以及可证性谓词满足三律。因此定理对一切一致且可递归公理化、并足以承载基本算术的理论 T 成立——ZFC 也罢,任何更强的系统也罢,都逃不过同一判决。「足够强」是定理的条件,「不完备」是定理的结论。
★★★★ 第一定理走通了,却留了一根刺:证明 ¬G 不可证时用到了 ω-一致性。ω-一致性比一致性强得多,且极难验证——能否只用一致性就把两条都拿下?罗塞尔 1936 给出了肯定答复。
罗塞尔的巧思是:与其断言「本句不可证」,不如断言「若本句可证,则其否定已被更早证出」。这样,两个方向的矛盾都只需拿「证明的大小」作比较,而比较是大小的算术,无需兑现存在句的见证。
PA ⊢ R ↔ ∀p( Proof(p, ⌜R⌝) → ∃q( q < p ∧ Proof(q, ⌜¬R⌝) ) ).
若 PA 一致,则 PA ⊬ R 且 PA ⊬ ¬R。即:只需一致性,无需 ω-一致性,即可判定系统不完备。
证明思路(只用一致性)。记 p*、q* 为 R 与 ¬R 的最小证明(若存在)。
两根刺的比较。哥德尔句把「不可证」正面说出来,验证它需要「没有见证」这种全称直觉,故要 ω-一致性帮忙;罗塞尔句则把「不可证」换成「否定先到」——两个证明的大小可以直接比较,比较是 Δ0 的,于是只需一致性。代价是句子更长、构造更绕,但逻辑上更干净。今天教科书讲的「不完备定理」,通行版本正是罗塞尔版。
罗塞尔的改进提示:一条定理的「假设」也是可以优化的对象。哥德尔 1931 用 ω-一致性换来简洁,罗塞尔 1936 用构造换来更弱的假设;此后「1-一致性」「可靠性」「Σ1-可靠性」逐级弱化,成为证明论里一门专门的手艺(§5.17)。
★★★★★ 第一定理说:有一个真句证不出来。它有一个更惊人的推论——那个证不出来的真句,恰恰就是「本系统一致」。本节证明第二不完备定理:PA 证不出自己的一致性。
Con(PA) :≡ ¬Prov(⌜0 = 1⌝),
读作「矛盾句 0 = 1 不可证」。由 D1、D3(§5.4),这是一个 Π1 句:它说的是「对一切证明 p,p 都不是 0 = 1 的证明」。注意:这是一句算术句,不是元语言里的断言;「真正的一致性」与「PA 能写出的 Con(PA)」是两码事,第二定理的全部张力就在这条缝里。
设 PA 一致,则 PA ⊬ Con(PA)。更精确地:PA ⊢ Con(PA) → G,其中 G 是 §5.6 的哥德尔句;既然 PA ⊬ G,也就 PA ⊬ Con(PA)。
证明。关键是「把 §5.6 的证明搬进 PA 内部」,而这正需要可证性三律。
一句话收尾。若 PA 能证 Con(PA),则由上式它也证出 G,与第一定理(PA ⊬ G)冲突,故 PA ⊬ Con(PA)。(此处用到「PA 一致」这个元假设,因为第一定理的 (a) 正是以之为前提。)
对任意句子 ψ:若 PA ⊢ Prov(⌜ψ⌝) → ψ,则 PA ⊢ ψ。
证明思路。用对角线引理取 λ 使 PA ⊢ λ ↔ (Prov(⌜λ⌝) → ψ)(取 φ(x) :≡ Prov(x) → ψ)。由 D1、D3 可得 PA ⊢ Prov(⌜λ⌝) → Prov(⌜Prov(⌜λ⌝) → ψ⌝),进而 PA ⊢ Prov(⌜λ⌝) → (Prov(⌜Prov(⌜λ⌝)⌝) → Prov(⌜ψ⌝));再由 D2 消去中间的 Prov(⌜Prov(⌜λ⌝)⌝),得 PA ⊢ Prov(⌜λ⌝) → Prov(⌜ψ⌝)。结合假设 Prov(⌜ψ⌝) → ψ 与 λ 的定义,推出 PA ⊢ λ,再用 D1、假设与定义得 PA ⊢ ψ。∎
Löb 定理的读法。它说:一个句子若「只要可证就为真」这件事本身可证,那它早就被证出了。把 ψ 取成 0 = 1,Löb 定理立刻给出第二定理的「反面教材」:PA 证不出 Prov(⌜0 = 1⌝) → 0 = 1,否则 PA 就自证矛盾。第二定理、Löb 定理、哥德尔句,是同一枚硬币的三面。
「内外有别」才是第二定理的真正教训。在同一页纸上,两句话看起来很像,地位却天差地别:一句是元语言的断言「PA 是一致的」,另一句是 PA 内部写出的公式 Con(PA)。前者站在这套算术之外,用更强的视野(例如信赖标准模型 ℕ)说话;后者只是系统内一个编号固定的符号串,系统对它的「理解」完全由公理与推演规则决定。第二定理说的正是:外面的那句真话,进不了里面的门。这不是缺陷,而是「系统内的视角」与「系统外的视角」之间一道恒久的分界线——它将在 §5.11 由 Tarski 用「真不可定义」再刻画一次。
★★★★ 第二定理落地的那一刻,震动的不是某条数学命题,而是 1900 年以来一整套关于「数学确定性」的纲领。本节交代希尔伯特纲领被否定到什么程度,以及证明论界拿出的替代答卷。
希尔伯特纲领的三根支柱。① 形式化:把全部数学(含分析)写成一套形式系统,命题即符号串;② 完备性:每个真命题都可被推出(希尔伯特最初正是用「完备」称呼这一目标);③ 一致性:用有限主义(finitary)的方法——只看有限符号串、不用实无穷——证明这套系统不会推出 0 = 1。若三柱俱全,数学的确定性就一劳永逸地钉在纸上:任何数学命题,理论上都可机械地判出真假。
希尔伯特 1900 年在巴黎提出的第二问题,正是第 ③ 柱的一个具体化:证明算术与分析的一致性。它被看作纲领的试金石——若能证明,则「数学无矛盾」不再是信仰而成为定理。
第二不完备定理直接命中第 ③ 柱:任何一致、可递归公理化、且足以承载算术的系统 T,都不能在自己的框架内证明自身的一致性。把 T 取为 PA,得到 PA ⊬ Con(PA);取为 ZFC、取为分析的形式化系统,结论一样。于是:「用有限主义方法证明算术不一致是不可能的」这一原始形式的纲领被否定——因为「有限主义可证」蕴含「PA 可证 Con(PA)」,而后者恰被第二定理堵死。
第二定理「否定」的是什么,没有否定什么。它否定的是「系统自证一致性」。它并不说明算术不一致(PA 至今被普遍相信是一致的),也不说明一致性无法被证明——只是那证明必须动用系统之外的更强原理。这条缝隙,正是 Gentzen 的入口。
在 PA 之外、但仍属构造性的框架中,可以获得一致性证明:把「PA 无 0 = 1 的证明」化归为「不存在关于序数 ε0 的无穷下降链」,再对 ε0 做超限归纳。这套归纳超出 PA 的归纳模式(PA 只能对自然数归纳),却仍在相当强的构造意义下可行。于是
TI(ε0) ⊢ Con(PA),
其中 TI(ε0) 表示「沿 ε0 的超限归纳原则」。Gentzen 的另一半工作——切割消除(见第三章)——给出证明的「范式」,使一致性变成「空相继式不可导出」这一结构性事实。
替代答卷:相对一致性证明与序数分析。Gentzen 的结果把一致性证明从「绝对」变成「相对」:Con(PA) 相对 ε0-归纳成立。这条思路发展成二十世纪证明论的主干——序数分析:为每个形式系统配一个「证明论序数」,序数越小、系统越弱,而「系统的一致性 ⟺ 其序数下的超限归纳可用」。PA 的证明论序数正是 ε0。希尔伯特纲领的原始形态虽然终结了,它的精神——把「证明」当数学对象、量化系统的证明力量——反而由哥德尔与 Gentzen 亲手扶正,成为今天的证明论。
若只记一句话,记这句:哥德尔没有杀死希尔伯特纲领,他给它换了一个更诚实的目标——不再追求「绝对的自证」,而是精确地测量「一个系统到底能证到哪」。这门测量术,就是下一节起要展开的「边界与独立」。
★★★ 两条定理说得斩钉截铁:足够强的系统必不完备、不能自证一致。自然的追问随之而来——「足够强」究竟要强到什么程度?把强度降下来,不完备性会不会消失?本节的回答是:会,而且这类理论并不稀奇。
先拆开两个极易混淆的名词。哥德尔完备性定理(第二章)说的是「语义蕴含 ⟺ 语法可证」,是关于推理规则的定理;完备理论说的是「对每个句子 φ,T ⊢ φ 或 T ⊢ ¬φ」,是关于理论的性质。前者对一阶逻辑普遍成立,后者只对少数理论成立。第一定理里的「不完备」,指的正是后者。
若 T 完备、一致且可递归公理化,则 T 可判定:同步枚举 T 的一切证明,完备性保证 φ 与其否定必有一个先出现,先出现者即给出判定。
于是问题收窄为:哪些理论完备?关键不在「强」,而在「不能表示足够多的可计算函数」。哥德尔论证的发动机是原始递归函数(§5.2),而它需要乘法;一旦语言只剩加法,或换成实数域上的运算,那台发动机就点不着火。
① DLO:稠密线性序 (ℚ, <) 的一阶理论——完备且可判定(康托尔 1895 的序型论证是雏形)。② Presburger 算术:(ℕ, 0, S, +) 的一阶理论——完备且可判定(Presburger 1929),但没有乘法。③ 实闭域 RCF:(ℝ, +, ·, <, 0, 1) 的一阶理论——完备且可判定(Tarski 1948),初等欧氏几何正落在其中。
「乘法」是引爆点。比较三个结构:(ℕ, +) 可判定(Presburger);(ℝ, +, ·, <) 可判定(Tarski);而 (ℕ, +, ·)——只多了一个乘法——立刻不可判定、不完备(哥德尔)。乘法之所以致命,是因为有了它,才能用哥德尔编码把「公式」「证明」这类语法对象表达成数,让算术谈论自己。加法从不自指,乘法才会。
再补一条「完备但不一定可判定的」常识:完备理论的存在性并不依赖可判定性。若 T 完备但不可递归公理化(例如把 Th(ℕ) 整个当真公理集),它照样完备,只是没人能写出算法逐条枚举它。「可递归公理化」才是把哥德尔定理与判定问题连起来的桥。
本节的一句话:不完备性不是「系统太强」的副作用,而是「系统强到能自指」的必然结果。看清这条边界,才能在 §5.14 具体拆解那些「恰好停在界线内侧」的理论。
★★★★ 第一定理留下一个刺眼的事实:存在真的、却不可证的算术句子 G。这句话预设了「真」这个概念——那么,能不能把「真」也写成公式,搬进算术内部?Tarski 1933(英文版 1956)的回答是:不能,而且不能的理由与哥德尔的完全同源。
PA ⊢ Tr(⌜φ⌝) ↔ φ.
换句话说,Tr 要能「忠实翻译」:系统内断言「编号 ⌜φ⌝ 是真的」与句子 φ 本身可证地等值。这是对「真」最自然的形式要求——正是它把自己钉死。
算术真谓词 Tr 在算术语言内不可定义。更一般地,任何一致且能表示算术的理论都无法定义自身的真谓词。
证明。只用到对角线引理(§5.5)——与哥德尔句的构造一模一样。
与哥德尔的对照。两处构造逐字平行,只换了一个公式:哥德尔取 φ(x) :≡ ¬Prov(x),得到「本句不可证」;Tarski 取 φ(x) :≡ ¬Tr(x),得到「本句不真」。差别在于收场:哥德尔句存在且真的,它只让 PA 露出手脚(不完备);说谎者句则无法存在,因为它的存在会使 PA 直接崩掉。于是真谓词被判出局。同一台对角线机器,一个产出定理,一个产出不可能性。
两条包含关系。把「可证句的集合」Prov 与「真句的集合」Tr 当作两个自然数集合比较。可靠性与完备性给出 Prov ⊆ Tr(可证必真,D1 与可靠性);第一定理给出 Tr ⊄ Prov(G 真而不可证)。合起来是本章反复出现的那条不等式:
Prov(PA) ⊊ Tr(ℕ).
「可证」是系统内部的视角,只认公理与推演;「真」是系统外部的视角,站在标准模型 ℕ 上说话。Tarski 的贡献,是证明这两者之间的落差无法被系统自己跨越——真谓词进不了算术的门。若把语言升到二阶算术或集合论,一阶算术的真谓词便可定义了,代价是换了一个更强的、而且同样无法自证的真谓词。层次每升一级,「真」就后退一步,永不被追平。
Tarski 定理当作第一定理的语义版:哥德尔说「可证推不出全部真」,Tarski 说「真写不进系统」。两句话合起来,正好解释了为什么「数学的真理」永远比「某个系统的定理」更宽——这不是坏消息,而是数学不会终结的凭证。
★★★ 「不完备」是站在系统外面说的:系统证不出某句,也证不出它的否定。站在句子这侧看,同样的事有一个更响亮的称呼——独立。本节先把独立性定义清楚,再展示它五花八门的面孔;下一节专门处理其中最著名的一张:连续统假设。
独立性与不完备是一对同义词:一个理论不完备,当且仅当存在独立于它的句子。所以第一定理也可改述为「PA 有独立句」。但独立性并非铁板一块,它按「用多强的假设、动多重的工具」分成好几个物种。
① 算术独立句:哥德尔句 G、罗塞尔句 R,以及 Con(PA)——都独立于 PA。② 集合论独立句:连续统假设 CH、选择公理 AC、以及更强的组合命题——独立于 ZF/ZFC。③ 强度阶梯:同一句子在不同理论里命运不同,Con(PA) 独立于 PA,却在 ZFC 里可证。
① 内模型法:在一个 ZF 模型内部切出一个子结构,使新公理在其中成立——哥德尔 1938/1940 用可构造宇宙 L 证 Con(ZF) → Con(ZF + AC) 与 Con(ZFC + CH),用的就是这个办法。② 外模型法(力迫):把原模型扩大,加入新对象使新公理在其中成立——科恩 1963 用力迫法证 Con(ZFC) → Con(ZFC + ¬AC) 与 Con(ZFC + ¬CH)。③ 组合与算术方法:不用模型而直接与「良序」「增长速度」谈判,如 Paris–Harrington(1977)与 Goodstein 定理(Kirby–Paris 1982),它们独立于 PA,却在 ZFC 中可证。
两朵高峰。选择公理 AC 的独立性史几乎铺满了整个二十世纪:哥德尔 1938 在 L 中证出 AC 成立(故 AC 不能被 ZF 否证),科恩 1963 造出 ¬AC 的模型(故 AC 也不能被 ZF 证出),合璧得 AC 独立于 ZF。连续统假设 CH 走的是同一条路,但因为它是希尔伯特 1900 年的第一问题,二十余年的悬置使它成为数学史上最著名的一张「独立」标签(§5.13)。
独立性不等于「无意义」。这是最需要纠正的误读(§5.15 将展开)。CH 独立于 ZFC,意味着 ZFC 这条公理线同时容纳「CH 真」与「CH 假」两种宇宙;它并不意味 CH 是虚构的,也不意味无所谓。独立把「真值」问题转交给「选择哪套公理」的问题——这恰是大基数、Martin 极大公理与 Ultimate L 这些新公理登场的舞台。
★★★★★ 这是本章、也可能是全书分量最重的一页。希尔伯特 1900 年在巴黎提出的第一问题,问的正是连续统假设——实数集的基数是否为最小的不可数基数:
CH: 2ℵ0 = ℵ1.
它悬置了六十余年,最终的判决不是「真」也不是「假」,而是独立。这个判决由两根支柱抬起来:哥德尔的内模型与科恩的力迫。
定义可构造宇宙 L 的层谱:L0 = ∅,Lα+1 = Def(Lα)(Lα 中一阶可定义子集的全体),Lλ = ⋃α<λ Lα(λ 为极限序数),L = ⋃α∈Ord Lα。则 L ⊨ ZFC,且 L ⊨ GCH,特别地 L ⊨ CH。于是 Con(ZF) → Con(ZFC + CH)。
证明思路。① L 满足 ZF 的全部公理(包括 AC:用 L 中的良序可造出选择函数)。② 可构造性的绝对性:L 是每个 ZF 模型的「最小」内模型——任何 ZF 模型都含有一个与 L 同构的层谱,故「x 可构造」在 L 内部与外部判断一致。③ Condensation(凝聚)引理:若 M ≺ Lα 是初等子结构,则 M ≅ Lβ 对某序数 β 成立——它把任意「看起来像 Lα 的初等子结构」压回层谱,从而精确控制 L 中基数与幂集的规模。④ 用 ③ 逐层数出「L 中只有 ℵ1 个实数」,得 L ⊨ 2ℵ0 = ℵ1,并由同样的计数推广到所有基数得 GCH。∎
存在力迫扩张 V[G] 使 V[G] ⊨ ZFC + ¬CH。于是 Con(ZFC) → Con(ZFC + ¬CH)。
证明思路(力迫直觉)。① 取一个偏序 (ℙ, ≤) 作为「条件集」,每个条件是一段有限的、相容的信息。② 泛型滤子 G ⊆ ℙ:它在该偏序中足够「一般」,避开一切可定义的「陷阱」。③ 通过 G 把 ℙ 上的名字 τ「解释」为集合,得到扩张模型 V[G]。④ 真值引理:关系「p ⊩ σ」(条件 p 力迫 σ)在 V 内可定义,且 V[G] ⊨ σ 当且仅当存在 p ∈ G 力迫 σ——这把「新模型中为真」化归为「旧模型中关于条件的判断」,使整个论证可在 V 内进行。⑤ 取 ℙ 为「加入 ℵ2 个新实数」的条件集,则 V[G] 中实数有 ℵ2 个,而 ℵ1 未被抬高,故 V[G] ⊨ 2ℵ0 = ℵ2 > ℵ1。∎
合璧。定理 5.29 说 ZFC 证不出 ¬CH(否则 L 里 CH 成立会与 ZFC 相容性冲突),定理 5.30 说 ZFC 证不出 CH。两柱合起:CH 独立于 ZFC。希尔伯特第一问题因此得到一个「不是答案的答案」:在 ZFC 的公理线内,CH 两向皆可行。
判决之后。独立性不是终点,而是新问题的入口。① 推广:同样的技术给出 GCH 的独立性与 Easton 定理(幂集函数在正则基数上的取值几乎任意)。② 大基数:若存在实值可测基数(一种极强的大基数),则 2ℵ0 > ℵ1——大基数能替 CH 定音。③ 新公理:Martin 极大公理 MM 与其保稳版 PFA 蕴含 2ℵ0 = ℵ2,改写了「实数有多少」。④ Woodin 方向:Ω-猜想与 Ultimate L 若成立,则 CH 为真;这条路线试图把「哪套公理对」的问题,转成「哪套公理更完备、更可解」的判据。CH 的最终归属,如今是一场关于「数学该往哪走」的投票。
把这一页与 §5.6 对照着读:第一不完备定理说 PA 有一句 G 既不可证也不可否证,希尔伯特第一问题说 ZFC 有一句 CH 既不可证也不可否证。两件相隔三十年、分属算术与集合论的巨案,用的是同一套语法:先造一个模型让命题成立,再造一个模型让它失败。
★★★★ §5.10 说边界之内有一批完备又驯服的理论。本节走进其中两个家庭,看清「驯服」是怎么做到的:它们的判定程序都靠同一种手术——量词消去。
① 实闭域 RCF:(ℝ, +, ·, <, 0, 1) 具有 QE(Tarski–Seidenberg 1951),故其理论完备且可判定;初等欧氏几何经由坐标化为 RCF,因而可判定。② Presburger 算术:(ℕ, 0, S, +, <) 具有 QE(Presburger 1929;现代算法见 Cooper 1972),故完备可判定。③ 代数闭域 ACF:固定特征 p 的代数闭域理论具有 QE(Tarski 1948),故完备可判定。
为什么「有乘法」不再是罪名?RCF 明明含乘法,为何不像 PA 那样崩掉?差别全在归纳模式。RCF 的公理是域公理加序公理(如「每个奇次多项式有根」),不含针对自然数的归纳模式;它的语义是实数域,而实数上的「最小归纳集」无法被一阶语言捕获——ℕ 不是 RCF 语言里可定义的集合。没有归纳,就没有哥德尔编码赖以运行的那台发动机;没有编码,就无法自指。「离散的、可递归枚举、可归纳」才是致命的组合。
反过来看 Presburger 的脆弱。Presburger 算术只有加法,判定程序存在,但它的判定代价极高(复杂度至少双重指数)。而一旦把乘法放进去,乘法又能借助加法与量词把「整除」「素数」「编码」写出来,Presburger 的温顺立刻消失——这正是 PA 与它的分野。分界点极其精确:加法的世界可判定,加法的世界一旦长出乘法就不可判定。
对工程的意义。这些「例外」不是学术珍玩。今天的 SMT 求解器里,线性整数算术(Presburger 的可判定片段)与实闭域(非线性实数约束的决策过程)是两大支柱;数据库与程序的「约束求解」「模型检测」,靠的正是 RCF 的量词消去与其高效后代(柱形代数分解 CAD)。哥德尔的墙把「全自动证明」挡在门外,但这些可判定片段,是墙上开出的、足够养活一整门工程技术的窗。
读到这里,本章的「边界」理论已经完整:不完备与不可判定不是数学的普遍命运,而是特定强度的代价。下一节起清点误用、转向 Chaitin 的随机性,再把独立性证明的技术谱收成一页。
★★ 哥德尔定理大概是被引用得最多、被读错得也最多的数学定理。它常被拿去支撑一堆与它无关的结论——「数学不可靠」「理性有极限」「机器不如人脑」「意识无法算法化」。本节做一件清扫工作:列出最常见的误用,再配一把「三问」的尺子,供遇到任何「哥德尔式论证」时当场检验。
误用一:把「不完备」读成「数学不可靠」。不完备不等于不一致,也不等于「什么都证不出来」。恰恰相反,系统强到能表示算术,才有这门烦恼——弱小的理论(§5.10 的 DLO、Presburger、实闭域)既完备又可判定。不完备是「强到能自指」的代价,不是数学地基松动。
误用二:把「不可证」读成「不可知、无意义」。哥德尔句 G 在标准模型 ℕ 中为真,而且我们可以(在元理论里)知道它为真——推理只用了一致性与可靠性。它只是 PA 证不出,并非无人能知,更不是无意义的符号串。「系统内不可证」与「我们不知道」是两件事。
误用三:把它当成「人脑强于机器」的论据。这是最有名的一次越界(Lucas 1961、Penrose 1989)。论证大致是:机器等价于某形式系统,它有不可证的 G;而我们能看出 G 为真,故人脑超越任何机器。漏洞在于:我们「看出 G 为真」依赖「该机器(系统)是一致的」这一前提,而这个前提我们同样无法在系统内自证;一旦要把它当定理用,就得站在一个更强的系统里,而那个更强的系统又有它自己的 G。人脑并不同时拿到「可靠」与「自证可靠」这两件东西——论证在这里断链(Feferman 的批评最完整)。
误用四:把不完备性套到不相干的理论上。「这个定理独立于 ZFC」不能被随意改写为「这个定理永远证不出」。独立性是相对某个公理系统说的;换一套更强的公理(大基数、新公理),同一个句子可能立刻可证或被否证。Con(PA) 独立于 PA,却能被 ZFC 证出,就是最直白的例子。
误用五:把「不可判定」与「不可计算」「NP 完全」混为一谈。三者的量级完全不同:不可判定是「没有算法」(§4.6 的停机问题);NP 完全是「算法也许有,只是不知道快不快」(§4.12);不可计算是「不存在机器能算出这个函数」。把它们互串,是初学逻辑最常见的失分点。
误用六:把第二定理读成「PA 可能不一致」。第二定理说的是「PA 证不出 Con(PA)」,不是「PA 不一致」。一致性是一个元语言事实,我们基于对 ℕ 的信赖相信它极高概率成立;不可证只是说,这份信赖无法被装在系统内部当成定理。「无法自证」与「其实是假」之间隔着一整个宇宙。
① 对象问:所说的系统是否一致、可递归公理化、且足以表示算术?三者缺一,定理即不适用。② 层面问:结论讲的是「系统内可证」还是「客观为真」?两者被偷换,论证立刻失效。③ 归属问:是否把一句元语言的断言(如「我们知道它为真」)伪装成系统内部的定理?若是,则犯了「越界内化」的错。
★★★★ 哥德尔用「自指」证明不可证;四十年后,Chaitin 用「随机」证明同一件事。本节引入算法信息论,看看「不可压缩」怎样成为另一种形式的不可证。
由计数即可看出:长度为 n 的串有 2n 个,而长度小于 n 的程序不足 2n 个,故必有大量串满足 K(x) ≥ n——它们无法被比自身更短的程序描述。这类串就是「随机」的:不可压缩,没有任何规律可循。
Ω = Σp 停机 2−|p|,
即「随机生成一个二进制串,它恰好是一段可停机程序」的概率。这个和收敛(前缀无关性保证 Ω ≤ 1),故 Ω 是一个具体的实数。Chaitin 常数 Ω 因所固定的机器不同而不同,但任一 Ω 都具有下列性质。
① 随机:存在常数 c,使 K(Ω 的前 n 位) ≥ n − c——Ω 的每一位都是新鲜信息,不可压缩。② 前 n 位即停机判据:知道 Ω 的前 n 位,就能判定所有长度不超过 n 的程序是否停机。③ 不可计算:由 ② 与停机问题不可判定(§4.6),Ω 不可计算。
对任何一致且可递归公理化的形式系统 T,存在常数 cT,使 T 只能证明有限多个「K(x) > cT」形式的断言。换句话说:系统能验证的「随机性」有上限;超过某个长度,它连「这个串是随机的」都证不出来。
证明思路。若 T 能对任意大的 c 都证出某个 x 的 K(x) > c,则可写一个程序「枚举 T 的定理,找出第一个被证 K(x) > c 的 x 并输出它」。这个程序输出 x,其长度只比 log c 略多,于是 K(x) ≤ log c + O(1) < c(c 足够大时),与「K(x) > c」矛盾。故 c 有上限。∎
与哥德尔的对照。哥德尔句说「本句不可证」,是逻辑形式;Chaitin 句说「本串不可压缩」,是信息形式。两者都靠自指(Chaitin 的证明里,那段「枚举定理」的程序正是自指装置),都指向同一条边界。区别在于视角:哥德尔看「可证性」,Chaitin 看「随机性」——同一个洞的两侧。
不存在算法判定任意 Diophantus 方程是否有整数解(Davis–Putnam–Robinson 1961 归约 + Matiyasevich 补上最后一步)。更强地:存在一个具体的 Diophantus 方程,它「有解」当且仅当 ZFC 不一致——于是这个方程是否有解,独立于 ZFC。
把三条线拧成一股。停机问题(§4.6)、Hilbert 第十问题、哥德尔句、Chaitin 的 Ω——它们不是四件孤立的事,而是同一条「不可判定—不可证—不可压缩」河流的四个观景台。哥德尔给出了逻辑的坐标,图灵给出了计算的坐标,Chaitin 给出了信息的坐标;三条坐标轴指向同一个原点。
★★★★ 哥德尔 1931 年给出的不只是两个定理,更是一整套「证明某句独立」的作坊。本节把这座作坊的工具摆成一排,看看九十年里它怎样从一间小屋长成一片工业区。
先说「证明独立」的两条铁律。要证 φ 独立于 T,必须做满两步:① 造一个 T + φ 的模型(证 T ⊬ ¬φ);② 造一个 T + ¬φ 的模型(证 T ⊬ φ)。两向缺一,独立性就不成立——这是本节所有技术共有的骨架。
一页对表。把三种技术与它们的代表成果列在一起,可以看出「独立」这张地图并不神秘——它只是模型与证明两条线的交会处。
| 技术 | 做法 | 代表作 / 代表成果 | 局限 |
|---|---|---|---|
| 内模型法 | 切出子结构,使新公理成立 | 哥德尔 L 证 Con(ZF) → Con(ZFC + CH) | 只能造「里」,难以造「¬CH」 |
| 力迫法 | 扩张模型,翻转命题真值 | 科恩 1963 Con(ZFC) → Con(ZFC + ¬CH) | 需精细控制基数,技术门槛高 |
| 迭代力迫 | 可数无限次叠加力迫步 | PFA / MM ⟹ 2ℵ0 = ℵ2 | 公理本身独立于 ZFC |
| 组合 / 序数 | 用增长速度与良序谈判 | Goodstein、Paris–Harrington 独立于 PA | 多为 PA 层级,少见于集合论 |
| 算术自指 | 对角化 + 编码 | 哥德尔句、Rosser 句、Con(PA) | 只证「存在」,不辨具体句子 |
逆数学:把技术谱翻过来读。既然公理有强有弱,那就反过来问:一条经典定理到底用了哪条公理?这就是 Friedman 与 Simpson 开创的逆数学(见第六章):把分析学的定理放进五大子系统 RCA0 ⊂ WKL0 ⊂ ACA0 ⊂ ATR0 ⊂ Π11-CA0 里精确标定,看某条定理恰好等价于哪一层。独立性与逆数学,是同一枚硬币的「分」与「合」两面。
当代前沿。独立性的故事没有结束。① 大基数:从不可达基数到 Woodin 基数,形成一条线性有序的强度阶梯;「可测基数蕴含 V ≠ L」是它对内模型纲领的判决。② Ω-逻辑与 Ultimate L:Woodin 试图给「正确的新公理」一个判据,Ultimate L 若成立将定 CH 为真。③ 多宇宙观:Hamkins 主张集合论宇宙本就有许多个,独立性是常态而非缺陷。三派之争,正是希尔伯特第一问题留给二十一世纪的余响。
例 5-1(在标准模型里判真)。在 ℕ = (ℕ, 0, S, +, ·) 中判定下列句子的真假:① ∀x (x + 0 = x);② ∀x∃y (y = Sx);③ ∀x∃y (x = y + y ∨ x = S(y + y))。
解。① 真:任何自然数加 0 等于自身。② 真:取 y 为 x 的后继即可。③ 真:每个自然数要么是偶数(x = y + y)要么是奇数(x = y + y + 1),把「加一」写作 S(y + y) 即得。要点:「在 ℕ 中为真」是语义判断,与「PA 能否证出」是两回事——③ 可证,而 §5.6 的 G 同样在 ℕ 中为真却不可证。
例 5-2(把句子分级)。判断下列公式属于 Δ0、Σ1 还是 Π1:① ∀x ≤ t ∃y ≤ t (x + y = t);② ∃p Proof(p, x);③ ∀p ¬Proof(p, ⌜0 = 1⌝)。
解。① Δ0:两个量词都有界,是有限核验。② Σ1:一个无界存在量词套在有界核验上——这正是 Prov(x) 的形状(§5.4)。③ Π1:一个无界全称量词套在 Δ0 上,正是 Con(PA) 的形状。规律:量词从内到外的「无界」层数决定级别;Σ1 真则必可证(Σ1-完全性),Π1 真未必可证——哥德尔句就住在 Π1 层。
例 5-3(真值表判重言)。用真值表判定 (p → q) ∨ (q → p) 是否为重言式,并说明这件事与命题逻辑可判定的关系。
解。列四行赋值:(p, q) 取 (T,T),(T,F),(F,T),(F,F)。第一行两析取项均真;第二行 q → p 真;第三行 p → q 真;第四行两者皆真(前件假)。四行全真,故是重言式。关系:命题逻辑只有有限多个变元,模型空间有限,2n 行穷举即为判定——这正是 §5.10 所说「有限模型空间带来可判定」的最朴素样本;升到一阶逻辑,模型空间无穷,判定性即失守。
例 5-4(有限结构与无穷结构的对照)。句子 φ :≡ ∀x∃y (x + y = 0)(读作「每个元都有一个加法逆元」)在结构 (ℤ, +, 0) 中真吗?在 (ℕ, +, 0) 中呢?
解。在 (ℤ, +, 0) 中真:任取整数 x,取 y = −x 即有 x + y = 0(整数对加法封闭,负元就在域内)。在 (ℕ, +, 0) 中假:取 x = 1,则任何自然数 y 都使 1 + y ≥ 1 > 0,不存在逆元。两结构共享同一个语言 {+, 0},却在同一句子上分道扬镳。要点:同一个句子可在不同结构里取不同真值——「语义」永远相对某个结构而言;这也正是判定一阶有效性如此之难的原因:要遍历无穷多个结构。
本页四题共同的收获:先把「真」钉在一个具体的结构或赋值上,再谈可证。例 5-1、5-4 练的是「给定结构判真值」,例 5-2 练的是「看公式的量词形状定级别」,例 5-3 把「有限模型空间」的可判定直觉钉死。三者合起来,正是理解哥德尔句「真而不可证」的前置功——先在语义上把真假说清楚,才不至于把语义与语法混为一谈。
例 5-5(手算一次对角化)。在一个玩具编码里,把「编号为 n 的公式」的变元替换为 n̄。设有两公式 ψ1(v) :≡ v = v(编号 1)、ψ2(v) :≡ v = 0(编号 2)。求 d(1) 与 d(2),并说明哪一个是「自指句」。
解。d(1):把 ψ1 里的 v 换成常数 1̄,得 1̄ = 1̄(真)。d(2):把 ψ2 的 v 换成 2̄,得 2̄ = 0(假)。自指的发生处不是 d 本身,而是「让某个公式的编号恰等于它被代入的那个数」:在 §5.5 的构造里,取 δ(v) :≡ ∃y(D(v, y) ∧ φ(y)) 并令 m = ⌜δ⌝,此时 d(m) = ⌜δ(m̄)⌝,代入的数与被代入的公式编号重合,自指才成立。
例 5-6(写出哥德尔句的存在性四步)。不重述全部细节,只按 §5.6 的路线,列出从对角线引理到「PA ⊢ G ↔ ¬Prov(⌜G⌝)」的四个关键步骤。
解。① 表示对角化:由可表示性(定理 5.6)取 Σ1 公式 D(x, y) 表示 d。② 定义 δ:δ(v) :≡ ∃y(D(v, y) ∧ ¬Prov(y))——即把 φ 取为 ¬Prov 的对角化公式。③ 回投取不动点:令 m = ⌜δ⌝、G :≡ δ(m̄),则 d(m) = ⌜G⌝。④ 代入表示式:PA ⊢ ∀y(D(m̄, y) ↔ y = ⌜G⌝),代入 δ 得 PA ⊢ G ↔ ¬Prov(⌜G⌝)。四步与定理 5.13 的证明同构,只是把 φ 具体化成 ¬Prov。
例 5-7(用 Löb 定理做一步推理)。已知 Löb 定理:若 PA ⊢ Prov(⌜ψ⌝) → ψ,则 PA ⊢ ψ。用它证明:PA ⊬ Prov(⌜0 = 1⌝) → 0 = 1。
解。反设 PA ⊢ Prov(⌜0 = 1⌝) → 0 = 1。取 ψ = (0 = 1),由 Löb 定理得 PA ⊢ 0 = 1,即 PA 证出矛盾,与一致性(假设)冲突。故 PA ⊬ Prov(⌜0 = 1⌝) → 0 = 1。解读:系统不能把「只要矛盾可证,矛盾就成立」当成自己的定理——否则它会顺着这条链条自证矛盾。这正是第二定理的「反面教材」(§5.8)。
例 5-8(为什么第二定理离不开 D2)。可证性三律中 D2 是「传递律」PA ⊢ Prov(⌜φ⌝) → Prov(⌜Prov(⌜φ⌝)⌝)。试说明:若缺少 D2,第二定理的证明会在哪一步卡住。
解。回顾 §5.8 的证明:要把 Prov(⌜G⌝) 逐步推成 Prov(⌜¬G⌝),中间必须把「G 可证」这件事再内化一层:从 Prov(⌜G⌝) 走到 Prov(⌜Prov(⌜G⌝)⌝),再借 Prov(⌜G⌝) ↔ ¬G 的编码把外层换成 Prov(⌜¬G⌝)。D2 正是完成「再内化一层」的那条桥;缺了它,Prov(⌜G⌝) 无论怎么拼接都换不成 Prov(⌜¬G⌝),整个链在 ② 处断裂。这也解释了为什么满足 D1–D3 是第二定理的必要条件——「可证性的可证性」不是可选的装饰,而是自证一致的唯一通道。
本页四题串起一条从「手艺」到「原理」的线:例 5-5 把对角化摊开成可手算的替换,例 5-6 把哥德尔句的构造压成四步,例 5-7 用 Löb 定理反向验证第二定理,例 5-8 则把三律中的 D2 单拎出来说明它为何不可省。证明的实操,练的是「每一步都点名出处」的习惯:D1 用在何处、D2 用来跨哪一层、对角线回投发生在哪一步——把出处点清,繁琐的形式推演就变成可复查的工序。
习题 5-1(在给定结构中判真假)。分别判定下列句子在 (ℕ, 0, S, +, ·) 与 (ℤ, 0, S, +, ·) 中是否为真:① ∀x∃y (x + y = 0);② ∀x (x · 0 = 0);③ ∃x∀y (x · y = y)。
提示。① 在 ℤ 真(取 y = −x)、在 ℕ 假(x = 1 即反例);② 两处皆真;③ 两处皆真(取 x = 1)。要点:句子的真假永远相对结构;判真要从「结构里有没有那个见证元」入手,而不是凭「语言看起来像什么」。
习题 5-2(给公式分级)。把下列公式按 Δ0、Σ1、Π1 或更高分级:① ∀x ≤ t (x + 0 = x);② ∃p Proof(p, x);③ ∀p ¬Proof(p, ⌜0 = 1⌝);④(Euclid)∀x∃y (y > x ∧ Prime(y))。
提示。① Δ0(量词有界,有限核验);② Σ1(无界存在套有界核验,即 Prov 的形状);③ Π1(无界全称套 Δ0,即 Con(PA) 的形状);④ Π2(一个无界全称套一个无界存在)。口诀:分级只看外层无界量词的「类型串」,不问内容;Σ1 真则必可证,Π1 真未必可证。
习题 5-3(用 Los–Vaught 判完备)。用「来回」法(back-and-forth)证明:任意两个可数、无端点、稠密的线性序同构;由此说明稠密线性序理论 DLO 完备。
提示。来回法:把两个结构各自枚举为 a0, a1, … 与 b0, b1, …,交替地「回去」与「过来」地把新元插进已建好的有限同构,稠密无端点保证总能插得进去,极限即得同构。完备性的落点:DLO 是 ℵ0-范畴的(可数模型唯一到同构)且无有限模型,由 Los–Vaught 判据即完备。注意这条判据只保证完备,可判定性需另配量词消去(§5.14)。
习题 5-4(可判定与不可判定的分界)。说明为何 (ℕ, +) 的理论可判定,而 (ℕ, +, ·) 的理论不可判定,并指出关键差别。
提示。前者是 Presburger 算术,靠量词消去(Cooper 算法)可判定(§5.14);后者是 PA 的真理论,因乘法足以编码句法与证明,哥德尔论证得以运行,故不完备且不可判定(§5.6)。关键差别只有一个:乘法。加法不能自指,乘法能——这一点是本章「边界」全部结论的浓缩。
习题 5-5(初等等价与同构)。判断 (ℚ, <) 与 (ℝ, <) 是否初等等价(同真值),并说明理由。
提示。是,初等等价。两者都是无端点稠密线性序,都满足 DLO 的全部公理;DLO 完备(习题 5-3),故任一 DLO 句子在两者中取相同真值。但二者不同构(基数 ℵ0 ≠ 2ℵ0)。教训:初等等价远弱于同构——一阶语言「看不见」基数的差别,这正是 Löwenheim–Skolem 现象的语义面。
习题 5-6(Henkin 句)。用对角线引理取句子 σ 使 PA ⊢ σ ↔ Prov(⌜σ⌝)(读作「本句可证」)。证明 PA ⊢ σ,并说明这与哥德尔句有何不同。
提示。由 σ ↔ Prov(⌜σ⌝) 得 PA ⊢ Prov(⌜σ⌝) → σ;这正是 Löb 定理(定理 5.21)的前件,故 PA ⊢ σ。再由 D1 得 PA ⊢ Prov(⌜σ⌝),与 σ 一致(无矛盾)。对比:哥德尔句说「本句不可证」,结果不可证;Henkin 句说「本句可证」,结果可证。同一台对角线机器,投进 ¬Prov 与投进 Prov,产出命运相反的两个句子。
习题 5-7(罗塞尔句的形状)。说明哥德尔句 G 与罗塞尔句 R 都是 Π1 句,但后者只需一致性即可完成论证(§5.7)。
提示。形状上:G :≡ ¬Prov(⌜G⌝) :≡ ∀p ¬Proof(p, ⌜G⌝);R :≡ ∀p(Proof(p, ⌜R⌝) → ∃q < p Proof(q, ⌜¬R⌝)),内层量词有界,故亦 Π1。为何只需一致性:罗塞尔论证的每一步都在比较「证明的编号谁更小」,而比大小是 Δ0 的有限判定,不需要「兑现存在句的标准见证」这一步——后者正是 ω-一致性的用武之地。
习题 5-8(G 与 Con(PA) 的等值)。证明 PA ⊢ G ↔ Con(PA)(方向一用 §5.8 的链;方向二用「从矛盾可推出一切」加 D1、D3)。
提示。方向一(Con → G):即 §5.8 的结论。方向二(G → Con):PA 内可证 0 = 1 → G(矛盾蕴含一切);编码后由 D1、D3 得 Prov(⌜0 = 1⌝) → Prov(⌜G⌝),取逆否即 ¬Prov(⌜G⌝) → ¬Prov(⌜0 = 1⌝),而 ¬Prov(⌜G⌝) ↔ G、¬Prov(⌜0 = 1⌝) :≡ Con(PA),故 PA ⊢ G → Con(PA)。两向合起即等值。推论:「PA 一致」与「哥德尔句为真」在 PA 内是同一句话的两种写法;既然 PA ⊬ G,也就 PA ⊬ Con(PA)。
习题 5-9(从模型判独立)。已知 ZFC + φ 与 ZFC + ¬φ 各有一模型。证明 φ 独立于 ZFC(设 ZFC 一致)。
提示。反设 ZFC ⊢ φ。由可靠性,φ 在 ZFC 的一切模型中真,故 ZFC + ¬φ 无模型,与已知冲突。反设 ZFC ⊢ ¬φ,同理 ZFC + φ 无模型,亦冲突。两向皆不能证,故 φ 独立。要点:「两向造模型」这条铁律(§5.17)就是独立性的充分判据;CH、AC 的独立性证明,走的都是这道程序。
习题 5-10(误用辨析)。用 §5.15 的三问尺子,指出下列说法的错误:(a)「哥德尔证明了数学不可靠」;(b)「CH 不可证,所以 CH 无意义」;(c)「人脑能看出 G 为真,故人脑强于任何机器」。
提示。(a) 悖于「不完备 ≠ 不一致」:不完备只是「有真句证不出」,系统仍可一致;弱系统还常常完备。(b) 悖于「独立 ≠ 无意义」:CH 独立只是说 ZFC 线内两向皆可,新公理(大基数、MM、Ultimate L)能为之定音。(c) 悖于「归属问」:人脑看出 G 真,依赖「系统一致」这一元语言前提,而这个前提同样无法在系统内自证;把「我们的信念」当「系统内定理」,正是越界内化。三题合看:越界引用是哥德尔定理最常见的误用方式。
本章 17 节结成一张网,却有一条清晰的骨架。本页把它画出来:箭头 A → B 表示「B 的定义、证明或结论需要 A」。全章的起点是形式算术,终点是「真实多于可证、独立是常态」。
三条推理主线。① 自指线:PA(§5.1)→ 可表示性(§5.2)→ 编码(§5.3)→ Prov(§5.4)→ 对角线引理(§5.5)→ G(§5.6)→ Con(PA)(§5.8)。这条线只用一把刀:把语法变成算术,再让算术指向自己。② 边界线:完备与可判定(§5.10)→ Tarski 真不可定义(§5.11)→ 完备理论的例外(§5.14)。这条线回答「不完备性躲得过吗」——躲得过,只要弱到不能表达乘法。③ 独立线:独立性的多种面孔(§5.12)→ CH 的判决(§5.13)→ 技术谱(§5.17)。这条线把「独立」从恐慌变成一门有工具、有分类、有前沿的技术。
通向外部的接口。① 第二章:哥德尔完备性定理(语义=语法)与本章的不完备定理,是同一作者最容易混淆的两条结论,务必分清「逻辑的完备」与「理论的完备」。② 第三章:Gentzen 的切割消除是 Con(PA) 相对证明的技术底子(§5.9)。③ 第四章:停机问题的对角化与哥德尔句的自指,是同一种手法在两个战场的应用。④ 第六章:形式化与证明助手把「可机械检查的证明」变成工程;逆向数学反过来用独立性给经典定理定价。⑤ 集合论:L 与力迫(§5.13)是集合论方法论的本体,也是与相邻方法论对照的接口。
一句话复盘。先把算术写死成符号,再把符号编成数,最后让数谈论自己——三步走完,「可证」就再也追不上「真」。本章的技术内核,就是这三步。
读图指南:三处最容易卡住的接缝。① 编码与可证性的接缝(§5.3 → §5.4):容易误以为「编码就是翻译逻辑」,实则是「给逻辑对象编号,使逻辑操作变成算术操作」——编号任意,固定即可。② 可证性与对角线的接缝(§5.4 → §5.5):容易误以为自指是「句子包含自己」,实则是「句子的编号作为一项进入句子」,一步合法的代入而已。③ 两定理与独立的接缝(§5.6 → §5.13):容易误以为「不可证」是孤立的奇观,实则是「两向造模型」这一统一工序的产物。三处接缝打通,全章就成了一条直线。
本页任务。把本章「关于真、结构与可判定」的一面收成随身卡片;语法与自指的一面在下一页。
| 理论 | 语言 / 结构 | 完备? | 可判定? | 关键判据 |
|---|---|---|---|---|
| DLO | (ℚ, <) | 是 | 是 | ℵ0-范畴 + 量词消去 |
| Presburger | (ℕ, 0, S, +, <) | 是 | 是 | Cooper 量词消去 |
| 实闭域 RCF | (ℝ, +, ·, <, 0, 1) | 是 | 是 | Tarski–Seidenberg |
| 代数闭域 ACF | (𝔽, +, ·, 0, 1) | 是 | 是 | 量词消去(固定特征) |
| 皮亚诺算术 PA | (ℕ, 0, S, +, ·) | 否 | 否 | 哥德尔 / 罗塞尔 |
| ZFC 集合论 | ∈-结构 | 否 | 否 | 哥德尔 / 科恩(CH、AC) |
最易混淆的三对。① 「逻辑完备」vs「理论完备」:前者(哥德尔完备性定理)说语义蕴含等于可证,普遍成立;后者说每个句子或否定可证,只对少数理论成立。两者同名不同义,混用必错。② 「不可证」vs「不为真」:哥德尔句不可证却在 ℕ 中为真;判「不可证」看系统,判「真」看结构,两个坐标不能互换。③ 「独立」vs「无意义」:独立只是相对某套公理说的,添新公理即可定音;把独立读成「无意义」,是把公理的选择问题误当成了语言的失效。三对理清,语义篇的地基就稳了。
本页任务。把本章「关于形式系统、自指与独立」的技术一面收成卡片,并给出与全书后续章节的接口。
| 手法 | 产出 | 代表 |
|---|---|---|
| 对角化 + 编码 | 自指句、不完备、不可证一致 | 哥德尔 1931 · 罗塞尔 1936 |
| 内模型(切子结构) | 使 AC / CH 成立 | 可构造宇宙 L(1938/1940) |
| 力迫(扩张模型) | 使 ¬AC / ¬CH 成立 | 科恩 1963 · 布尔值模型 |
| 序数 / 组合 | 相对一致性、算术层独立句 | Gentzen 1936 · Kirby–Paris 1982 |
| 算法信息论 | 随机性不可证的上限 | Chaitin · Ω |
与全书的接口。① 第三章的切割消除 → 本章 §5.9 的相对一致性证明;② 第四章的停机问题 → 本章自指手法的孪生兄弟;③ 第六章的证明助手与逆向数学 → 把「可机械检查的证明」做成工程,把独立性倒过来给定理定价;④ 与 L、力迫、大基数直接合流。下一章将看到:哥德尔之后,逻辑没有终结,而是换了一副能在计算机里运行的身体。
本章最深的一课,藏在一个不起眼的动作里:把「如果」当成算子。日常语言里,「如果下雨就带伞」是一种建议、一种因果;而在逻辑里,它被锻造成 →,与「并且」「或者」并列,成为一台有真值表、可机械计算的机器。这枚算子一旦立住,推理就变成了计算——而哥德尔做的事,是把这枚算子用到极致,直到它开始谈论它自己。
本章的技术全在此展开:既然「如果」是算子,那么「某个句子可证」也能被写成公式 Prov(x)——一个关于算子能否推出某物的算子。再用编码与对角线引理,让 Prov 回过头来作用于自己的编号,于是「本句不可证」这样的句子被造了出来。算子化到能自指的那一刻,也是它撞上边界的那一刻:可证算子写得出、算得了,却永远覆盖不了「真」。同一种手法,既造出完备的推理机器(一阶逻辑的完备性),又暴露出任何足够强的系统必有一句真话说不出口。
更值得记取的是这份「代价」的两面性。把「如果」当成算子,换来的是可检查、可执行、可跨主体传递的推理——这正是全书从真值表到证明助手一路铺的路;可它同时意味着,系统只能按被给定的规则说话,无法替自己说出「我相信我不会自相矛盾」这类系统外的真话。第二定理、Tarski 不可定义、CH 独立,都是这条代价的三个面孔。算子让语言变强,也让语言看清了自己够不到的地方。
留下的自问:既然「真」不能被写成一个系统内的算子,那么「理解」「意义」「知道」呢?它们是尚待形式化的算子,还是与「真」一样、注定住在系统之外?——这一问没有标准答案;但每一次追问,都会让人重新掂量形式化的力量与它的边界。
任务。用一阶语言 L = {点, 线, 在…上, ∥}(∥ 表示「平行」)写出一组公理,刻画仿射平面的关联与平行结构;再改造它,得到射影平面;最后追问:这套几何理论完备吗、可判定吗?这是把 §5.10 的「边界」用到几何上的一次动手演练。
第一步:写公理。用 P(x) 表「x 是点」、L(x) 表「x 是线」、I(x, y) 表「x 在 y 上」。仿射平面的经典刻画只需三条:
这三条逐字译成一阶句子(「恰在一条」要写成「存在一条,且若另有则相等」)。注意 A3 是存在句,它排除「只有一条线」「只有两个点」等退化模型。
第二步:找模型。验证坐标平面 ℚ2(点是有理点、线是 ax + by = c 的解集)满足 A1–A3;再验证 ℝ2 与有限域上的平面 AG(2, q) 也满足。仿射平面由此得到一大批互不同构的模型——这个事实,它直接决定第三步的答案。
第三步:改造成射影平面。给每条线补上一个「无穷远点」,并让同一方向的所有线共享同一个无穷远点,再把所有无穷远点连成一条「无穷远线」。新的关联结构就是射影平面:任意两条线恰交于一点(不再有平行)。出对应的公理 P1–P3,并说明为什么射影平面里「平行」这个概念可以被删去。
第四步:追问理论的性质(最关键的一步)。试问:由 A1–A3 生成的几何理论完备吗?不完备。理由与 §5.10 同源——它有无限多个互不同构的模型(ℚ2、ℝ2、AG(2, q) 各不相同),而「仿射平面是有限的」这类句子在一阶语言里既不能保证真、也不能保证假。更尖锐地:任何一阶理论若有任意大的有限模型,则必有无限模型(紧致性,第二章),故「平面有限」无法被一句公理钉死。
第五步:找一个「可判定的几何」。把语言升级:在 ℝ2 上使用 {+, ·, <, 0, 1},则初等欧氏几何恰好落进实闭域 RCF,因而是完备且可判定的(§5.14)。这只差一步:放弃「点、线」这种抽象关联语言,改说坐标与运算。教训:同一门几何,换个语言,「可判定」的结论可以完全翻转。
进阶(选做)。① 用 Beltrami–Klein 模型把双曲平面也写进有序域上的坐标语言,查证「初等双曲几何」同样是可判定的(Schwabhäuser–Szmielew–Tarski 1983)。② 想想为什么「欧氏几何可判定」并不与哥德尔冲突——提示:RCF 的模型是 ℝ,它不像 ℕ 那样「可递归枚举 + 可归纳」,哥德尔的引擎在这里没有燃料。
实验目的。把 §5.3–§5.4 的三件事做成可跑的程序并与理论对拍:① 用素数幂把公式编成唯一的数、再完整解码;② 用 β 函数 + 中国剩余定理把不定长序列压成一对数;③ 枚举「证明序列」,检验 Prov(x) :≡ ∃p Proof(p, x) 的搜索本质。脚本见 qa/exp_c5.py,输出见 qa/exp_c5_out.txt,纯 Python,无第三方库。
实验原理(为什么要「对拍」)。编码与可证性是本章的两块基石,却都是「纸上定理」。本实验把它们各自落实为一段可执行的程序,再让程序的输出与元定理逐条比对:素数幂的编与解必须互为逆运算,β 函数取回的序列必须与原序列逐项相等,证明搜索找到见证时目标必须真的可证。三条比对照过去,理论中「原始递归」「可逆」「存在见证即真」这些抽象表述,就都有了一台可复跑的机器作证。对拍的意义在于:当纸上的证明与运行的程序说法一致时,才算真正握住了这段编码。
核心代码(素数幂编码与解码)。
# 符号表:逻辑/算术符号 → 哥德尔数
SYM = {'0':1,'S':2,'+':3,'*':4,'<':5,'=':6,'(':7,')':8,',':9,
'x1':11,'x2':12,'not':14,'and':15,'or':16,'imp':17,'exists':19}
CODE = {v: k for k, v in SYM.items()}
PRIMES = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
def encode_pow(symbols): # <s1..sk> = 2c1 · 3c2 · 5c3 · …
n = 1
for i, s in enumerate(symbols):
n *= PRIMES[i] ** SYM[s]
return n
def decode_pow(n, length): # 逐素因子取指数,反查编号表
out = []
for i in range(length):
p = PRIMES[i]; e = 0
while n % p == 0:
n //= p; e += 1
out.append(CODE[e])
return out
核心代码(β 函数 + 中国剩余定理;证明搜索)。
def beta(b, c, i):
return b % (1 + (i + 1) * c)
def encode_seq(seq): # 把序列 (a0..ak-1) 压成一对 (b, c)
k = len(seq)
c = factorial(k) * (max(seq) + 1) # c 是 k! 的倍数 ⇒ 各模数两两互素
ds = [1 + (i + 1) * c for i in range(k)]
b, mod = 0, 1
for a, d in zip(seq, ds): # 逐个同余方程做增量 CRT
cand = b
while cand % d != a:
cand += mod
b, mod = cand, mod * d
return b, c
def proof_of(seq, target): # 玩具证明谓词 Proof(p, x)
if not seq:
return False
return all(is_axiom(s) for s in seq) and tuple(seq[-1]) == tuple(target)
对拍结果摘要(qa/exp_c5_out.txt)。实验一:x1 = x1 编成 72900000000000,解码回读一致;更长的公式(含量词、括号)同样往返一致——说明素数幂法的编与解都是可逆的原始递归操作。实验二:序列 [7, 3, 1] 压成 (b, c) = (674541, 48),β 逐项取回无误;这正是 β 引理「不定长序列 ≡ 一对数」的机器验证。实验三:目标 0 = 0 搜到证明序列 (0 = 0),判定为真——可证性就是「找到一个具体见证 p」;而目标 0 = S0 在长度 1–3 内搜不到证明,程序只敢说「未找到」,不敢说「不可证」。
实验报告要求。① 贴出脚本运行的三段输出(编码往返、β 压解、证明搜索);② 自拟两条公式(含至少一条含量词与括号者),重跑并解释编码位数的增长;③ 回答:为什么实验三的「搜不到证明」不能读成「不可证」?结合 §5.6 与 §5.10 说明「不可证」为何必须由元定理而非穷举给出(提示:搜索的失败只是「在有限长度内无见证」,而不可证是「对一切 p 都无见证」的全称事实)。
自指这件事,不止西方想过。哥德尔句的核心是「一句话谈论自己」。回到轴心时代,希腊、中国、印度都不约而同地撞上过这块礁石,只是撞的方式各不相同。古希腊麦加拉学派的欧布利德斯(Eubulides,公元前四世纪)留下「说谎者」:一个人说「我此刻在说谎」——若为真则他在说真话,故为假;若为假则他说的是假话,故为真。亚里士多德在《形而上学》里反复辨析「同一事物不能既是又不是」,正是为这类自指句划界。这是最直接的一次迎头相撞:语言当面拷问自己,撞出悖论的火花。
中国的入口,是「矛盾」的实例而非「悖论」的抽象。《韩非子·难一》记楚人鬻盾与矛:「吾盾之坚,物莫能陷也」;又誉其矛「吾矛之利,于物无不陷也」。旁人问「以子之矛陷子之盾,何如?」——楚人不能应。这则寓言给出的,是两个全称断言互相取消的最干净样本:一个说「没有任何东西能穿破我的盾」,一个说「我的矛能穿破任何东西」,两条一相遇,只需把矛与盾叠在一起,系统立即倾覆。后世成语「自相矛盾」正由此而来。再看《墨子·经下》:「以言为尽悖,悖」——若「一切言论都是错的」这句话本身也是言论,那它自己就错了;墨家由此给「以言非言」的自指反对打了一个漂亮的死结。此外,公孙龙《白马论》「白马非马」精辨名实的外延,庄周「彼亦一是非,此亦一是非」则把是非的立场相对化。中国传统的入口,落在名实之辨与论辩实例上,厚于举证与辨析,未把自指本身抽成形式对象。
印度的入口,是把语言的边界划出来。因明学的发展中,「自语相违」(svavacana-viruddha)被明确列为立论的一种过失——所立之宗与自己先前承许的命题相冲突,立论即失效;陈那(Dignāga,约五至六世纪)改造的三支作法,把「因」的成立条件(因三相)钉得极严,正是为了防止言说在内部自行崩解。更彻底的是龙树《中论》的四句否定(catuṣkoṭi):对同一命题,「有」「无」「亦有亦无」「非有非无」四句——看似矛盾,实则是把语言的四种立场逐一悬置,逼出「言语道断」的结论。这是用自指去瓦解自指的一种极端姿态,与希腊的「撞上悖论」、中国的「举出反例」并列为第三种处理方式。
三条入口的落点。三种传统都触碰了「语言谈论语言」这片地带:希腊用说谎者直撞,中国用矛盾实例揭示,印度用四句把边界划出。差别在于后续走向——只有希腊传统把「推理规则本身」与「语言的形式结构」分离出来并加以公理化,才使自指从「悖论」升格为「定理」:先有弗雷格把语言形式化,再有哥德尔用编码把自指写成算术句,悖论于是被驯服为一条可证明的元定理。数理逻辑的胜利,不在于它独占了对「理」的追问,而在于它找到了一种能被机器逐步检查的写「理」的方式——这正是这本册子在第五章反复打磨的边界感。
| 条目 | 内容 | 出处 § |
|---|---|---|
| PA 的语言 | 常元 0;函数 S, +, ·;等号 =;标准模型 ℕ | §5.1 |
| 罗宾逊 Q | 七条公理:后继骨架 + 加乘递归式 | §5.1 |
| 归纳模式 | [φ(0) ∧ ∀x(φ(x)→φ(Sx))] → ∀x φ(x),无穷多条 | §5.1 |
| 原始递归函数 | 零 / 后继 / 投影 + 复合 + 原始递归 | §5.2 |
| 可表示性与 Σ1-完全性 | 原始递归函数被 Σ1 公式逐点算准;真 Σ1 句必可证 | §5.2 |
| 哥德尔编码 | 符号 ↦ 编号;⌜s1⋯sk⌝ = 2#s1⋯pk#sk | §5.3 |
| β 引理 | β(b, c, i) = b mod (1 + (i+1)c);序列 ≡ 一对数(中国剩余定理) | §5.3 |
| 证明谓词 | Proof(p, x) 为 Δ0;Prov(x) :≡ ∃p Proof(p, x) 为 Σ1 | §5.4 |
| 可证性三律 | D1 内化 · D2 传递 · D3 分配(Hilbert–Bernays–Löb) | §5.4 |
| 对角线引理 | 对任意 φ(x) 存在 σ 使 PA ⊢ σ ↔ φ(⌜σ⌝) | §5.5 |
| 哥德尔句 G | PA ⊢ G ↔ ¬Prov(⌜G⌝);读作「本句不可证」 | §5.6 |
| 第一不完备定理 | 一致则 PA ⊬ G;ω-一致则 PA ⊬ ¬G;G 在 ℕ 中为真 | §5.6 |
| ω-一致性 | 证 ∃xθ 则必有标准见证;强于一致性 | §5.7 |
| 罗塞尔句 R | 「若我具有证明,则 ¬R 有更小的证明」;只需一致性 | §5.7 |
| 罗塞尔定理 | 一致即 PA ⊬ R 且 PA ⊬ ¬R | §5.7 |
| 一致性句 | Con(PA) :≡ ¬Prov(⌜0 = 1⌝)(Π1) | §5.8 |
| 第二不完备定理 | PA ⊢ Con(PA) → G,故 PA ⊬ Con(PA) | §5.8 |
| Löb 定理 | PA ⊢ Prov(⌜ψ⌝) → ψ ⟹ PA ⊢ ψ | §5.8 |
| Gentzen 相对一致性 | TI(ε0) ⊢ Con(PA):用 ε0 超限归纳 + 切割消除 | §5.9 |
| 完备 · 可判定 | 完备:⊢φ 或 ⊢¬φ;完备 + 可递归公理化 ⟹ 可判定 | §5.10 |
| 驯服理论 | DLO · Presburger (ℕ,+) · ACF · RCF(含初等欧氏几何) | §5.10 / §5.14 |
| Tarski 不可定义 | 算术真谓词 Tr 不可在算术内定义;Prov ⊊ Tr | §5.11 |
| 独立性 | φ 独立于 T:T ⊬ φ 且 T ⊬ ¬φ | §5.12 |
| 可构造宇宙 L | L0=∅,Lα+1=Def(Lα),L=⋃Lα;L ⊨ ZFC + GCH | §5.13 |
| 力迫 | 偏序 ℙ · 泛型滤子 G · 名字 · 真值引理 ⊩;造 V[G] ⊨ ¬CH | §5.13 |
| CH 独立 | 哥德尔 1938/1940(L)+ 科恩 1963(力迫)⟹ CH 独立于 ZFC | §5.13 |
| 后续 | GCH · Easton · 大基数(实值可测 ⟹ 2ℵ0>ℵ1)· MM/PFA ⟹ 2ℵ0=ℵ2 · Ultimate L | §5.13 / §5.17 |
| 量词消去 | 公式 ↦ 无量词公式;RCF(Tarski–Seidenberg)· Presburger(Cooper)· ACF | §5.14 |
| Chaitin Ω | Ω = Σp 停机 2−|p|;随机、不可计算;K(x) > c 对大 c 不可证 | §5.16 |
| Hilbert 第十问题 | Diophantus 方程可解性不可判定(Davis–Putnam–Robinson 1961 + Matiyasevich 1970) | §5.16 |
符号卡。PA 皮亚诺算术;Q 罗宾逊算术;⌜φ⌝ 公式 φ 的编码;Prov · Con 可证性 / 一致性谓词;Δ0 · Σ1 · Π1 算术层级;G · R 哥德尔句 / 罗塞尔句;L 可构造宇宙;V[G] 力迫扩张;TI(ε0) 沿 ε0 的超限归纳;Ω Chaitin 常数;K(x) 描述复杂度。
定理卡(一句话)。① 第一不完备:一致系统有真句证不出。② 罗塞尔:只需一致性。③ 第二不完备:系统证不了自身一致。④ Löb:Prov(⌜ψ⌝)→ψ 可证则 ψ 可证。⑤ Tarski:算术真谓词不可定义。⑥ Gentzen:ε0 归纳可证 Con(PA)。⑦ 哥德尔 + 科恩:CH 独立于 ZFC。⑧ 分界:乘法与归纳是引爆点。
易错三坑。① 把「不完备」读成「不一致 / 数学不可靠」——不完备只是「有真句证不出」(§5.15);② 把「独立」读成「不可知 / 无意义」——独立是相对某套公理说的,添新公理可定音(§5.13);③ 把定理套到不相干的系统上——须先验「一致 + 可递归公理化 + 足够强」三条件(§5.15 的三问尺子)。
下一步。本章收束,逻辑换一副能在计算机里运行的身体:第六章将走进证明助手、同伦类型论、逆向数学与自动推理,看哥德尔划下的边界如何成为工程与前沿的起点。
前五章走完了一条古老的路线:从三段论到真值表,从一阶逻辑到证明论,从图灵机到哥德尔的边界。每一站都在追问「什么可证、什么可算、什么不可判」。本章换一个身份看这一切——把逻辑当成工程。同一套布尔代数、同一套推理规则,一旦写进计算机,就变成可以逐行检查、可以复用、可以由成千上万名贡献者协作维护的巨型代码库。
「逻辑正在变成工程」有两层意思。第一层是证明的工业化:过去一条定理的证明写在纸上,靠同行的眼睛把关;现在它可以写成机器可校验的脚本,由一个小到可以逐行审读的内核核对,把「每一步都对」压缩成「整棵树类型正确」。第二层是逻辑的产业化:正确性不再只是数学家的洁癖,而成了硬件、编译器、操作系统、数据库、芯片里的硬约束——四色定理与 Kepler 猜想被形式化,CompCert 编译器与 seL4 内核通过了机器验证,模型检测器每天在工业流水线上巡行。
本章沿三级台阶上升,每一级都踩在前一级上。
第一级(§6.1–6.4)——工具。看形式化走过的四十年:Automath(1968)、Mizar(1973)、Coq(1989)、Lean(2013)与它的 mathlib。看类型论如何成为逻辑的另一种写法(命题即类型),看证明助手的内部构造(内核+策略+库),看规模化数学库怎样把「一个人写完」变成「一群人合写」。
第二级(§6.5–6.9)——新基础。看形式化的里程碑(四色定理、奇数阶定理、Kepler 猜想、CompCert、seL4);看同伦类型论如何追问「等式的等式」;看构造主义数学的复兴与计算含义的抽取;看逆向数学怎样给每条定理标价——究竟哪条公理在干活;看力迫法换上布尔值模型这副逻辑面孔。
第三级(§6.10–6.17)——前沿与交汇。连续统假设的新公理之争(Ω-猜想、Ultimate L、Martin 极大公理);大基数纲领与逻辑强度的刻度;描述复杂度与有限模型论(NP 等于存在性二阶逻辑);模型检测、SMT 求解器、数据库与 Datalog;人工智能中的逻辑与神经符号;以及逻辑在中国的百年脉络与本章的未竟之问。
常驻嘉宾:一段可运行的证明。本章会反复引用一小段 Lean 或 Coq 的代码——它证明的往往只是「若 n + 0 = n 则…」这样朴素的事实。代码不长,却浓缩了本章全部关键词:类型(命题被写成类型)、策略(一句话推动一棵证明树)、内核(只认最原始的规则)、库(现成引理随手取用)。读懂这几行,第五章铺垫的一切抽象都会落到实处。
读法建议:本章术语密集,宜把术语当人物记——记住「谁、在什么时候、做了什么」,细节自会各就各位。遇到百年悬案(CH、P vs NP),重点不在记住结论,而在记住问题为什么活到今天。
★★ 形式化(formalization)指把数学命题与证明翻译成机器能逐字核对的形式语言。它有前史,也有六十年的正史。本节把这段正史压成一张时间表,并说明每一代系统的核心难题是什么。
前史:从莱布尼茨到《数学原理》。绪论讲过莱布尼茨之梦——造一台「推理演算机」,把争论交给算。希尔伯特纲领把这一理想推到极致:把全部数学写成形式系统,再用有穷方法证明它的一致性(第五章已见其结局)。真正逼近机器实现的第一座丰碑是怀特海与罗素的《数学原理》(Principia Mathematica, 1910–1913):三卷上千页的符号推演,直到第二卷才把 1 + 1 = 2 变成定理。这份工作证明了两件事——形式化在原理上可行;以及纯手工形式化在人力上不可行。
Automath(de Bruijn,1968 起)。荷兰数学家 N. G. de Bruijn 设计了 AUTOMATH,第一次让机器能够完整检查一段数学证明。它的思想来自一个朴素要求:证明的正确性只应依赖一个极小的规则集合,其余一切都由使用者显式写清。这条「小内核」原则此后为所有证明助手继承。
Mizar(Trybulec,1973 起)。波兰数学家 Andrzej Trybulec 发起的 Mizar 系统,基于 Tarski–Grothendieck 集合论,特点是用接近日常数学散文的语法写证明。它积累了最早的大型数学库——Mizar Mathematical Library,数千篇形式化文章,其中经典的「Mizar 重证」包括 Jordan 曲线定理(2005 年起陆续完成)。
Coq(1984–1989,INRIA)。Coq 的基础是 Thierry Coquand 的《构造演算》(Calculus of Constructions,1984),把依赖类型与高阶逻辑统一起来;1989 年作为系统发布,成为法国 INRIA 的旗舰工程。它是四色定理、奇数阶定理形式化所选用的平台(§6.5)。其后续版本在 2025 年前后改名 Rocq,以示与旧系统的区分。
Isabelle(Paulson,1986)与 Lean(de Moura,2013)。Isabelle 由 Lawrence Paulson 等人提出,其 Isabelle/HOL 建立在简单类型论之上,以人类可读的 Isar 证明语言与强大的自动化(Sledgehammer)著称;HOL Light(John Harrison,1996)则是另一支轻量实现,Kepler 猜想项目(Flyspeck)即以它为主力。Lean 由 Leonardo de Moura 在微软研究院发起(2013),Lean 4(2021 起)重写内核并强化元编程,直接催生了数学库 mathlib(§6.4)。
| 系统 | 起始年 | 逻辑基础 | 代表作 |
|---|---|---|---|
| Automath | 1968 | 类型论(de Bruijn) | 首个可用证明检查器 |
| Mizar | 1973 | Tarski–Grothendieck 集合论 | Mizar 数学库 |
| Coq / Rocq | 1989 | 构造演算 | 四色定理、奇数阶定理 |
| Isabelle/HOL | 1986 | 简单类型论 | Isar、大规模自动证明 |
| HOL Light | 1996 | 简单类型论 | Flyspeck(Kepler 猜想) |
| Lean 4 | 2021 | 依赖类型论 | mathlib |
这张时间表里藏着一条主线:内核越来越小,库越来越大。de Bruijn 定的规矩——把信任压缩到一个可以逐行读的检查器——从未改变;变的是围绕内核的工程:更聪明的策略、更自动的引理搜索、更大规模的协作库。下一节先补上「类型论」这门地基课。
★★★ 证明助手为什么用「类型」而不是「公式」来写命题?答案是一条跨越编程与逻辑的对应,它把「证明」翻译成「程序」。本节给出这条对应,并解释依赖类型为何是它的关键。
这条对应最早见于 H. B. Curry 1934 年对组合子与蕴涵的观察,1969 年由 William Howard 明确陈述,故称 Curry–Howard 对应。它的价值在于:逻辑的连接词一个不落地对应到程序构造上:
| 逻辑 | 类型论 | 程序含义 |
|---|---|---|
| ⊤(真) | 单位类型 | 只有一个平凡值 |
| ⊥(假) | 空类型 | 无值可造 |
| A ∧ B | 积类型 | 一对值 (a, b) |
| A ∨ B | 和类型 | 左注入或右注入 |
| A → B | 函数类型 | 把证明 A 变成证明 B |
| ∀x. A | Π 类型 | 对每个 x 返回证明 A |
| ∃x. A | Σ 类型 | 见证 x 与其证明 |
依赖类型论的现代形态由 Per Martin-Löf 在 1972 年前后给出(直觉主义类型论),它把「类型」「项」「相等」都作为原语,并引入归纳类型——自然数、列表、树都由「构造子」与「递归」定义,而不是预先假定存在。证明助手的内核据此搭建:命题写成类型,证明写成项,检查证明就是检查项的类型是否正确。
为什么「依赖」是分水岭。在简单类型论里,每个项都有固定的类型,无法谈论「长 n 的向量」这类随值变化的类型;而在依赖类型论里,类型可以「携带数据」,于是数学中大量「先构造对象、再断言其性质」的论证都能直接编码。这也是 Coq、Lean、Agda 与 Isabelle/HOL(简单类型论)在表达力上的主要分歧点:依赖带来精确,也带来复杂性——类型检查可能变得更难,需要使用者更谨慎地设计定义。
一句话记住本节:命题是类型,证明是程序,验证是类型检查。第三章讲过的「证明即程序」在这里从口号变成了可运行的架构。
★★★ 本节把四个主流系统摆在一起看,并给两段可读的证明:一段 Coq,一段 Lean。读代码时两件事——命题如何写成类型,以及一句「策略」如何推着证明走。
Coq / Rocq。基于构造演算与归纳类型,用 Ltac(及后来的 SSReflect)写证明脚本。它的强项在代数、有限群与几何的形式化,第 §6.5 的四色定理与奇数阶定理都出自这里。Coq 证明常以「引理—策略序列—Qed」的形式呈现,末了的 Qed 会触发内核复核整棵树。
(* 命题即类型:证明「若 P 则 P」 *) Theorem identity : forall P : Prop, P -> P. Proof. intros P H. (* 引入命题 P 与假设 H : P *) exact H. (* 目标恰是 H 所证者,直接交出 *) Qed. (* 归纳类型:把「偶」定义出来,再证 4 是偶数 *) Inductive even : nat -> Prop := | even0 : even 0 | evenS : forall n, even n -> even (S (S n)). Lemma even_4 : even 4. Proof. apply evenS. apply evenS. apply even0. Qed.
第一段展示了「蕴涵即函数」:假设 H : P 就是一个「证明项」,exact H 把它当成返回值。第二段展示了归纳类型:even 不是靠外部定义,而是由两条构造子规则「生成」出来的;even 4 的证明就是把 evenS 用两次、even0 用一次拼起来。
Lean 4。同为依赖类型论,但内核重写、元编程更强,策略与编程在同一个语言里。mathlib 建在它之上。下面这段证明加法交换律,走的是标准的数学归纳:
-- 命题即类型:证明自然数加法的交换律
theorem add_comm' : forall m n : Nat, m + n = n + m := by
intro m n
induction n with
| zero => simp -- m + 0 = 0 + m,用 add_zero 与 zero_add
| succ k ih => simp [Nat.add_succ, ih]
-- m + (k+1) = (m+k)+1,(k+1)+m = (k+m)+1
induction 把目标拆成「基础」与「归纳步」,ih 是归纳假设;simp 是自动化策略,负责用一批已登记的重写规则把两边化到同一项。注意 simp 并不「猜」——它只是在库里查找适用的重写规则,找不到就停;最终谁来判定成立,仍是内核。
Isabelle/HOL 与 Agda。Isabelle/HOL 建立在简单类型论上,用 Isar 写人类可读的「结构化证明」,并由 Sledgehammer 调用外部自动定理证明器找引理——它的哲学是「让机器多干、人少打字」。Agda 走另一端:依赖类型、没有策略语言,证明就是纯粹的程序项;它的立方版本(Cubical Agda)直接支持同伦类型论(§6.6)。四个系统对应四种取舍:自动化(Isabelle)、库生态(Lean)、可靠性与代数(Coq)、类型论的纯粹性(Agda)。
怎样选系统。教材式的判据是:想快速上手写程序式证明,用 Lean 或 Agda;想调用庞大自动化,用 Isabelle;想复用最成熟的代数证明库,用 Coq。真做研究时,选择往往由「伙伴的库」决定——形式化是一项极依赖生态的活动,这一点在下一节 mathlib 的规模上会看得最清楚。
★★★ 一个人的证明助手只是工具,一群人的证明助手才叫基础设施。本节讲 mathlib——一座由全球贡献者共同维护的 Lean 数学库,以及它给「规模化形式化」提出的新问题。
规模。mathlib 于 2017 年前后起步,如今已是上百万行的代码库,收录数十万条定义与定理,从自然数与实数的基本律,到群论、线性代数、拓扑、测度论、代数数论。据通行统计,它每年新增的定理数以万计;通读一遍所需的时间,早已超出任何个人的寿命——这正是「规模化」三字的字面意思。作为对照,Mizar 数学库花了数十年积累万余篇条目,Flyspeck 一个项目就动用了数十人年的协作。
自动化:让机器替人翻书。规模化靠的不只是人多,更是自动化策略。
| 策略 | 任务 | 书的对应 |
|---|---|---|
| simp | 用重写规则化简目标 | 「由定义化简」 |
| ring / field_simp | 交换环 / 域中的恒等式 | 「通分、整理」 |
| linarith / omega | 线性算术 / 整数算术 | 「解不等式组」 |
| norm_num | 数值与算术常量 | 「按计算器」 |
| aesop | 通用搜索式证明 | 「试遍常见招式」 |
这些策略不是「黑箱魔法」,而是可审计的元程序:它们构造一条证明路径,最终仍要交给内核复核。若一条策略给出的证明无法通过内核,整个文件都编译不过去——自动化带来的便利,由内核的严格兜底。
Lake 与持续集成。Lean 4 配套的包管理器 Lake 负责依赖管理与版本锁定;mathlib 每次提交都跑持续集成(CI),把整库重新编译一遍,确认无人踩坏别人的引理。这套工程实践把数学变成了类似开源的软件项目:引理有命名规范,证明有风格指南,改动要走审查。命名冲突、定义重复、编译时间过长,成了形式化数学的新「工程难题」——它们的解法往往来自软件工程,而非逻辑本身。
规模化的意义。当库足够大,「形式化某条新定理」常常变成「在库里找现成的引理、把新证明接到旧证明上」——这正是人类数学家的工作方式,只是全部搬进了机器。它带来一个耐人寻味的推论:形式化数学会「逼」出更干净的证明,因为复用要求定义规整、引理通用;一个只顾自己好用、与库格格不入的写法会被审查拦下。第五章讲过的「完备性与边界的抽象提问」,在这里落成了具体的工程纪律。下一节进入形式化最耀眼的成果——那些被机器彻底核验过的大定理。
★★★ 形式化从数学边缘走进中心,靠的是一批「硬骨头」被机器啃下。本节挑五块里程碑,附带它们各自的难点与代价。
四色定理(Coq,2005)。「任何平面地图可用四色染色,使相邻区域异色」是 1852 年 Francis Guthrie 提出的猜想。1976 年 Kenneth Appel 与 Wolfgang Haken 给出了第一个证明,但它依赖计算机检查约两千种「不可避免构形」——这引发了长达二十年的争论:一个靠程序跑出的证明,算不算证明?2005 年,Georges Gonthier 与 Benjamin Werner 在 Coq 中完整形式化了整个论证,2008 年正式发表。意义不在于「又证了一遍」,而在于:连程序本身也被形式化进了证明,检查者不必信任那段 C 代码,只需信任 Coq 的小内核。
奇数阶定理(Coq,2012)。Feit–Thompson 定理(1963)断言:每个奇数阶有限群都是可解的。它原文长达 255 页,是有限群论的分水岭。Gonthier 团队用 Coq 完成形式化(2012 年完成,2013 年发表),工程浩大,也顺带锤炼了 Coq 的代数库——数学结构与类型的工程实践由此成熟。
Kepler 猜想(Flyspeck,2014)。Kepler 于 1611 年猜想:等体积球体的最密堆积密度为 π/(3√2) ≈ 0.7405。Thomas Hales 于 1998 年宣布证明,最初发表在《数学年刊》的文稿含大量计算;为终结信任争议,他发起 Flyspeck 项目,用 HOL Light 与 Isabelle 把整个证明形式化,2014 年完成,2017 年正式发表。这是一次「为消除怀疑而重做」的形式化。
编译器与内核:CompCert 与 seL4。形式化不止于纯数学。CompCert 是 Xavier Leroy 等人自 2005 年起用 Coq 验证的 C 编译器——它证明「编译后的机器码与源程序语义一致」,把「编译器 bug 导致程序错误」这一整类风险排除在外。seL4 是 NICTA(后属 CSIRO/DATA61)于 2009 年完成形式化验证的微内核,用 Isabelle/HOL 给出功能正确性证明——操作系统内核第一次被证明「代码真的做了规范说的事」。
| 里程碑 | 年份 | 平台 | 难点 |
|---|---|---|---|
| 四色定理 | 2005 | Coq | 计算机检查的构形被形式化 |
| 奇数阶定理 | 2012 | Coq | 255 页群论论证的工程化 |
| Kepler 猜想 | 2014 | HOL Light / Isabelle | 大量非线性数值计算 |
| CompCert | 2005 起 | Coq | 编译器语义的正确性 |
| seL4 | 2009 | Isabelle/HOL | 内核功能正确性 |
里程碑的共同教训。它们都不是「机器替人想出了证明」,而是「人想到了证明,机器负责一字不差地验收」。形式化不生产新数学(偶尔会暴露旧证明的漏洞),它生产的是不可动摇的确定性。当论证巨大到任何个人都无法完整核查时——255 页的群论、上千行计算的地图染色、上万行的编译器——只有形式化能把「相信」换回「检查」。这正是下一节转向新基础之前,先立下的一块路标。
★★★★ 一条等式凭什么等于另一条等式?这个看似无聊的问题,催生了 2006 年以来最活跃的一支逻辑-数学基础纲领:同伦类型论(HoTT)。
出发点:等式的类型。在类型论里,「a = b」本身是一种类型,它的项就是「a 等于 b 的证明」。既然它也是类型,就同样可以问:「两个等式证明 p 与 q 是否相等?」——于是有了「等式的等式」。1994–1998 年间,Martin Hofmann 与 Thomas Streicher 给出了一个关键观察:若把类型看成「空间」、把等式证明看成「连接两点的路径」、把等式的等式看成「路径之间的同伦」,那么类型论天然自带群胚(groupoid)结构。
单值公理。HoTT 的核心公理只有一条,却极强:单值公理(univalence axiom)——类型之间的「相等」与「等价」可以互相转化:
用粗话说:同构的对象彼此相同,可以互相替换。数学里「同构的结构视为同一个」这条日常惯例,在 HoTT 里被升格为公理。它的威力立竿见影——比如函数外延性(两个处处相等的函数相等)由它导出。Voevodsky 在 2006 年前后开始探究这一方向,2012–2013 年在普林斯顿高等研究院发起专门学年,2013 年出版的《同伦类型论基础》(俗称 HoTT 书)系统总结了这一纲领。
2026 年的状态。HoTT 已经孵化出几支活跃的工程:UniMath(Coq 上的 HoTT 库)、立方类型论(Cohen–Coquand–Huber–Mörtberg,2015–2016 提出,用「立方」结构让单值公理可以像普通运算一样计算),以及支持立方类型论的 Cubical Agda;Lean 社区也有实验性的 HoTT 分支。但要如实说明:主流数学库 mathlib 至今仍建立在经典逻辑与选择公理之上,并未转向 HoTT——HoTT 目前更多是新基础与类型论前沿的研究纲领,而非大规模数学形式化的主战场。它的价值,一部分正在于逼问一个老问题:数学的「相等」究竟有几种含义?
若说前几章关心的是「证明能不能被机器检查」,HoTT 关心的是更精细的一层:「证明与证明之间的区别,机器能不能也看明白」。
★★★ 构造主义曾是二十世纪初数学基础之争中的少数派,如今却因为「证明即程序」而复活。本节讲它的历史、它的原则,以及它最实用的收获——从证明里抽出算法。
从 Brouwer 到 Bishop。荷兰数学家 L. E. J. Brouwer 于 1907 年前后创立直觉主义:数学对象是心智的构造,否定排中律的普遍有效——对无穷对象,「非非 A」未必就是「A」。Arend Heyting 于 1930 年把直觉主义逻辑形式化,给出不含排中律的联结词规则。1967 年,美国数学家 Errett Bishop 出版《构造性分析基础》,用纯构造的方式重做了大块实分析,且不必卷入哲学论战——他要证明的是:不以排中律为靠山,数学照样能长。这一路线史称「Bishop 构造分析」。
计算含义的抽取。BHK 解释的实用价值在于:一个构造性证明就是一个算法。证明 ∀x. ∃y. P(x, y),就内含一个「输入 x、输出 y」的程序;证明里若用了排中律或选择公理,这个程序可能抽不出来。Coq 等系统提供 程序抽取(extraction):把证明里的构造部分翻译成 OCaml 或 Haskell 代码,直接当程序跑。Stephen Kleene 在 1945 年提出的可实现性(realizability)从理论上保证了这一翻译的合理性:命题的真可由「实现它的数」来刻画。
与经典逻辑的关系。构造主义并不否定经典数学的成果,而是追问「哪一步用到了排中律」。一个经典定理若能改写成构造版本,往往意味着它含有一个可执行的内容;改不成,则说明它只是「存在性断言」而无实际构造。Gödel 与 Gentzen 的负翻译给出了一座桥:经典算术可以嵌入直觉主义算术,经典的一致性问题由此转化为构造系统的一致性问题(这在第五章哥德尔的讨论中被反复用到)。构造主义不是对经典的否定,而是给经典标注了「计算成本」。
一句总结:排中律让证明「省事」,构造性让证明「能跑」。当证明要被机器执行时,后者重新变得贵重——这就是它在当代复兴的理由。
★★★★ 通常的数学是「公理 → 定理」:假定公理,推出结论。逆向数学倒过来问:要证出这条定理,最少需要哪条公理?——它给每条定理标上一个精确的「公理价格」。
纲领的由来。逆向数学由 Harvey Friedman 在 1970 年代提出思路,Stephen Simpson 在《二阶算术子系统》(1999 年首版)中系统化。它把研究范围限制在二阶算术(对象是自然数与自然数集合,既能谈数论也能谈分析),然后考察「定理 T 与公理组 S 等价」这种精细的对应关系:T 通常是一条常见数学定理,S 是某个标准子系统。
逆向数学的核心发现是:大量「普通数学」定理恰好落在五层中的某一层上,且与该层的公理等价。据 Simpson 的经典等价表:
| 子系统 | 加入的公理 | 与之等价的常见定理(通行说法) |
|---|---|---|
| RCA0 | 基系统(可计算数学) | 有理数系的基本性质、连续函数的初等性质 |
| WKL0 | 弱 König 引理 | Heine–Borel 覆盖定理、Brouwer 不动点定理、可分 Hahn–Banach、一阶逻辑完备性 |
| ACA0 | 算术概括 | Bolzano–Weierstrass 定理、[0,1] 的序列紧性、Baire 纲定理 |
| ATR0 | 算术超限递归 | 完美集定理、Ulm 定理、Σ11 分离 |
| Π11-CA0 | Π11 概括 | 更强的 Cantor–Bendixson 定理、可数良序的深层比较 |
举例说明这套标价的用处。Heine–Borel「闭区间上的任一开覆盖有有限子覆盖」听起来像分析的基本功,逆向数学却指出:它等价于弱 König 引理——而弱 König 引理在可计算的意义下是「非构造」的。Bolzano–Weierstrass 更贵,它等价于算术概括,需要「判定任意算术性质」的能力。于是「这条定理用了几斤公理」从玄学变成了可计算的账目——这与第一章反复演练的「给设计参数标价」是同一种气质的数学。
意义。逆向数学把「这条定理到底假设了什么」变成了一门可核算的学问,也让「构造性」与「非构造性」的边界有了精确刻度(§6.7 的讨论在此获得量化)。它提示:数学定理并非同样「昂贵」;看清一条定理需要哪一层地基,往往比记住它的证明更有价值。下一节把目光转向集合论——那里也有类似的「换地基」操作,名字叫力迫。
★★★★ 第五章讲过 Cohen 用力迫法证明连续统假设(CH)独立。本节换一副眼镜重看力迫:它其实是一种多值逻辑——把「真」从两个值扩充成一个布尔代数。
从「扩模型」到「赋值」。Cohen 式的力迫,直觉上是往原先的集合论宇宙 V 里「塞进」一个全新的集合 G(脱胎于一个偏序集 ℙ 上的脱殊滤子),得到更大的宇宙 V[G]。Dana Scott、Robert Solovay 与 Petr Vopěnka 在 1965 年前后给出了一种等价的、纯代数的表述:不必真的构造新模型,只需在一个布尔值模型 V𝔹 里工作,其中每个命题被赋予一个「真值」,而真值取自一个完备布尔代数 𝔹,而非只有「真/假」两值。
逻辑面孔。这套表述把力迫翻译成了逻辑:
由此,力迫法与「多值逻辑」「直觉主义逻辑的代数语义」连成一气:完备布尔代数既是力迫的真值空间,也是命题逻辑的一种代数语义(每本布尔代数都是一组二值赋值的交集)。Grothendieck 拓扑与 topos(拓扑斯)把这一思想推到极致——集合论的宇宙可以被一个更一般的「范畴中的逻辑」取代,而力迫只是其中最经典的一个例子。
交汇点。这张面孔揭示了逻辑与集合论的深层互穿:集合论的问题(CH 是否成立)可以用逻辑的工具(多值语义、代数语义)来回答,而逻辑本身的很多概念(完备性、独立性、模型)又要在集合论的地基上建立。下一节就顺着这条线,去看 CH 在今天引发的公理之争——那是这项百年工程仍在施工的地方。
★★★★ 第五章已经确立:连续统假设(CH)与 ZFC 独立——Gödel(1938)用可构成宇宙 L 证明 ZFC + CH 相容,Cohen(1963)用力迫证明 ZFC + ¬CH 相容。独立意味着「ZFC 管不着 CH」。这引出希尔伯特第一问题在今天的真正形态:要不要为数学添一条新公理,把 CH 定下来?而两派给出的答案针锋相对。
一条线索:极大性原理。Martin 极大公理(Martin's Maximum,MM)由 Foreman、Magidor、Shelah 于 1988 年提出,它把 Martin 公理推广到「保稳(proper)力迫」,粗糙地说:宇宙已经尽量「饱和」,任何能用保稳力迫造出的对象都已存在。它的近亲——保稳力迫公理(PFA,Shelah)——同样是一条极大性原理。二者都导出同一个惊人的算术推论:
而 CH 说的恰恰是 2ℵ0 = ℵ1。于是 MM / PFA 与 CH 冲突——它们为「CH 为假」提供了一个有原理支撑的候选答案。支持这一路线的学者视其为「极大性」哲学的胜利:数学宇宙应当尽量丰富,CH 却让实数轴过于贫瘠。
另一条线索:Ultimate L。另一派追随 Gödel 的旧思路——寻找一个「规范的、能被清晰描述」的内模型,让所有重要问题在其中都有确定答案。W. Hugh Woodin 自 2000 年前后提出 Ω-猜想与候选内模型 Ultimate L(终极 L)。设想若成立,则在 Ultimate L 中 CH 为真:2ℵ0 = ℵ1。Woodin 的目标是给出一条新的公理 V = Ultimate L,它像「V = L」的现代替身,既是内模型(因而规范),又能把大量在 ZFC 中不确定的命题一举定下。
| 路线 | 代表公理 | 对 CH 的裁决 | 哲学 |
|---|---|---|---|
| 极大性原理 | MM / PFA | 2ℵ0 = ℵ2(CH 假) | 宇宙尽量丰富 |
| 规范内模型 | V = Ultimate L | 2ℵ0 = ℵ1(CH 真) | 宇宙尽量确定、可描述 |
为什么还没定论。争议的焦点不是技术细节,而是什么才算「好的」新公理:极大性原理取胜于「结构丰富」,Ultimate L 取胜于「规范确定」,两者的合理性标准不同,难以直接比较。加之 Ω-猜想的成立与否本身仍悬而未决(它依赖 Woodin 基数的深层性质,见 §6.11),这条路线的最终裁决至今未下。据通行说法,多数集合论学家对未来持开放态度:CH 的最终归属,也许要等新公理理论本身成熟之后才会明朗。
这一节的意义不在于选边,而在于让人看见:独立不等于「没有答案」,只是答案要由 ZFC 之外的新公理来提供——而哪些新公理值得接受,正是数学哲学最前沿的活儿。
★★★★ 如果说 CH 之争关乎「哪些命题有答案」,大基数纲领关乎「我们愿意假定宇宙有多大」。本节给出一串比 ℵ0、ℵ1 大得多的「巨大基数」,并说明它们如何被排成一条精确的强度刻度尺。
层级。大基数不是散落的孤点,而是构成一条线性有序的梯子:越靠上的基数蕴含越靠下的基数存在,也蕴含更强的一致性强度。下面的清单由弱到强(据通行说法):
| 大基数 | 直觉刻画 | 强度关系 |
|---|---|---|
| 不可达 | 正则、强极限 | ZFC 不可证其存在 |
| Mahlo | 其下的不可达基数构成驻集 | 强于不可达 |
| 弱紧致 | κ 上的树有 κ 长分支 | 强于 Mahlo |
| 可测 | 存在 κ-完全非主超滤 | 蕴含 V ≠ L |
| 强紧致 / 超紧致 | 更强的嵌入性质 | 逐级递增 |
| Woodin 基数 | 支配投影集的决定性 | 为 Ω-猜想所依赖 |
可测基数:第一次「跳到 L 之外」。可测基数的定义用到一个 κ-完全非主超滤子。它的重要性在于一条经典定理:可测基数的存在蕴含 V ≠ L(Dana Scott,1961)——也就是说,一旦承认存在一个可测基数,可构成宇宙 L 就不再等于真实的集合论宇宙。这是大基数理论的第一记重锤:它不只是「更大的数」,而是关于宇宙形状的断言。
为什么它算「逻辑层级」。大基数的真正用处不是造大集合,而是校准证明强度。许多数学命题(例如「所有投影集都是可测的」「实数集上的博弈决定性」)无法在 ZFC 中判定,但可以与某级大基数的存在性精确对应——例如投影决定性(PD)与大基数的存在强度相关,Woodin 的工作建立了「无穷多 Woodin 基数」与「L(ℝ) 理论的决定性」之间的桥梁。于是大基数成了一把尺子:一条越强的命题,需要越高的基数来支撑。这把尺子与 §6.8 逆向数学的「五层塔」气质相通——都是在给数学命题标出强度价格,只不过一个向上(大基数)、一个向下(最弱子系统)。
一句话记住本节:大基数是集合论宇宙的「海拔刻度」,它衡量的是「假定宇宙有多高」,而不同海拔恰好对应用不同强度的数学命题。
★★★★ 复杂度讲的是「算得多快」,逻辑讲的是「说得多准」。描述复杂度把两者焊在一起:一个复杂度类,等于某一类逻辑公式能表达的全体性质。它的开山之作是 Fagin 1974 年的一条规定。
这条定理之所以震撼,是因为它把「非确定性多项式时间」这样一个计算资源概念,翻译成了一句纯逻辑的话。它的证明骨架也漂亮:NP 的证书(如哈密顿圈的顶点序列)本身就是存在量词要的那个二阶对象;反向地,给定一个 ∃SO 语句,非确定性地猜出那组关系,再用一阶求值多项式时间验证即可。
沿着这条线,一套「逻辑 ↔ 复杂度」的词典被逐条建立(在有序的有限结构上,据通行结果):
| 逻辑 | 复杂度类 | 出处 |
|---|---|---|
| 一阶逻辑 FO(带序) | 一致 AC0 | 经典 |
| FO + 传递闭包 TC | NL(非确定对数空间) | Immerman 1987 |
| FO + 最小不动点 LFP | P | Immerman 1986 / Vardi 1982 |
| 存在性二阶逻辑 ∃SO | NP | Fagin 1974 |
| 二阶逻辑 SO | PH(多项式层级) | Stockmeyer 1976 |
Ehrenfeucht–Fraïssé 博弈。「这句一阶话能不能分辨两个结构?」这个问题有一个游戏化的判据。把两个结构 𝒜 与 ℬ 摆上桌,两位玩家轮流挑元素:甲在一边挑一个点,乙必须在另一边挑一个「对应点」,共走 k 轮;若 k 轮后对应的点组满足完全相同的一阶关系,则乙获胜。定理断言:乙有必胜策略,当且仅当 𝒜、ℬ 满足同一批「量词深度不超过 k」的一阶语句。这个博弈把「一阶可分辨性」变成了一场有胜负的游戏,是有限模型论与描述复杂度的主力工具。
一个副产品。有限模型论还给出了一条关于「随机结构」的定理:Fagin 1976 年证明,对有限结构上的任一 FO 语句,当规模趋于无穷时,它几乎必然为真或几乎必然为假(0-1 律)。略作推理即得一个漂亮的推论:任何不能「几乎必然」地判定的性质(如奇偶性)都不是一阶可表达的。逻辑的边界由此获得了「概率」这一全新的测量方式,也让人隐约看见 P vs NP 的深层身影——若 NP = co-NP,则 ∃SO 将与它的补类相撞,而这正是这座词典最贵的一个未解之谜。
★★★ 逻辑不只待在书房里。有一支逻辑,从上世纪八十年代起就搬进了芯片设计室,每天替工程师检查电路与协议是否满足规格——它叫模型检测(model checking)。
起源:1981 年的两路人马。E. M. Clarke 与 E. A. Emerson 于 1981 年提出用分支时序逻辑 CTL描写系统的性质,并给出自动检验的算法;几乎同时(1982),Jean-Pierre Queille 与 Joseph Sifakis 提出了结构相近的方法。三人因此在 2007 年共同获得图灵奖。此前的 1977 年,Amir Pnueli 已提出用线性时序逻辑 LTL刻画程序性质——「活着就总会有响应」「不会永远停在坏状态」这类命题,第一次被写成精确的时序公式。
算法与「状态爆炸」。模型检测的基本算法很直白:把系统写成状态转移图,把规格写成时序公式,然后机械地搜索——看图上有没有反例路径。如果找到,就输出一条具体轨迹(工程师最爱这个「反例」);如果找不到,就报告「系统满足规格」。难点在于状态数是「变量数的指数」——所谓状态爆炸问题。1990 年代的两项突破缓解了它:一是符号模型检测(Ken McMillan 等,1992)用二叉决策图(BDD)符号地表示状态集合;二是有界模型检测把问题化为布尔可满足性(SAT),交给高效的 SAT 求解器(CDCL 算法)。
SMT 求解器:逻辑的另一件工业兵器。与模型检测并行的,是可满足性模理论(SMT)求解器——Z3、CVC5 等。它们把 SAT 求解器与背景理论(整数线性算术、数组、位向量、未解释函数)结合,能判定「这组约束有没有解」。SMT 求解器今天广泛用于程序验证、符号执行、软件测试用例生成、甚至数学猜想的反例搜索。它们与证明助手互补:证明助手保证「证明正确」,SMT 求解器负责「快速找答案或反例」。
工业界为什么离不开它。芯片流片一次代价高昂,协议漏洞可能导致真实事故。用模型检测在「设计图纸」阶段穷尽检查,等于给系统做一次数学体检。据通行说法,Intel、AMD、IBM 等公司在上世纪末先后遭遇过因逻辑错误导致的芯片召回,此后普遍引入形式验证团队——逻辑由此从数学殿堂走进了生产线。它与形式化证明(§6.5)是一对:一个面向「有限状态的自动判定」,一个面向「无限数学的机器核验」。
★★★ 每天被亿万人使用的数据库查询语言 SQL,其理论祖先是逻辑。把这条传承讲清楚,是「逻辑变成工程」最日常的注脚。
Codd 的模型(1970)。IBM 的 Edgar F. Codd 于 1970 年发表《大型共享数据库的关系模型》,提出把数据组织成「关系」——即数学上的表(一组元组),而不是当时流行的层次或网状结构。他的核心洞见是:数据与「怎么查」无关,只与「查什么」有关。为此他引入了一组运算,合称关系代数。Codd 于 1981 年获图灵奖。
| 运算 | 符号 | 含义 |
|---|---|---|
| 选择 | σ | 按条件挑出满足的行 |
| 投影 | π | 挑出指定的列 |
| 连接 | ⋈ | 按共享列把两张表拼起来 |
| 并 / 差 | ∪ / − | 集合的并集 / 差集 |
| 笛卡尔积 | × | 两表的全部组合 |
这一定理的有趣推论是:既然查询等于一阶逻辑,那么一阶逻辑的局限就是查询语言的局限。例如「传递闭包」(从一张父子表求出全部祖先—后代对)不是一阶可表达的——这解释了为什么 SQL 早期版本难以优雅地表达递归查询,必须等到后来的递归扩展(如 SQL:1999 的 CTE)才补上。
Datalog:把不动点加进来。为表达递归查询,逻辑界给出了 Datalog:用「规则」从句(形如 P(x) ← Q(x), R(x))不断推导新事实,直到不再有新事实为止——这正是「最小不动点(LFP)」语义。回忆 §6.12 的词典:FO + LFP 恰好刻画复杂度类 P。这意味着 Datalog 的表达力与「多项式时间可判定」相关;它把递归、不动点与计算复杂度在一个语言里串了起来。Chandra 与 Harel 在 1982 年的工作系统研究了不动点逻辑与查询语言的复杂度,是这条线索的关键文献。
从理论到生活。今天的数据库系统(无论是 PostgreSQL 还是云上的分布式引擎)在内部都要做「查询优化」——把一条 SQL 改写成执行代价更低的等价查询。可优化的前提,正是「等价」二字可以被精确判定,而这套判定规则来自关系代数与逻辑。于是这样理解:每一次在手机上滑动列表、每一次电商结账,背后都有一小块一阶逻辑在替人干活。这正是本章开篇那句「逻辑正在变成工程」的日常尺度。
★★★ 逻辑与人工智能的渊源比多数人以为的更深——早期 AI 几乎等于「符号逻辑 + 搜索」。本节梳理这条线索,并说明为什么今天它又回来了。
知识表示:把「知道的事」写成公式。要让机器推理,先得把知识形式化。这一支叫知识表示,其经典形态是描述逻辑(Description Logic)。描述逻辑是一阶逻辑的一个可判定片段,专为「概念与个体」的关系设计:概念(如「人」「哺乳动物」)之间可定义包含与交并补,个体用概念断言。它最著名的落地成果是本体语言 OWL——万维网联盟推出的《网络本体语言》,用于语义网上的知识共享。
知识图谱是描述逻辑在工业界的近亲:用「实体—关系—实体」的三元组存储知识(如「北京—位于—中国」),底层常对应 RDF 数据模型。它们的查询与推理,与 §6.14 的关系代数、Datalog 一脉相承。
自动定理证明:从 Logic Theorist 到当代求解器。1956 年,Newell、Shaw 与 Simon 的 Logic Theorist 用搜索证明《数学原理》里的命题,被视为 AI 诞生的标志之一;1958 年,王浩(Hao Wang,1921–1995)编写的程序在几分钟内证明了《数学原理》中数百条定理,据通行说法,其效率令当时的同行惊讶。1965 年 John Alan Robinson 提出归结原理,把一阶逻辑的证明化归为「消去互补文字」的机械过程,成为自动定理证明(ATP)的基石;它的编程化身是 Prolog(1972 年前后由 Colmerauer、Kowalski 等人发展),一度是 AI 的主力语言。今天,一阶 ATP 系统(如 Vampire、E)与 SMT 求解器(§6.13)继续在软件验证中服役。
神经符号:两条路线的会师。1980 年代之后,AI 的重心从符号推理转向统计学习,逻辑一度退居幕后。近年「神经符号」成为热门方向:用神经网络处理感知与直觉,用逻辑(或逻辑约束)保证推理的可解释与一致——例如用 SMT 求解器检查大语言模型的输出是否自相矛盾,用知识图谱给生成内容「接地」。据通行说法,这一方向尚未成熟,但它重新提出了最初的问题:机器的「推理」与「联想」能不能在同一副身板上共存?
为什么逻辑在 AI 里不可替代。统计模型擅长「像不像」,逻辑负责「对不对」。当系统要给出保证——「这个药物交互检查不会漏」「这段合同条款不矛盾」「这个证明没错」——就必须有可机械核验的推理。这也解释了本章的一条暗线:逻辑的工具(SAT/SMT、模型检测、证明助手、描述逻辑)不是 AI 的对手,而是它的质检部门。
★★ 数理逻辑在中国的落地只有一个世纪,但「什么算一个说法、什么算一个推断」的追问,在中国的名辩传统里早有回响。本节先接现代一脉,再回望古代源头。
传入:1920 年代的一场讲学。1920 年至 1921 年,罗素应讲学社之邀来华讲学,在北京等地系统介绍数理逻辑与哲学,成为这门学科进入中国的重要契机。此前梁启超等人对西学的引介已铺好路基,此后一批学人负笈海外、专攻逻辑,回国后把它立成大学里的正式课程与研究方向。
第一代奠基者。金岳霖(1895–1984)是中国现代逻辑的主要奠基人,曾在哥伦比亚、剑桥求学(据通行说法,他在剑桥期间受罗素与摩尔影响),回国后在清华大学讲授逻辑,著有《逻辑》(1937)、《论道》(1940)、《知识论》等,把逻辑学与哲学、认识论一并引进。沈有鼎(1908–1989)是金岳霖的学生,后赴哈佛求学(受教于 Quine 等人),回国后既研究数理逻辑,又专精中国古代逻辑思想,其《墨经的逻辑学》(1980)是这一领域的里程碑。王宪钧(1910–1993)长期主持数理逻辑教学,所著《数理逻辑引论》(1982)影响了几代学子。胡世华(1912–1998)在中国科学院从事数理逻辑与递归论研究,推动了这门学科在中国的建制化。
机器证明的一支中国力量。1977 年,数学家吴文俊(1919–2017)提出几何定理机器证明的特征列方法(俗称「吴方法」):把几何命题化为多项式方程组,再用代数消元判断其是否成立。它把「证明几何定理」变成可机械执行的代数计算,在国际上引起广泛反响,也让中国在自动推理领域占有一席之地。万维网之前、证明助手之前,这条路线已经展示了「把推理交给计算」的可能。
回望:《墨经》的名辩传统。《墨子》中的《经上》《经下》《经说上》《经说下》诸篇合称《墨经》,其中系统讨论了「辩」(论证)的方法,提出「故」「理」「类」三物——相当于说:论证要有根据(故)、要合规则(理)、要能类推(类)。《墨经》还给出了大量与今日逻辑密切相关的论题:对「是而且非」的批评、对「类」同异的辨析、对「推」的定义。与之呼应的名家(惠施、公孙龙)则围绕「名实」「同异」反复论辩。与古希腊相比,中国的名辩传统同样关心「怎样说服、怎样指出对方的错」,只是它更多依附于政治与伦理的语境,未发展为公理化的话语体系。这不是「中国没有逻辑」的证明,而是提醒:逻辑可以有不同的生长方式。
当代状况。今天,数理逻辑在中国已是成熟学科:高校普遍开设逻辑学课程,数学系有数理逻辑与模型论方向,计算机系有形式化方法与自动推理团队,哲学系有逻辑哲学与逻辑史研究。形式化数学、SMT 求解、程序验证等方向也有活跃的国内团队与国际合作。一个世纪前那个「来华讲学」的起点,如今已经长出了一片自己的林子。
★★★ 本章走了一大圈,最后一页回到提问。逻辑从公元前走到今天,留下了一批没有答案的问题——它们不是「还没人算出来」的习题,而是「不知何时能算出来」的悬案。这一页把它们列成清单。
其一:P 与 NP。第四章讲过:一个问题「能快速验证」是否意味着「能快速求解」?这是理论计算机科学最深的问题,也是最值钱的问题之一。它与逻辑紧咬:若 P = NP,则所有 ∃SO 能表达的性质都可快速判定(§6.12);若不相等,则存在无法被这类逻辑高效捕获的性质。证明助手与 SMT 求解器的效率上限,也隐隐系于此。
其二:CH 的新公理。§6.10 已经说明,CH 独立于 ZFC,而两派新公理给出相反裁决。争论的焦点是「接受哪种形式的公理才算合法」。这既是技术问题(Ω-猜想是否成立),也是哲学问题(什么样的数学宇宙才算「对」)。据通行说法,短期内难有共识。
其三:AI 能否发现证明。当前的证明助手是「人想证明、机器验收」。下一站是「机器提出猜想、机器寻找证明」——自动定理证明已在有限领域做到(如四色定理的构形检查),但出人意料的、富有数学意义的证明仍是人的领地。大语言模型会写看起来像证明的文字,但要真正可信,还得回到内核逐行核验(§6.15)。
其四:形式化的极限。mathlib 越来越厚,可是数学的大厦比它更大得多。会不会存在「原则上无法形式化」的数学?据通行看法,形式化在原理上没有禁区(一切可以被严格写下的证明都能被机器检查);真正的瓶颈是成本——人力、时间、库的复用度。形式化的下一个百年,可能是「工程极限」而非「逻辑极限」的故事。
怎么面对未竟。面对悬案,本册建议一种姿态:把「不知道答案」与「不知道问题是否可答」分开。CH 已被证明「在 ZFC 内不可答」,这是确凿的知识;P vs NP 至今连「是否独立」都无定论。分清了这一层,就能既尊重未知,又不陷入虚无——这正是逻辑训练出的分寸感。下一章(综合站)将用年表、人物与总图把这些线索收束成一张全景。
例 6.1。用真值表判定公式 (p → q) ∨ (q → p) 是否为重言式。
解。逐个赋值计算蕴涵,列表如下。
| p | q | p → q | q → p | 公式 |
|---|---|---|---|---|
| T | T | T | T | T |
| T | F | F | T | T |
| F | T | T | F | T |
| F | F | T | T | T |
四行公式列全为 T,故它是重言式。更省力的读法:q → p 只在「q 真而 p 假」时假,p → q 只在「p 真而 q 假」时假——这两个坏情形互斥,因此不可能同时为假,析取恒真。∎
例 6.2。用真值表验证「拒取式」:{p → q, ¬q} ⊨ ¬p。
解。要找的是:是否每个使前提全真的赋值都使结论为真。
| p | q | p → q | ¬q | 前提皆真? | ¬p |
|---|---|---|---|---|---|
| T | T | T | F | 否 | F |
| T | F | F | T | 否 | F |
| F | T | T | F | 否 | T |
| F | F | T | T | 是 | T |
唯一使两前提皆真的是第四行,而该行结论 ¬p 也为真。故蕴涵关系成立,拒取式有效。∎
例 6.3。验证德摩根律 ¬(p ∧ q) ↔ (¬p ∨ ¬q)。
解。只需比较两边的真值列。
| p | q | p ∧ q | ¬(p ∧ q) | ¬p ∨ ¬q | ↔ |
|---|---|---|---|---|---|
| T | T | T | F | F | T |
| T | F | F | T | T | T |
| F | T | F | T | T | T |
| F | F | F | T | T | T |
第四列与第五列逐行相同,故等价式恒真。∎
例 6.4。用真值表法求 p → q 的主析取范式。
解。只取使公式为真的行,每行写成一个「合取小项」(该行取 T 的变元用本身、取 F 的用否定,全部相合取),再把它们析取起来。由例 6.1 的中间列,p → q 在「(p,q) = (T,T)、(F,T)、(F,F)」三行为真,于是
(p → q) ≡ (p ∧ q) ∨ (¬p ∧ q) ∨ (¬p ∧ ¬q).
把前三项合并(前两项含 q,后两项含 ¬p)即得 ¬p ∨ q,与蕴涵的定义吻合。主析取范式是「从真值表直接读出」的标准化写法,也是可满足性问题在逻辑程序里的常见表示。∎
复盘:四个例子分别演练了「判重言」「验蕴涵」「验等价」「求标准形」——语义方法的四种基本用途。它们的共同点是:全部答案都能从真值表上读出来,无需任何巧思,这正是「语义可检查」的第一层含义。
例 6.5。用自然演绎证明 p → (q → p)。
解。这是「蕴涵引入」的两次套用,骨架是把假设一步步「收进」蕴涵里。
例 6.6。证明 (p → q) → (¬q → ¬p)。
解。结论的否定 ¬p 是「从 p 推出矛盾」。
例 6.7。用归结法证明 {p → q, q → r} ⊨ p → r。
解。归结法先化为子句集,再把结论取反加入,推出空子句即证。
例 6.8。写出恒等蕴涵 P → P 的 Curry–Howard 对应项,并说明它为何是一个证明。
解。按「命题即类型」,P → P 是函数类型;它的一个项是恒等函数
λx:P. x.
类型检查过程即证明核对:给定 x : P,函数体 x 的类型正是 P,于是 λx:P. x 的类型为 P → P(§6.2)。这个项非空,说明类型 P → P 有 inhabitant——即该命题可证。Coq 里的 exact H(例见 §6.3)本质上就是交出这个恒等项。∎
复盘:前两例是纯自然演绎的「假设—消去」演练,第三例换成归结式的机械推演,第四例把证明翻译成程序。四种方式看着不同,背后是同一条「可检查」的标准——无论用纸笔、用归结器还是用内核,证明了的东西必须能被逐步核对。
习题 6-1(判重言)。判定下列公式是否重言式,说明理由:① (p ∧ q) → (p ∨ q);② (p → q) → p;③ p ∨ ¬p;④ (p ∨ q) → (p ∧ q)。
提示。赋值 p = q = F 一举判掉④(前件假?不,F ∨ F = F 使前件假,蕴涵为真——再换 p = T, q = F:前件真后件假,④假)。答案:① 真(合取弱于析取);② 假(p = F, q = T 时前件真后件假);③ 真(排中律);④ 假(p = T, q = F)。
习题 6-2(标准形)。求 p ↔ q 的主合取范式(先列使公式为假的行)。
提示。p ↔ q 在 (T,F) 与 (F,T) 两行为假。对每一假行写一个「析取大项」(该行取 F 的变元用本身、取 T 的用否定,相析取):(¬p ∨ q) 与 (p ∨ ¬q);二者相合取即主合取范式。要点:主合取范式由「假行」读出,主析取范式由「真行」读出。
习题 6-3(一致性)。判断前提集 {p → q, ¬q ∨ r, ¬r, p} 是否可同时满足;若可,给出一个满足的赋值。
提示。由 ¬r 得 r = F;由 ¬q ∨ r 得 q = F;由 p 得 p = T;但 p → q 要求 q = T——冲突。结论:不可满足(这组前提自相矛盾,等价于归结出空子句 □)。
习题 6-4(完备联结词集)。说明 {¬, ∧} 是「完备」的——只用否定与合取就能表达一切真值函数(提示:先把 ∨ 写成 ¬(¬a ∧ ¬b),再用主析取范式)。
提示。任一 n 元真值函数都能写成真值行对应的「合取小项」的析取(主析取范式,习题 6-2 的对偶);每个合取小项只用 ∧ 与 ¬;而析取 ∨ 可用 ∧ 与 ¬ 模拟(德摩根)。于是 {¬, ∧} 完备。延伸:单靠 NAND(与非)或 NOR(或非)单独一种也能完备——这是数字电路只用一种门搭出一切的原理。
习题 6-5(可满足与推论)。证明:φ ⊨ ψ 当且仅当 φ ∧ ¬ψ 不可满足。
提示。φ ⊨ ψ 的意思是「凡使 φ 为真的赋值都使 ψ 为真」,即「不存在使 φ 真且 ψ 假的赋值」,也就是「φ ∧ ¬ψ 无模型」。这条等价是归结法(反证式自动证明)与 SMT 求解器(§6.13)得以工作的语义原理:把「验证推论」翻译成「判定不可满足」。
习题 6-6(自然演绎)。证明 [p → q] ∧ [q → r] → (p → r)(假言三段论的「陈述式」版本)。
提示。依次引入三个假设:p → q、q → r、p;对 p 用第一个假设得 q,对 q 用第二个得 r;消去 p 得 p → r,再消去前两个假设并用 ∧ 引入收束。要点:每引入一个假设就要在最后「消去」它,否则证明不合法。
习题 6-7(归结)。用归结法证明 {¬p ∨ q, ¬q ∨ r, p, ¬r} 不可满足。
提示。对 p 与 ¬p ∨ q 归结得 q;对 q 与 ¬q ∨ r 归结得 r;对 r 与 ¬r 归结得空子句。要点:归结是「命题 6-5 的机械化版本」——把推论验证翻译成不可满足判定,再纯机械地消去互补文字。
习题 6-8(构造性)。在直觉主义逻辑中,排中律 p ∨ ¬p 不普遍有效。说明「双重否定消去」¬¬p → p 为何也不能在直觉主义中普遍成立(提示:用一个「尚未有构造」的命题想)。
提示。直觉主义要求「A ∨ B 的证明要明确指出是哪一支并给出其证明」。对「尚未被判定」的命题(例如某数论猜想),¬¬p 只说明「p 不可能被否证」,并没有给出 p 的构造,因此推不出 p。要点:经典逻辑多出的正是「不给出构造就断言成立」的权力(BHK 解释,§6.7)。
习题 6-9(一阶满足)。取结构 𝒩 = (ℕ, <, +, 0)。判断句子 ∀x ∃y (x < y) 与 ∃y ∀x (x < y) 在 𝒩 中是否成立。
提示。前者真(任何自然数都有更大的数,如 y = x + 1);后者假(不存在「最大的自然数」)。要点:量词顺序不可交换——∀∃ 与 ∃∀ 的差别,正是「逐点构造」与「一致构造」的差别,这与 §6.7 的构造性精神一脉相承。
习题 6-10(边界·论述)。用三到五句话说明:为什么「ZFC 无法判定 CH」不等于「CH 没有真假」,并指出要「判定 CH」需要付出什么代价。
提示。独立意味着 ZFC 的每条模型都能被安排成使 CH 真或假(Gödel 1938 / Cohen 1963),因此 ZFC 这套公理「看不见」CH 的真假;要给它一个答案,必须添加 ZFC 之外的新公理(§6.10)。代价是:新公理必须自证其合理性(极大性?规范内模型?),而这正是当代集合论尚未解决的哲学辩论。要点:「不可判定」是相对于某套公理系统的相对事实,不是绝对的无意义。
本章从「工具」出发,把逻辑从纸笔搬进机器(§6.1–6.4),再到「新基础」重审数学的地基(§6.5–6.9),最后走向「前沿与交汇」(§6.10–6.17)。下图画出一条主干依赖线:箭头 A → B 表示「读懂 B 需要先掌握 A」。
三条推理线路。① 工具线:类型论 → 证明助手 → mathlib → 里程碑。要理解「机器为何能检查证明」,先要理解「命题即类型」;要理解「库为何能协作共建」,先要理解「内核为何够小」。② 基础线:构造主义 → 逆向数学 → 力迫 → CH 之争。要理解「哪条公理在干活」,先要理解「证明里的构造信息」;要理解「CH 为何要新公理」,先要理解「独立」的含义。③ 交汇线:描述复杂度 → 模型检测 / 数据库 → AI。要理解「逻辑为何进入工业」,先要理解「一阶逻辑能表达什么、不能表达什么」。
与全书其他章的接口。本章的 §6.2(命题即类型)与第三章(证明论)互为表里:切割消除对应程序的化归;§6.7(构造主义)回望第五章(不完备性与一致性)与第二章(完备性定理的构造性版本);§6.9–6.10(力迫与 CH)直接承接第五章末尾的独立性叙事;§6.12(描述复杂度)与第四章(可计算性与复杂度)同源。本章不是另起炉灶,而是把前五章的工具搬到当代的车间里。
本页任务。把本章「语义」一侧的收获浓缩成卡片——即「一个命题在什么世界里取什么值」这一面。
| 语义工具 | 回答的问题 | 出处 |
|---|---|---|
| 真值表 | 命题在每种赋值下真假如何 | 第一章 / §6 例题 |
| 类型 | 证明是一个怎样的项 | §6.2 |
| 布尔值模型 | 公理取什么真值 | §6.9 |
| 有限模型 | 句子能表达哪类性质 | §6.12 |
| 时序模型 | 系统是否满足规格 | §6.13 |
一句话串起语义篇。逻辑的语义一直在扩音:从两值真假,到类型空间,到布尔代数,到有限结构,到时间线上的系统。每一次扩音,都是为了回答一种新的「什么算真」——而每一种「真」,都对应着一个可被机器检验的判定问题。
本页任务。把本章「语法」一侧的收获浓缩成卡片——即「证明与公理如何被构造、被机器执行」这一面。
一句话串起语法篇。语法篇讲的是「证明如何被造出、被标价、被执行」:证明助手把造证明变成写程序,逆向数学给公理标出强度,大基数理论把宇宙的高度排成刻度,机械推理把它们交给机器。与语义篇合起来,本章的完整图景是:逻辑既在说「什么算真」,也在说「怎样把真造出来并让机器认可」。
检验是否读懂的三个小问题:能否写出一个 Curry–Howard 对应的例子?能否说出逆向数学五层塔的名字与顺序?能否解释「模型检测」与「形式化证明」各自适合哪类问题?能答上这三问,本章的主干就算过关。
本章最深的一课,藏在一个不起眼的词里:「如果」。日常语言里,「如果下雨,就带伞」是一种因果、一种建议、一种因果关系下的行动;而在逻辑里,它被锻造成一个算子 →——只要真值表上一栏填得干净,「如果」就和「并且」「或者」一样,是一台可计算的机器。
把这件小事想透,就能看懂本章全部工程奇迹的来源。一旦「如果」成为算子,推理就成了计算。蕴涵有真值表,所以能判重言;蕴涵对应函数类型,所以证明成了程序;蕴涵可以是子句间的消解,所以归结能机械地跑;蕴涵能被写进内核,所以 Lean 的 by 与 Coq 的 Qed 才能逐行复核。四色定理被机器验收、CompCert 编译器被证明正确、数据库查询被形式化为逻辑——这一长串成果,根子上都长在「把日常词变成算子」这一步上。
但算子化也有代价,这正是本章两条支线(构造主义、HoTT)在追问的。把「如果」当成真值算子,就丢掉了它的构造含义:经典逻辑允许「A 或非 A」却不说清是哪一支,允许「非非 A 推出 A」却不给出 A 的证明。直觉主义拒绝这种「不劳而获」;Curry–Howard 则把蕴涵升格为函数类型,让「如果」重新携带构造。同一枚算子,一侧通向可计算,一侧通向可构造——本章的两半正好由它分开。
留下的自问:日常语言里的「如果」,究竟有多少种含义?「如果是医生,就知道怎么处理」是蕴涵吗?「如果我有钱,我就买」是承诺还是条件?数学把它们统统压成一个真值表上的算子,这份「粗暴」是损失,还是数学威力恰恰来自这里?——这一问没有标准答案,但每一次追问,都会让人重新看见形式化的边界与代价。
任务。用一阶逻辑的语言 L = {点, 线, 在…上} 写出一组公理,刻画射影平面的「关联结构」;再改造它,得到仿射平面;最后讨论这套语言说不了什么。这是第二章「三套公理系统」的一次动手复演。
第一步:写公理。射影平面的经典刻画只需三条(符号 P(x) 表「x 是点」、L(x) 表「x 是线」、I(x, y) 表「x 在 y 上」):
这三条逐字译成一阶句子(「恰在一条」要写成「存在一条,且若有另一条则相等」)。注意 P3 是存在句,它排除了「只有一条线」「只有两个点」之类的退化模型。
第二步:找模型。验证 Fano 平面(七个点、七条线,见第一章 §1.6)满足 P1–P3。它是最小的射影平面,阶数 n = 2。再验证更大的例子 PG(2,3)(十三点十三线)也满足。
第三步:改造成仿射平面。在射影平面里删去一条线 ℓ 及其上的点,剩下的结构就是仿射平面:任意两条线要么交于一点,要么平行(即它们在 ℓ 上的交点被删掉了)。出仿射平面的对应公理:A1 两点定一线;A2 过线外一点恰有一条平行线(欧氏平行公设);A3 存在三点不共线。
第四步:找边界(最关键的一步)。试问:能不能用一句话就要求「平面是有限的」?不能——一阶逻辑若有任意大的有限模型,则必有无限模型(紧致性定理,第二章)。所以「存在一个 n 阶射影平面」只能对每个 n 单独写一条公理,无法一网打尽。更进一步:「n 阶射影平面存在」这个命题的真假,对大 n 至今是著名的开放问题——公理写得出,问题答不上,这条落差正是逻辑的分寸感。
进阶(选做)。若把「点」「线」都换成实数向量,用 ℝ3 中的过原点直线作「点」、过原点的平面作「线」,验证射影平面的公理成立——这是实射影平面 ℝP2。再想想:为什么这套「关联结构」无法用一阶逻辑把「球面」与「射影平面」区分开(提示:二者在纯关联语言下不是初等等价的?或反是?动手查找与验证)。
实验目的。用三套彼此独立的「判定机器」——真值表(语义)、DPLL(SAT 求解)、归结(证明论)——对同一批命题公式分别判定,检验它们结论完全一致。这是「形式系统可以被程序执行、且不同形式系统互相印证」的现场演示,脚本见 qa/exp_c6.py。
核心代码(真值表判定与「否定的 CNF」构造)。
# 公式以嵌套元组表示:('v','p') 变量;('~',f);('&',a,b);('|',a,b);('>',a,b)
def ev(f, env):
op = f[0]
if op == 'v': return bool(env[f[1]])
if op == '~': return not ev(f[1], env)
if op == '&': return ev(f[1], env) and ev(f[2], env)
if op == '|': return ev(f[1], env) or ev(f[2], env)
if op == '>': return (not ev(f[1], env)) or ev(f[2], env)
def is_taut(f, vs): # 真值表:全部赋值都真?
return all(ev(f, env) for env in all_assign(vs))
def blocking_cnf(f, vs): # 把「f 恒真」写成 CNF
clauses = []
for env in all_assign(vs):
if not ev(f, env): # 每个使 f 为假的赋值,出一条子句挡住它
clauses.append(frozenset((v, not env[v]) for v in vs))
return clauses
核心代码(DPLL 求解)。
def simplify(clauses, lit): # 代入单文字 lit=(var,val)
var, val = lit
out = []
for c in clauses:
if (var, val) in c: continue # 子句已满足
out.append(frozenset(l for l in c if l != (var, not val)))
return out
def dpll(clauses):
clauses = [set(c) for c in clauses]
while True: # 单元传播
unit = None
for c in clauses:
if len(c) == 0: return False
if len(c) == 1: unit = next(iter(c)); break
if unit is None: break
clauses = [set(c) for c in simplify([frozenset(c) for c in clauses], unit)]
if not clauses: return True
lit = next(iter(next(iter(clauses))))
return dpll(simplify([frozenset(c) for c in clauses], lit)) or \
dpll(simplify([frozenset(c) for c in clauses], (lit[0], not lit[1])))
对拍结果摘要(qa/exp_c6_out.txt)。对七条测试公式(排中律、恒等蕴涵、假言三段论、拒取式、德摩根析取,以及两条故意不是重言式的反例),三套机器结论完全一致:五条重言式的否定被 DPLL 判为 UNSAT、被归结推出空子句 □;两条反例被判为 SAT、归结推不出空子句。归结那一支还逐步打印出假言三段论的消解过程:p 与 ¬p ∨ q 归结得 q,再与 ¬q ∨ r 得 r,最后与 ¬r 得空子句。
实验报告要求。① 贴出脚本运行的三段输出(对拍表、归结演示、反例赋值);② 把测试公式改为自拟的三条(含至少一条非重言式),重跑并解释每一条的一致性;③ 回答:如果把 DPLL 换成「纯字面量消去」这类不完全方法,会出现三种结论不一致吗?为什么这说明「完备性」是求解器的关键指标?(提示:不完全方法可能把 SAT 误判为 UNSAT。)
两套「推理学」的诞生。公元前四世纪,亚里士多德在《前分析篇》里给出了三段论:从两个前提经共同词项推出结论,论证的有效性只取决于形式,与内容无关。几乎同一片时间轴上,中国的《墨子·大取》写下另一句纲领:「夫辞以故生,以理长,以类行者也。」——一句话把论证拆成三件:故(理由)、理(规则)、类(类推)。墨家由此建立了「名、辞、说」的分析框架:名相当于概念,辞相当于判断,说相当于推理。两条传统都发现了「推理要讲形式」这件事,只是着手的入口不同:希腊从「形式即真值保真」入手,把有效论证与事实与否分开;墨辩从「如何把人说服、如何指出对方的错」入手,把类比与举证放在中心。
名家的辩术与「辩」的技艺。与墨家相映的是名家:惠施的「历物十事」、公孙龙的《白马论》《坚白论》,都在拆解「名」与「实」的对应——「白马非马」不是诡辩,而是对「概念外延」的一次精确操作演示。再看佛教因明:六世纪的印度论师陈那(Dignāga)把古因明改造为「三支作法」,用宗(命题)、因(理由)、喻(例证)三段来立论;七世纪玄奘将它译介到中国,弟子窥基撰《因明入正理论疏》加以发挥。三支作法与三段论形似而神不同:它更强调「因」的成立条件(即「因三相」),把论证的可靠性锚定在理由与实例上,而不是纯粹的形式推演。中国与印度这两支传统都发展出了论证的规则,只是没有像希腊那样把「有效形式」单独抽出来公理化。
为什么这一步差别重要。把「有效形式」抽象成公理系统,是整个现代逻辑的起点:只有形式被单独拿出来,才谈得上「完备性」「一致性」「可判定性」这些元数学问题(第二章、第四章、第五章的全部议题)。中国的名辩传统长在语言与论辩的土壤里,长于辨析概念、提出反例、组织说服,却没有走到「把推理规则本身当成数学对象」这一步。这不必被读成「缺失」——它是另一种生长方式:墨辩关心的是「说得对不对、服不服人」,希腊逻辑关心的是「推得动不动、保不保真」。前者更接近今天说的「论证理论」与「非形式逻辑」,后者才是数理逻辑的直系祖先。本册反复用到的「形式化」「可检查」,正是后一种传统的当代形态;而当代逻辑学(§6.16)在中国落地一个世纪后,也早已把这门学问接了过来——传统与传入,在此交汇。
札记的注脚。本册选择把「可检查」当作主线的标准,是站在希腊传统的延长线上说话;但记住另一条线:在不同文明里,「怎样才算讲理」都被认真追问过,且答案各具匠心。数理逻辑的胜利不在于它垄断了「理」,而在于它找到了一种可以被机器执行的写「理」的方式——这或许才是这门学问最独特的贡献。
| 条目 | 内容 | 出处 § |
|---|---|---|
| Automath | de Bruijn,1968 起,首个可用证明检查器 | §6.1 |
| Mizar | Trybulec,1973 起,基于 Tarski–Grothendieck 集合论 | §6.1 |
| Coq / Rocq | 1989,构造演算;四色定理、奇数阶定理的形式化平台 | §6.1 / §6.5 |
| Lean 4 / mathlib | 2013 起(Lean 4:2021 起);依赖类型论;规模化数学库 | §6.1 / §6.4 |
| Isabelle/HOL | Paulson 1986;简单类型论;Isar + Sledgehammer | §6.1 / §6.3 |
| 命题即类型 | Curry–Howard:命题=类型,证明=项,验证=类型检查 | §6.2 |
| 四色定理 | 1976 Appel–Haken;2005 Gonthier–Werner 在 Coq 中形式化 | §6.5 |
| 奇数阶定理 | Feit–Thompson 1963;2012 在 Coq 中形式化 | §6.5 |
| Kepler 猜想 | 1611 提出;Hales 1998 证明;2014 Flyspeck 完成形式化 | §6.5 |
| CompCert / seL4 | 验证过的 C 编译器(Coq)/ 微内核(Isabelle/HOL) | §6.5 |
| 同伦类型论 | 等式即路径;单值公理 (A = B) ≃ (A ≃ B);立方类型论 | §6.6 |
| BHK / 抽取 | 构造性证明可抽取为程序;可实现性(Kleene 1945) | §6.7 |
| 逆向数学五大系统 | RCA0 ⊂ WKL0 ⊂ ACA0 ⊂ ATR0 ⊂ Π11-CA0 | §6.8 |
| 布尔值模型 | Scott–Solovay 1965:力迫=在完备布尔代数上的多值语义 | §6.9 |
| CH 之争 | MM / PFA ⟹ 2ℵ0 = ℵ2;Ultimate L ⟹ 2ℵ0 = ℵ1 | §6.10 |
| 大基数 | 不可达 → Mahlo → 弱紧致 → 可测 → Woodin;可测 ⟹ V ≠ L | §6.11 |
| Fagin 定理 | NP = ∃SO(存在性二阶逻辑) | §6.12 |
| 描述复杂度词典 | FO+P = LFP;FO+TC = NL;SO = PH | §6.12 |
| EF 博弈 | 一阶 k 轮博弈判定量词深度 ≤ k 的可分辨性 | §6.12 |
| 模型检测 | Clarke–Emerson 1981(CTL);Queille–Sifakis 1982;2007 图灵奖 | §6.13 |
| 时序逻辑 | LTL(Pnueli 1977)与 CTL;有界模型检测化为 SAT | §6.13 |
| Codd 定理 | 关系代数 ≡(安全)关系演算 ≡ 一阶逻辑查询 | §6.14 |
| Datalog | 加最小不动点(LFP);与多项式时间判定相关 | §6.14 |
| 描述逻辑 OWL | TBox / ABox;可判定片段(EL、DL-Lite) | §6.15 |
| 归结原理 | Robinson 1965;自动定理证明与 Prolog 的基石 | §6.15 |
| 中国脉络 | 1920 罗素来华;金岳霖、沈有鼎、王宪钧、胡世华;1958 王浩;1977 吴方法 | §6.16 |
符号卡。∃SO 存在性二阶逻辑;LFP 最小不动点;TC 传递闭包;MM Martin 极大公理;PFA 保稳力迫公理;Ω Woodin 的 Ω-逻辑;𝔹 完备布尔代数;V𝔹 布尔值模型。
定理卡(一句话)。① Fagin 1974:NP = ∃SO。② Codd:查询=一阶逻辑(不含递归)。③ 命题即类型:证明=程序。④ 独立即可作两解:CH 真、假各有相容扩张。⑤ 大基数阶梯线性有序,可测基数蕴含 V ≠ L。
易错三坑。① 把「CH 独立」读成「CH 无意义」——独立只是相对 ZFC,添新公理可定其真假(§6.10);② 混淆「模型检测」与「形式化证明」——前者面向有限状态自动判定与找反例,后者面向无限数学的机器核验(§6.5 / §6.13);③ 把「mathlib 转向 HoTT」当真——主流库至今仍建立在经典逻辑与选择公理之上(§6.6)。
下一步。本章收束,全书进入综合站:年表、人物谱、概念总图与自查将把六章的线索编成一张网——那里可以看到,从三段论到今天的内核,这条线索从未断过。
★★ 六章走完,到了清点行囊的时刻。
回望起点。全书从三个各自独立的历史场景出发:亚里士多德在《前分析篇》里写下第一套推理规则——三段论;莱布尼茨设想一台「推理演算机」,让争论的双方只需说「让我们算一算」;希尔伯特在二十世纪初提出纲领,要把全部数学变成一场可以机械检查的符号游戏。三个场景分属三个世纪,却在同一副骨架上相遇:一族符号、一组变形规则、一个「这个证明合法吗」的判定动作。数理逻辑研究的正是这副骨架——把推理写成符号,再问符号能推出什么、推不出什么、有没有机器能替我们判断。
六章的一句话。第一章把真假摊成一张表:命题逻辑的全部内容都落在真值表的有限行里,重言式即永真行。第二章升到一阶逻辑:加进量词与结构,「满足」与「可证」成为两个不同层次的动词,哥德尔的完备性定理在它们之间架起第一座桥。第三章把证明本身当成研究对象:相继式、自然演绎与切割消除让「证明的形状」可被谈论,证明于是变成程序。第四章回答「什么能机械地算」:图灵机给出可计算的标准模型,停机问题宣告了不可判定的边界。第五章完整走出哥德尔的两条定理,并在此交代连续统假设为何被判「独立」。第六章走向当代:证明助手、同伦类型论、逆向数学与人工智能中的逻辑。
三条线索。其一明线——从三段论到可运行的证明:先写符号(绪论),再把真假变成真值表(第一章),升到一阶逻辑并证明完备性(第二章),让证明成为对象(第三章),回答机器能算什么(第四章),走到可证性的边界(第五章),最后看见数学在计算机里被逐行验证(第六章)。其二暗线——每一次「显然」都要过形式化的关:切割消除要求证明可被机械检查;第二不完备定理说系统证不了自己的清白;五种几何的模型证明「同一套公理」远非显然。其三接口——数理逻辑是数学与计算的共同语法,与集合论、模型论、计算理论、数学基础四条战线相通。
综合站的十四个站点。接下来不再引入新理论,只做三件事:清点(年表、人物谱、观念史、概念总图、方法决策树);检验(两个用程序完成的综合实验、一道终极挑战、一份综合卷子与评讲);回望(全书小结上、下两页与一页终极速查表)。读法随人:只想抓纲的,读两张地图与两页小结;想动手的,直接进实验与挑战;想留作工具书的,收好最后一页速查表。
★★ 把一百八十年压进一张表。
下表按年代列出全书涉及的关键节点,末列标明在本册何处出现。读年表有一个要点:看的是「问题」与「答案」之间的时差。逻辑史最迷人的地方不是某一条定理,而是从「提问」到「作答」之间隔着多少年、由谁接棒。
| 年代 | 事件 | 本书位置 |
|---|---|---|
| 1847 | 布尔发表《逻辑的数学分析》,把命题运算写成代数——逻辑第一次拥有算式 | 绪论 · 第一章 |
| 1879 | 弗雷格《概念文字》引入量词与谓词,语言发生「符号转向」 | 绪论 · 第二章 |
| 1889 | 皮亚诺给出算术公理,自然数被写成可以逐条检查的句子 | 第二章 |
| 1900 | 希尔伯特在巴黎提出二十三个问题,第二问直指算术的一致性 | 绪论 · 第五章 |
| 1901 | 罗素发现集合论悖论,朴素集合论的字面理解宣告破产 | 绪论 · 第五章 |
| 1910–13 | 罗素与怀特海《数学原理》出版,试图把全部数学纳入一套形式系统 | 绪论 |
| 1928 | 希尔伯特与阿克曼提出判定问题:是否存在算法判定任一命题的可证性 | 绪论 · 第四章 |
| 1929 | 哥德尔证明一阶逻辑的完备性定理(博士论文) | 第二章 |
| 1931 | 哥德尔发表两条不完备定理:足够强的系统既不完全,也证不了自身一致性 | 第五章 |
| 1934 | 根岑给出相继式演算与切割消除,证明的形状成为研究对象 | 第三章 |
| 1936 | 图灵提出图灵机,丘奇提出 λ 演算,停机问题被判不可判定 | 第四章 |
| 1938–40 | 哥德尔构造可构成宇宙 L,证明选择公理与连续统假设的相对一致性 | 第五章 |
| 1963 | 科恩发明力迫法,证明连续统假设独立于公理系统 | 第五章 |
| 1965 | 罗宾逊提出归结原理,一阶逻辑的自动证明有了统一的机械格式 | 第二章 · 第三章 |
| 1968 | 德布鲁因启动 Automath,第一套「让机器逐行核对证明」的工程 | 第六章 · 综合站 |
| 1971 | 库克定理问世:可满足性问题是一类最难问题的起点,复杂度理论登场 | 第六章 |
| 1972 | 马丁-洛夫提出构造主义类型论,命题与类型开始合流 | 第三章 · 第六章 |
| 1989 | Coq 证明助手诞生,基于归纳构造演算,证明即程序首次工程化 | 第六章 |
| 2005 | 贡蒂耶用 Coq 完成四色定理的完整形式化,机器证明走向成熟 | 第六章 |
| 2006 | 沃埃沃茨基等人提出同伦类型论与单一性基础,类型论接通拓扑 | 第六章 |
| 2013 | Lean 与 Mathlib 发布,形式化数学进入规模化协作时代 | 第六章 |
| 2014 | 开普勒猜想在 HOL Light 与 Isabelle 中完成形式化(Flyspeck 工程) | 第六章 |
| 2026 | 大型数学库与人工智能辅助证明并进,逻辑从「辩论术」长成「工程学」 | 综合站 |
三处最长的时差。其一,判定问题:1928 年由希尔伯特与阿克曼明确提出「是否存在算法判定任一命题」,1936 年由图灵与丘奇给出否定答复,时差仅 8 年,却终结了希尔伯特纲领最乐观的一支。其二,连续统假设:1900 年作为希尔伯特第一问提出,1938 年哥德尔给出相对一致(不可反驳),1963 年科恩给出相对独立(不可证明),前后 63 年才判为「独立于公理」。其三,从莱布尼茨的推理演算之梦到能实际跑起来的自动化证明,从十七世纪到 1965 年的归结原理,跨了近三百年。一门学问的成熟度,常常可以用「问题与答案的时差」来度量。
三处最密的爆发。其一,1929–1936:完备性(1929)、不完备(1931)、切割消除(1934)、图灵机与不可判定(1936)——七年间现代逻辑的全部主干定理接连落地。其二,1963–1972:力迫法、归结原理、Automath、库克定理、构造类型论——独立性问题与机器化两线同时开工。其三,2005–2014:四色定理的形式化、同伦类型论、Lean 与 Mathlib、Flyspeck——形式化数学从示范走向规模工程。
一行注脚。年表里的名字分处英国、德国、奥地利、波兰、瑞典、俄国与美国,身份横跨数学家、哲学家、逻辑学家与计算机工程师。逻辑的诞生地不属于任何单一学科,它更像一个十字路口:谁路过,谁就留下一条路。
★★ 一门学问的脸。
把全书出现过的十二位主角排成一张表,列国籍与主要贡献。这里不追求生卒详备,只列「做了什么」与「在本书何处相见」。
| 序 | 人物 | 国籍 | 主要贡献 | 位置 |
|---|---|---|---|---|
| 一 | 布尔 Boole | 英国 | 把逻辑写成代数,命题运算获得算式(1847) | 绪论 · 第一章 |
| 二 | 弗雷格 Frege | 德国 | 《概念文字》引入量词与谓词,语言转向的起点(1879) | 绪论 · 第二章 |
| 三 | 希尔伯特 Hilbert | 德国 | 形式主义纲领、二十三个问题、判定问题 | 绪论 · 第五、六章 |
| 四 | 罗素 Russell | 英国 | 罗素悖论(1901);与怀特海合著《数学原理》 | 绪论 · 第五章 |
| 五 | 塔斯基 Tarski | 波兰 / 美国 | 真概念的严格定义、模型论;初等欧氏几何的判定 | 第二、三章 |
| 六 | 哥德尔 Gödel | 奥地利 / 美国 | 完备性定理(1929)、两条不完备定理(1931)、可构成宇宙 L(1938) | 第二、五章 |
| 七 | 根岑 Gentzen | 德国 | 相继式演算与切割消除(1934),算术一致性的构造性证明 | 第三章 |
| 八 | 图灵 Turing | 英国 | 图灵机、停机问题的不可判定(1936) | 第四章 |
| 九 | 丘奇 Church | 美国 | λ 演算;与图灵共同界定可计算 | 第四章 |
| 十 | 科恩 Cohen | 美国 | 力迫法,证明连续统假设独立(1963) | 第五章 |
| 十一 | 马丁-洛夫 Martin-Löf | 瑞典 | 构造主义类型论(1972),命题即类型 | 第三、六章 |
| 十二 | 沃埃沃茨基 Voevodsky | 俄国 / 美国 | 同伦类型论与单一性基础(2006) | 第六章 |
三张面孔。把十二人再压缩,会看到三类人:奠基者——布尔与弗雷格,他们贡献的是语言,让「推理」第一次有了可写的符号;破界者——哥德尔、图灵、丘奇、科恩,他们贡献的是边界,用定理划出「能证」与「不能证」「能算」与「不能算」的分界线;建造者——根岑、塔斯基、马丁-洛夫、沃埃沃茨基,他们把逻辑的成果改装成可以运行的机器与可以扩展的基础。一门学问的成长史大体就是这三类人接力:先有可写的语言,再有可知的边界,最后有可用的机器。
两处错位。其一是命名权:把逻辑写成代数的工作以布尔命名(布尔代数),但「把命题当成可运算对象」这一构想,弗雷格在量词层面推得更远、也更彻底,却因《概念文字》的记号艰涩而长期被忽视。其二是名声:哥德尔的完备性定理(1929)常被两条不完备定理(1931)的盛名掩盖,其实前者才是「逻辑学作为一门完备学科」的定音之锤——没有完备性,一阶逻辑不会成为今天所有形式化的公共底座。
一条时间线之外的观察。从布尔到沃埃沃茨基是一百五十九年。这张人名表里最动人的一处接力发生在 1929 与 1931 之间:同一个人、相隔两年,先证明「一阶逻辑要什么有什么」(完备性),再证明「足够强的系统要什么没什么」(不完备)。一座桥与一道墙由同一双手砌成——这不是矛盾,而是逻辑最深的对称。
★★ 同一件东西,三个文明各造了一半。
希腊:把推理写成形式。亚里士多德在《前分析篇》里第一次把推理从内容里剥离出来,只看形式。全称肯定的「三段论」——大前提「所有人都会死」、小前提「苏格拉底是人」、结论「苏格拉底会死」——之所以有效,与「人」「死」「苏格拉底」具体是什么无关,只与词项之间的包含关系有关。这是人类第一次意识到:有效性是一种形式性质,而不是内容性质。此后两千年,三段论一直是欧洲逻辑的骨架,直到弗雷格用「概念文字」把它替换成更细的量词语言。
中国:把名实与同异讲透。与希腊大致同时,中国也有一场围绕「辩」的思想运动。《墨子》中的《经上》《经下》《经说》《大取》《小取》六篇(约成于战国,是墨家后学的作品)讨论的核心正是「辩」:如何判断是非、审定名实、分辨同异。其中「故」「理」「类」三个字被反复琢磨——「故」是推理的根据,「理」是推理的道理,「类」是推理可以迁移的范围。这与三段论所关心的「词项包含」是同一件事的两副说法,只是墨家更强调「类」的推演与「故」的追溯。《小取》列出「效」「辟」「侔」「援」「推」五种推论方式,其中「效」近于演绎,「推」近于类比与归纳,是现代最容易与西方逻辑对号入座的一段。
公孙龙:把概念关系逼到极致。名家的另一位主角公孙龙,以「白马非马」「离坚白」名世。「白马非马」并非诡辩的顽童游戏,而是一道关于概念外延与内涵的严格追问:若「白」与「马」各有所指,「白马」是一个复合的名,那么它与单名「马」是否同一?这个问题在西方要等到中世纪唯名论与唯实论之争卷土重来,在现代则被类型与集合的区分重新拾起。公孙龙把「名与实」的关系逼到近乎形式的边缘,只是他没有把它抽成一套普遍有效的推理规则。
印度:因明与三支做法。与希腊、中国并称的是印度因明学。陈那(约五至六世纪)把推论整理成「宗」「因」「喻」三支:宗是要立的主张,因是理由,喻是例证;并提出「因三相」——理由必须遍及所立法、必须在同类中有、必须在异类中无。玄奘七世纪将因明传入中国,译出《因明入正理论》。三支做法与西方三段论形似而神异,它更接近今天所说的「论证的可靠性检验」,把「例子」当成推论合法性的证人。
一处必须讲清的差异。中国有发达的「辩」与「名实」之学,却没有像亚里士多德《工具论》那样,把推理形式抽离内容、写成一套可传授的规则系统。墨家已经走到「类」与「故」的门口,公孙龙已经摸到概念关系的门框,但因明、名辩都更关心「这一次论证对不对」,而较少追问「所有这一类论证凭什么总对」。现代逻辑的诞生,靠的正是后一个追问——把「这一次」升成「这一类」,把「对不对」变成「合不合规则」。这不是高下之分,而是侧重点的分岔:一个传统把力气花在算法的构造与事实的辨析上,另一个传统把力气花在公理的演绎上。
与本册的接口。本册的写法自觉地把两种传统拧成一股绳:凡是「账」都要算清楚(承中国传统的算法精神),凡是「理」都要能证明(承希腊传统的演绎精神)。第一章的真值表是一张诚实的事实表——它把中国传统「明同异、察名实」的工夫落在了具体的真假上;第二章的完备性定理则是一次彻底的演绎承诺——它保证语言能推出的东西与事实允许的东西一致。把两种精神合在一处,才是「逻辑」这两个字完整的分量。
★★★ 一张图收下全书。
下图把绪论、六章与综合站串成一条主干,每个节点标出该章的入口与出口。主干的走向就是本书的叙述顺序;节点中的「出口」是这一章交给下一章的货。左侧标注语义、语法、计算三条腿的归属,右侧标注跨章的两座桥。
关于这张图的读法。其一,三列不是三等分:第一章居左,是语义的地盘——真值表把「真假」变成可以逐行算完的有限表;第三章居右,是语法的地盘——相继式把「可证」变成可以逐行搭起的树;第四、五、六章居中下移,是计算的地盘——图灵机把「可算」变成可以逐格走完的纸带。其二,每个出口都是下一章的入口:第一章交出「可穷举的语义」,第二章用它谈结构与满足;第二章交出「可靠且完备」,第三章才能放心地把证明本身当成对象;第三章交出「证明即程序」,第四章才有资格谈计算;第四、五章交出「可算与可证的边界」,第六章才有机器证明的舞台。其三,综合站是收口的结:它不再输出新概念,只把前面七站的货物重新编号。
三条腿的名称。语义(第一章的核心动作是「算真假」)、语法(第三章的核心动作是「搭证明」)、计算(第四章的核心动作是「跑机器」)。三条腿各自都有「能」与「不能」:语义上,一阶逻辑没有一般的「有限表」可算;语法上,切割消除说证明可以平凡化,但代价是长度可能爆炸;计算上,绝大多数判定问题没有算法。三条腿合起来,才是数理逻辑完整的身量。
两座桥的承重点。完备性那座桥,承重点是「满足」与「可证」两个动词被证明等价——凡是语义上到处为真的句子,语法上就能被推出;这是把一个无穷的语义检查压缩成有限的符号操作的地方。切割消除那座桥,承重点是「证明的形状可以规范化」——任何证明都可以改写成一条不使用切割规则的证明,于是「证明」与「程序」通过柯里-霍华德对应互为翻译。桥的价值不在风景,而在它让两岸的工具可以互相搬运。
为什么值得画这张图。逻辑的难点从来不在单条定理,而在定理之间的关系:什么时候该用真值表、什么时候必须上升到结构、什么时候应当把证明本身当对象。这张图就是一张「工具箱地图」——遇到新问题时,先在图里找到位置,再决定动哪把工具。下一页的方法决策树,正是把这张图翻译成一套可执行的选型流程。
★★★ 面对一个待证或待判的句子,先动哪把工具?
六章下来,工具箱里摆着六件家伙:真值表(第一章)、范式与归结(第一、二章)、相继式与切割消除(第三章)、图灵机与不可判定(第四章)、力迫与内模型(第五章)、证明助手与类型检查(第六章)。真正动手时,难题不是「会不会用」,而是「先用哪一个」。下面把选型流程钉死。
第一个要点:先分层,再动手。初学者最常见的错是拿真值表去算带量词的句子,或者拿归结去证一条关于公理系统的独立性命题。正确的顺序是先问:这个句子属于哪一层?命题层最有福气——真值表把一切不确定摊成有限行,逐行算完即可。升到量词层,福气就没了:论域可能是无穷的,真值表不存在,只能靠语法侧的工具去搜证明。再升到「关于系统自身」的元层,问题变成「这句话能不能被公理推出、能不能被公理反驳」,此时真值表与归结都使不上劲,要动的是内模型与力迫。
第二个要点:命题层的三件工具各有脾气。真值表最诚实,但受变元数惩罚——n 个变元要算 2n 行,二十个变元就是上百万行,人手写不动。归结聪明得多,它只在子句之间做消去,能自动发现矛盾;但它只回答「是否不可满足」,对于「是否重言」要先取否定再判,而且最坏情况下它要枚举的组合一样爆炸。范式最适合「看清一个公式长什么样」——想比较两个公式是否等价、想数一个公式的成真行,主范式是最直接的处方。三件工具的选择标准只有一条:是要一个「是或否」的答案,还是要一张「看清楚」的图。
第三个要点:量词层必须接受「不完备的算法」。丘奇-图灵定理告诉我们,一阶逻辑的可证性没有算法能在有限步内对任一命题给出是或否。凡声称「自动证明一阶命题」的程序,本质上做的都是半判定:若命题可证,它会停并给出证明;若命题不可证,它可能永远跑下去。这不是工程缺陷,而是逻辑本身的边界。但边界内仍有绿洲:实闭域理论(塔斯基)、Presburger 算术、初等欧氏几何都是可判定的——把问题限制在这些片段里,机器就能给出确定的答复。
第四个要点:两类问题要另高明。第一类是「这个句子与公理系统独立吗」。真值表与归结问的都是「在某组公理下是否为真」,独立性问的却是「公理管不着它」——Gödel 的可构成宇宙 L 给出「推不出否定」(相对一致),Cohen 的力迫给出「推不出肯定」(相对独立),两者合起来才是「独立」。第二类是「我要机器替我把关」。证明助手不是自动证明器,而是证明检查器:人给出证明,机器用一个小内核逐行类型检查;小内核本身可被人工复核,这正是形式化数学可信的根基。该人做的推理交给人,该机器做的核对交给机器——这是分工,不是替代。
| 情形 | 首选工具 | 它能保证 | 它的边界 |
|---|---|---|---|
| 命题逻辑判定 | 真值表 / 主范式 | 完全判定,一个不漏 | 变元数一多,行数指数爆炸 |
| 子句集不可满足性 | 归结原理 | 导出空子句即不可满足(可靠且完备) | 只搜不判,可能无休止 |
| 一阶命题的可证性 | 归结 / 表列法(半判定) | 可证则必停机给出证明 | 不可证时不保证停机 |
| 可判定片段 | 量词消去(实闭域、Presburger) | 给出确定答复与算法 | 只对特定理论成立 |
| 证明的结构与规范形 | 相继式 + 切割消除 | 每个证明可化为无切割证明 | 无切割证明可能极长 |
| 公理间的独立性 | 内模型 L + 力迫 | 分别给出相对一致与相对独立 | 技术门槛高,模型构造繁复 |
| 大规模形式化核验 | 证明助手(Coq / Lean / Isabelle) | 小内核类型检查,逐行可信 | 人不给证明,机器不会凭空造 |
一句话。决策树的形状就是本书的形状:上端是表(第一章),中段是树与刀(第二、三章),下端是机器与边界(第四至六章)。遇到陌生问题时,从上往下走一遍,不必慌张。
★★★★ 把第一章、第二章、第五章的三件核心装置放进同一段程序。
实验目的。这一页让机器把三件事各做一遍:真值表穷举——把「重言式」变成一次全表扫描;归结证明器——把「推出」变成消去直到空子句;哥德尔编码——把公式变成数、再从数翻译回公式。三段程序都不依赖任何第三方库,全部可运行于任何 Python 3 环境。它们合起来,正好是本书从语义(真值表)、语法(归结)到编码(哥德尔)的一条纵切面。
第一段:真值表穷举。公式用嵌套元组写成语法树,遍历全部赋值,逐行求真值。
from itertools import product
def ev(f, env):
op = f[0]
if op == 'var': return env[f[1]]
if op == 'not': return not ev(f[1], env)
if op == 'and': return ev(f[1], env) and ev(f[2], env)
if op == 'or': return ev(f[1], env) or ev(f[2], env)
if op == 'imp': return (not ev(f[1], env)) or ev(f[2], env)
if op == 'iff': return ev(f[1], env) == ev(f[2], env)
def vars_of(f):
if f[0] == 'var': return {f[1]}
if f[0] == 'not': return vars_of(f[1])
return vars_of(f[1]) | vars_of(f[2])
def is_taut(f):
vs = sorted(vars_of(f))
for bits in product([False, True], repeat=len(vs)):
if not ev(f, dict(zip(vs, bits))):
return False # 抓到一行假,当场否决
return True
V = lambda n: ('var', n)
IMP = lambda a, b: ('imp', a, b)
AND = lambda a, b: ('and', a, b)
# 假言三段论 (p→q)∧(q→r) → (p→r)
F1 = IMP(AND(IMP(V('p'), V('q')), IMP(V('q'), V('r'))), IMP(V('p'), V('r')))
print('假言三段论是重言式?', is_taut(F1))
第二段:归结证明器。子句是文字的集合;归结就是找一对互补文字做消去,直到导出空子句。
def resolve(c1, c2):
for lit in c1:
opp = (lit[0], not lit[1])
if opp in c2:
return (c1 - {lit}) | (c2 - {opp})
return None
def refute(clauses):
pool, steps = list(clauses), 0
while True:
new = []
for i in range(len(pool)):
for j in range(i + 1, len(pool)):
r = resolve(pool[i], pool[j])
if r is None:
continue
steps += 1
if not r: # 空子句 ⇒ 反证完成
return True, steps
if r not in pool and r not in new:
new.append(r)
if not new:
return False, steps # 再也消不出新子句 ⇒ 可满足
pool += new
P, Q, R = ('p', True), ('q', True), ('r', True)
nP, nQ, nR = ('p', False), ('q', False), ('r', False)
# 证 r:前提 {p∨q, ¬p∨r, ¬q∨r},加结论的否定 ¬r
prem = [frozenset({P, Q}), frozenset({nP, R}), frozenset({nQ, R})]
print('{p∨q, ¬p∨r, ¬q∨r} ⊢ r ?', refute(prem + [frozenset({nR})]))
第三段:哥德尔编码。给每个符号编一个号,第 i 个符号用第 i 个素数的相应次幂表示;序列的码就是这些素幂的乘积。解码靠素数分解的唯一性。
def primes(n):
ps, x = [], 2
while len(ps) < n:
if all(x % p for p in ps):
ps.append(x)
x += 1
return ps
SYMBOLS = ['¬','∧','∨','→','↔','(',')','∀','∃','=',
'+','·','0','1','p','q','r','x','y','t']
IDX = {s: i + 1 for i, s in enumerate(SYMBOLS)} # 符号编号从 1 起
def godel(seq):
ps, g = primes(len(seq)), 1
for i, s in enumerate(seq):
g *= ps[i] ** IDX[s]
return g
def decode(g, n):
ps, out = primes(n), []
for i in range(n):
p, e = ps[i], 0
while g % p == 0:
g //= p; e += 1
out.append(SYMBOLS[e - 1])
return ''.join(out), g
code = godel(list('(p→q)'))
print('(p→q) 的哥德尔数 =', code)
print('还原回来 =', decode(code, 5))
真跑输出(qa/exp_big1_out.txt)。
=== 一、真值表穷举 ===
公式:假言三段论 (p→q)∧(q→r) → (p→r)
变量 ['p', 'q', 'r'] | 总行数 8 | 成真行 8 | 重言式? True
公式:德摩根律 ¬(p∧q) ↔ (¬p∨¬q)
变量 ['p', 'q'] | 总行数 4 | 成真行 4 | 重言式? True
公式:逆否律 (p→q) ↔ (¬q→¬p) 重言式? True
公式:(p→q)→(q→p) 重言式? False | 反例行数 1
=== 二、归结证明器 ===
前提 {p∨q, ¬p∨r, ¬q∨r} ⊢ r ? True (归结步数 29 )
可满足集 {p∨q, ¬p∨q, p∨¬q} 导出空子句? False (归结步数 12 )
不可满足集 {p∨q, ¬p∨q, ¬q} 导出空子句? True (归结步数 9 )
=== 三、哥德尔编码 ===
「(p→q)」 长度 5 → 码 371703155919887992966432931880000 → 还原「(p→q)」 余数 1 一致? True
「∀x(p→q)」 长度 7 → 归元成功 一致? True
「¬(p∧q)」 长度 6 → 归元成功 一致? True
素数列前 6 个: [2, 3, 5, 7, 11, 13]
读结果。其一,真值表的「小」是它的力量,也是它的边界:三个变元八行就穷尽了一切可能,假言三段论八行全真、逆否律全真,而「肯定后件」(p → q) → (q → p) 只抓到一行反例(p 假、q 真)就被否决——这正是一张反例表的全部威力。其二,归结是一台「反证机」:它不是直接证 r,而是把 ¬r 塞进前提,看能否消出空子句。前提可满足时它消不出空子句,程序如实报告 False——「没导出空子句」与「导出空子句」是两个方向的答案,程序不偏袒任何一边。其三,哥德尔编码是一一对应的翻译:「(p → q)」 五个符号被翻成一个约 3.7 × 1032 的整数,再用素数分解唯一地还原回来,余数恰为 1。编码的深层含义是:关于公式的每一句话,都可以改写成关于数字的一句话——这正是让系统「谈论自己」的机关。
实验报告要求。① 贴出三段程序的完整输出;② 回答:把「肯定后件」改写成子句集后交给归结程序,它会导出空子句吗?(不会——它是可满足的,故不可满足性判定返回 False,这正是「非重言式」的语法侧对偶。)③ 回答:若把符号编号表里的 → 与 ∧ 对调,「(p → q)」 的哥德尔数会变成多少?(换表即换码,但「可还原」这一性质不变。)
★★★★ 同一批公理,换成不同的模型,三角和就变了脸。
实验目的。第二章反复强调「公理与模型是两回事」。这个实验把它做成一次数值对拍:欧氏、球面、罗氏三种度量几何各取一个三角形,算出三角和、角盈与角亏,看它们如何分别等于零、为正、为负;仿射与射影两种不含度量的一般几何,则改拍「点线关联账」——角度在这两种几何里不是不变量,能对拍的是点与线的计数与相交规律。五段程序合起来,说明同一个词「几何」在不同公理系统下究竟分岔成哪几支。
第一段:三种度量几何的三角和。欧氏用向量夹角公式;球面用单位球上两条大圆弧的切向夹角;罗氏用双曲余弦定律由边长反求角度。
import math
def euclid_angle(P, Q, R): # 顶点 P 处的欧氏夹角
ux, uy = Q[0]-P[0], Q[1]-P[1]
vx, vy = R[0]-P[0], R[1]-P[1]
return abs(math.atan2(ux*vy - uy*vx, ux*vx + uy*vy))
def hype_angle(a, b, c): # 双曲三角形:a 边所对的角
num = math.cosh(b) * math.cosh(c) - math.cosh(a)
den = math.sinh(b) * math.sinh(c)
return math.acos(max(-1.0, min(1.0, num / den)))
E = [(0.0, 0.0), (4.0, 0.0), (0.0, 3.0)]
sE = sum(euclid_angle(E[i], E[(i+1)%3], E[(i+2)%3]) for i in range(3))
print('欧氏直角三角形的三角和 =', sE, '(= π)')
s = 1.0
A = hype_angle(s, s, s) # 罗氏等边三角形,边长 1
print('罗氏:单角 =', A, ' 三角和 =', 3*A, ' 角亏 =', math.pi - 3*A)
第二段:球面三角形的角盈。取单位球上三条互相垂直的半径端点,得八分之一球面三角形。球面角的定义是两条大圆弧在顶点处的切方向夹角。
def sph_angle(A, B, C): # 单位球上顶点 A 处的球面角
dot = lambda u, v: sum(u[i]*v[i] for i in range(3))
sub = lambda u, v: [u[i]-v[i] for i in range(3)]
norm = lambda v: [x / math.sqrt(dot(v, v)) for x in v]
def tangent(B): # 把 A→B 投影到 A 的切平面
t = sub(B, A)
return norm(sub(t, [dot(t, A)*A[i] for i in range(3)]))
c = max(-1.0, min(1.0, dot(tangent(B), tangent(C))))
return math.acos(c)
S = [(1.0,0.0,0.0), (0.0,1.0,0.0), (0.0,0.0,1.0)]
sS = sum(sph_angle(S[i], S[(i+1)%3], S[(i+2)%3]) for i in range(3))
print('球面三角形三角和 =', sS, ' 角盈 =', sS - math.pi)
第三段:有限模型的关联账。仿射平面 AG(2,3) 有九个点、十二条线;射影平面 PG(2,3) 补上无穷远元素后,点线账变成十三与十三。
from itertools import combinations
def ag2(q): # 仿射平面:点 (x,y),线 y=mx+b 与 x=c
pts = [(x, y) for x in range(q) for y in range(q)]
lines = [frozenset((x, (m*x + b) % q) for x in range(q))
for m in range(q) for b in range(q)]
lines += [frozenset((c, y) for y in range(q)) for c in range(q)]
return pts, list(dict.fromkeys(lines))
pts, lines = ag2(3)
parallel = {sum(1 for L2 in lines if L2 != L1 and not (L1 & L2)) for L1 in lines}
meet = {}
for L1, L2 in combinations(lines, 2):
meet[len(L1 & L2)] = meet.get(len(L1 & L2), 0) + 1
print('AG(2,3): 点数', len(pts), '线数', len(lines))
print(' 每条线的平行线数 =', sorted(parallel), ' 两线交点数分布 =', dict(sorted(meet.items())))
真跑输出(qa/exp_big2_out.txt,节选)。
欧氏直角三角形 (0,0)(4,0)(0,3):三角和 = 3.1415926536 = 1.000000π
角盈/角亏 = 三角和 − π = 0.000e+00(数值零)
单位球面三角形(三正交):三角和 = 4.7123889804 = 1.500000π
角盈 = 1.5707963268;球面面积(八分之一单位球)= 1.5707963268;差 0.00e+00
罗氏等边三角形(边长 s=1):单角 = 0.918798 rad = 52.6432°,三角和 = 2.7563936165
角亏 = π − 三角和 = 0.3851990371;双曲面积(单位曲率)= 0.3851990371;差 0.00e+00
AG(2,3):点数 = 9,线数 = 12
每线点数(应恒为 q=3): [3]
过每点的线数(应恒为 q+1=4): [4]
两线交点数分布(仿射:或 0 或 1): {0: 12, 1: 54}
PG(2,3):点数 = 13,线数 = 13(应为 q2+q+1 = 13)
两线交点数分布(射影:恒为 1): {1: 78}
读结果。其一,同一条「三角形」这条公理,落在不同模型里长出不同的账:欧氏三角和恰好 π,球面三角和 1.5π、角盈 π⁄2 正好等于球面三角形的面积(高斯-博内:曲率 1 时角盈即面积),罗氏三角和 2.756、角亏 0.385 正好等于双曲面积(曲率 −1 时角亏即面积)。一个符号之差,把「三角和内角和」这条看似天经地义的直觉拆成了三种。其二,三处数值都对得上有限位数:欧氏的残差是 0.00 × 100,球面角盈与八分之一球面积的差也是零,罗氏角亏与双曲面积一字不差。这不是巧合,而是三条几何各自的内定理在数值上的兑现。其三,仿射与射影的账目差一个「无穷远」:AG(2,3) 里十二条线中有十二对相交于零个点(平行),射影平面补上无穷远点后,十三条线两两恰好交一点(78 对全中)——这正是第二章「射影平面把平行线也接上交点」那句话的数值证据。
实验报告要求。① 贴出五段程序的完整输出;② 回答:把罗氏等边三角形的边长从 1 改到 2,单角与角亏各变向哪边?(边长变大,角变小、角亏变大——向着「更弯」的一端去。)③ 回答:把 AG(2,3) 的 q 换成 4 与 5,点数、线数与每条线的平行线数分别是多少?(q2 点、q(q+1) 线、q−1 条平行线。)
★★★★★ 亲手造一个小系统,再亲手检查它不说假话。
目标。本书讲了六个系统——命题逻辑、一阶逻辑、相继式演算、图灵机、算术、类型论,一直是「使用者」。这道挑战把角色调过来:从零造一个形式系统,然后证明它健全(不说假话)。系统可以极小,但五脏必须齐全:一个语言、一组公理、一条推理规则、一个语义,以及一道「可证者皆真」的自检。
分步引导。
验收标准。① 写清语言、公理模式、规则、语义四件套;② 给出健全性证明的两半,并至少手工验证 K 与 S 在一个具体实例上是重言式;③ 给出一个「本系统内可证」的公式及其证明序列(例如 (p → p),它由 K、S 与两次 MP 导出);④ 讨论:若把公理 N 抽掉,系统还健全吗?还完备吗?
为什么值得做。这道挑战把全书的三条腿一次走遍:语言与规则(语法)、赋值与重言式(语义)、「可证者皆真」与「真者可证」(两座桥)。做完之后,「形式系统」四个字就不再抽象——它不过是这样一套有骨头、有血肉、还能自我体检的小机器。能亲手造一台并检查它不说谎,才算真正读懂了本书第一章到第五章之间的那条主线。
★★★★ 一份把六章混在一起的卷子。
本卷分三组:A 组真假与证明(第一、二、三章的工具)、B 组计算与边界(第四、五章的工具)、C 组模型与基础(第二、五、六章的工具)。每题只署主要涉及的章节,允许跨章取用工具;答案与要点见下一页评讲。
A 组 · 真假与证明。
综合 13-1(真值与范式)。判断公式 (p → q) ∨ (q → p) 是否重言式;再把 ¬(p → q) 化成合取范式。
提示。第一问:唯一可能的反例是 p 真 q 假,代进去看两个析取支是否至少一支为真。第二问:¬(p → q) 等价于 p ∧ ¬q,它本身就是一个合取式。
综合 13-2(归结证明)。用归结原理证明:前提 {p ∨ q ∨ r, ¬p ∨ s, ¬q ∨ s, ¬r ∨ s} 能推出 s。
提示。把 ¬s 加入子句集,让 (p ∨ q ∨ r) 分别与 ¬p ∨ s、¬q ∨ s、¬r ∨ s 归结,逐条消去 p, q, r,最后与 ¬s 归结出空子句。
综合 13-3(可靠与完备)。陈述可靠性定理与完备性定理,并说明两者方向相反、为什么缺一不可。
提示。可靠:⊢ φ ⇒ ⊨ φ(证得出的都不假);完备:⊨ φ ⇒ ⊢ φ(真的都证得出)。只有可靠,系统可能「说得太少」;只有完备,系统可能「说得太多、会说假话」。两者同时成立,语法与语义才真正对齐。
综合 13-4(切割消除)。陈述切割消除定理,并说明它如何推出「子公式性质」与算术一致性的证明思路。
提示。切割消除:任一相继式证明可改写成不用切割规则的证明。推论一:无切割证明里的每个公式都是结论的子公式(子公式性质),于是证明的形状被结论「锁住」。推论二:算术一致性——若 0 = 1 可证,则存在无切割证明,其中出现的都是 0 = 1 的子公式,而这样的证明不可能存在。根岑对算术的证明需要超限归纳,正因为无切割证明未必有限步可消。
B 组 · 计算与边界。
综合 13-5(不可判定)。用对角线法证明停机问题不可判定。
提示。假设存在判定器 H(M, x) 能判定机器 M 在输入 x 上是否停机。构造过程 D(x):调用 H(x, x);若判定「停机」则让 D 死循环,若判定「不停机」则让 D 停机。再把 D 作用于自身:D(D) 停机当且仅当它不停机——矛盾。
综合 13-6(哥德尔编码)。用符号编号表(( = 6、p = 15、→ = 4、q = 16、) = 7)写出公式 「(p → q)」 的哥德尔数。
提示。序列长度 5,用前五个素数 2, 3, 5, 7, 11:码 = 26 · 315 · 54 · 716 · 117。实验页的程序算出的就是这个数的十进制展开;由素数分解唯一性,把它分解回去就能逐位取回符号。
综合 13-7(连续统假设的独立)。说明 CH 独立性证明的两半各由谁、用什么方法给出。
提示。一半是哥德尔 1938–40 的可构成宇宙 L:它是 ZF 的内模型,在 L 中 CH 成立,故 ZFC 推不出 ¬CH(CH 相对一致,不可反驳)。另一半是科恩 1963 的力迫法:从一个可数模型出发加入「新实数」,得到 CH 失败的模型,故 ZFC 推不出 CH(CH 相对独立,不可证明)。两半合起来:CH 与 ZFC 独立。
C 组 · 模型与基础。
综合 13-8(几何模型对拍)。单位球上以三个互相垂直的点构成的球面三角形,三角和是多少?它的面积是多少?用角盈公式说明二者的关系。
提示。三个顶点两两正交,每个顶点处的球面角都是 π⁄2,三角和 = 3π⁄2。角盈 = 3π⁄2 − π = π⁄2;单位球上曲率 K = 1,高斯-博内给出面积 = 角盈 = π⁄2,正好是整球面积 4π 的八分之一。
★★★★ 先给终极挑战的验收要点,再逐题讲卷。
终极挑战的验收要点。那套希尔伯特式小系统要过四道关:① 四件套齐全——语言(¬ 与 → 为原始联结词)、三条公理模式 K, S, N、一条分离规则 MP、一套真值赋值语义。② 公理为真——把 K 的实例 p → (q → p) 逐行代入四个赋值,四行全真。③ 规则保真——MP 在两前提都真的赋值下结论必真。④ 归纳合拢——对证明长度做归纳,得「可证者皆真」。抽掉 N 的追问答:系统仍健全(剩下两个公理模式也都是重言式、MP 仍保真),但会不完备——像 (¬q → ¬p) → (p → q) 这类重言式将推不出。健全性与完备性是两根独立的柱子:拆一根,另一根不会跟着倒。
卷面总评。下表先给出每题的一行结论与关键一步;细讲见其后。
| 题号 | 结论 | 关键一步 |
|---|---|---|
| 13-1 | 是重言式;¬(p → q) ≡ p ∧ ¬q | 唯一反例代入即知两支至少一真 |
| 13-2 | 可以推出 s | 加 ¬s 后逐条归结 p, q, r |
| 13-3 | 可靠 ⊢ ⇒ ⊨;完备 ⊨ ⇒ ⊢ | 两句方向相反,缺一则语法语义不对齐 |
| 13-4 | 证明可去切割;子公式性质 | 无切割证明的公式都是结论的子公式 |
| 13-5 | 停机问题不可判定 | 构造自指过程 D,令 D(D) 自相矛盾 |
| 13-6 | 码 = 26 · 315 · 54 · 716 · 117 | 第 i 个符号用第 i 个素数 |
| 13-7 | CH 独立 | L 给「不可反驳」,力迫使「不可证明」 |
| 13-8 | 三角和 3π⁄2,面积 π⁄2 | 角盈 = π⁄2 = 面积(K = 1) |
13-1 详细解答。要证 (p → q) ∨ (q → p) 恒真。唯一可能的候选反例是使两个析取支都假的行,而 p → q 假要求 p 真、q 假;但在这同一行里 q → p 的前件 q 假,故该蕴含为真。两支不可能同时为假,原式为重言式。第二问:¬(p → q) 按蕴含的真值表只在 p 真 q 假时为真,故它等价于 p ∧ ¬q,本身已是合取范式。此题点破一件事:任何蕴含式的否定都会「降级」成一个合取式。
13-2 详细解答。把结论的否定 ¬s 添入子句集。第一步:(p ∨ q ∨ r) 与 (¬p ∨ s) 归结,得 (q ∨ r ∨ s);再与 (¬q ∨ s) 归结,得 (r ∨ s);再与 (¬r ∨ s) 归结,得单元子句 (s)。最后 (s) 与 (¬s) 归结,空子句出现,反证完成。这条链的形状值得记住:三条「否定一支、推出 s」的子句,像三个闸门,逐一把 p, q, r 排干,只剩 s。
13-3 详细解答。可靠性(健全性):若 ⊢ φ,则 ⊨ φ——每个可证公式在一切结构中都真。证明靠「公理真 + 规则保真 + 对证明长度归纳」,正是终极挑战第五步的内容。完备性:若 ⊨ φ,则 ⊢ φ——每个语义上到处为真的句子都能被证明;哥德尔 1929 给出,证明用到了判定一阶语言「是否有模型」的构造。两者方向相反:可靠性防「说假话」,完备性防「说得太少」。只可靠不完备的系统,是一台从不撒谎却常常沉默的机器;只完备不可靠的系统,是一台有问必答却满口胡言的机器。一阶逻辑两者兼备,才成为所有人的公共底座。
13-4 详细解答。切割消除(根岑 1934):任一在相继式演算里可证的相继式,都存在一个不用切割规则的证明。其一是子公式性质:无切割证明中的每一公式都是结论公式的子公式——割开证明的每一处,都找得到它在结论里的出处。其二用于一致性:若 0 = 1 可证,则存在一个无切割证明;但 0 = 1 的子公式只有它自己,而不含任何基本公理的这种末式不可能有一个合法证明,矛盾。故算术一致。注意根岑对算术的证明需要超限归纳——因为无切割证明虽然存在,却未必是有限步消去的产物;这正是「证明可以规范化」与「规范化要付出代价」的一体两面。
13-5 详细解答。见提示全文。要点是自指:设判定器 H 判定「机器 M 在输入 x 上是否停机」;构造 D(x):查 H(x, x),若答「停机」则 D 死循环,否则 D 停机。把 D 喂给自己:D(D) 停机当且仅当 D(D) 不停机。矛盾说明 H 不存在。这条对角线与罗素悖论、康托尔对角线是同一条「自指」的脊椎,只是换了一身衣服。
13-6 详细解答。符号序列 (, p, →, q, ) 的编号依次为 6, 15, 4, 16, 7;用前五个素数 2, 3, 5, 7, 11 作底,码 = 26 · 315 · 54 · 716 · 117,其十进制展开正是实验页程序打印的那个约 3.7 × 1032 的整数。解码时对每个素数取幂次,查表即还原。编码的意义不在数字本身,而在于它把「关于公式的话」翻译成「关于数的话」——这是让形式系统能谈论自己、进而制造自指句的全部机关。
13-7 详细解答。哥德尔 1938–40:在 ZF 内部构造可构成宇宙 L,它是一个内模型(与 ZF 同模型地下工作),其中选择公理与连续统假设都成立;因此在 ZFC 里推不出 ¬CH(否则 L 会自相矛盾)。科恩 1963:从 ZFC 的一个可数传递模型出发,通过力迫添加新的实数使 2ℵ0 变大,得到 CH 失败的模型;因此在 ZFC 里推不出 CH(否则该模型会自相矛盾)。两半方向相反、方法迥异,合起来才是「独立」。这恰好是完备性两句话的元层翻版:一半说「反驳不了」,一半说「证明不了」。
13-8 详细解答。三顶点两两正交,每个顶点处两条大圆弧的切向夹角都是 π⁄2,三角和 = 3π⁄2。角盈 = 3π⁄2 − π = π⁄2。单位球半径 1、曲率 K = 1,由高斯-博内 K · 面积 = 角盈,得面积 = π⁄2。这正是整球面积 4π 的八分之一——三坐标平面把单位球切成八个全等的直角三角形。本题与实验二的球面段互为印证:角盈不是装饰,它就是面积。
一句话收卷。八道题恰好把六章的工具各点了一遍:真值表与范式、归结、可靠与完备、切割消除、停机、哥德尔编码、力迫、几何模型。会做这份卷子的人,手里已经握着本书全部的行装。
★★★★ 把六章的建筑法收成三根柱子与一座桥。
小结 · 上
① 两根柱子。语法柱由四件东西砌成:一族符号、一套合式公式的形成规则、一组公理、一条或多条推理规则;柱子上刻着的动词是「可证」。语法世界里的证明是一个纯粹的符号对象——它是否合法,只取决于每一步是否按规则拼接,与外界的真假无关。语义柱由一套结构砌成:一个论域、若干关系与函数、一个把符号映射过去的方式;柱子上刻着的动词是「满足」。一个句子在某个结构里真,在另一个结构里可能假,脱离结构谈真伪没有意义。两根柱子合起来,才是逻辑的完整身量:一根管「搭得出」,一根管「真不真」。
② 一座桥。两根柱子之所以不是两座孤立的塔,全靠中间的桥。可靠性说:可证的必真(⊢ ⇒ ⊨)——语法从不越界,机器学习语法永远学不出假话。完备性说:真的必可证(⊨ ⇒ ⊢)——语义没有漏网之鱼,凡是到处为真的句子,语法侧都能把它推出来。哥德尔 1929 年证明一阶逻辑两者兼备,这是逻辑学成为一门完备学科的定音之锤。桥的形状是一切「形式化」得以可能的前提:人在语义侧理解,机器在语法侧核对。
③ 三个定音定理。全书有三条定理定义了这门学问的边界。完备性(1929):一阶逻辑的语法与语义对齐——「要什么有什么」。切割消除(1934):每个证明都可改写成不使用切割的证明——证明的形状可以被规范化,证明于是变成程序。这两条是「能给尽给」。不完备(1931):足够强又一致的系统必有不为其所证的句子,且证不了自身一致性——「再给也给不出」。三条定理一正一反,把「能给」与「给不出」的分界线画得清清楚楚。其中切割消除与不完备甚至同出于根岑与哥德尔对算术的同一种追问,只是拿到了一正一反两个答案。
分层的建筑。逻辑不是一层楼,而是一栋多层的建筑。底层是命题逻辑:只有联结词,可判定,真值表一算到底,优雅但贫瘠。中层是一阶逻辑:加进量词与关系,表达力猛增,可证性仍完备,但判定不再可算法化(第四章);它是几乎所有形式化的公共楼层。高层是算术与集合论:一阶算术与集合论本身就在这一层,这里是哥德尔不完备定理生效的地方——楼层够高,就够得着自己说不了的话。顶层是类型论与高阶逻辑:命题与类型、证明与程序合流,是当代证明助手的落脚处。每一层都自带一根语法柱、一根语义柱和一座桥,只是桥的完好程度逐层递减。
与旧章的接口。第三章的相继式是语法柱的承重墙;第二章的结构与满足是语义柱的地基;第四章的图灵机问的是「这栋楼里哪些问题有算法楼梯」;第五章的哥德尔编码问的是「哪些问题连楼梯都没有,甚至楼本身都够不着」;第六章的证明助手则是把这栋楼搬进计算机,让每一面墙都在机器里被逐块检查。同一栋楼,六个视角。
一句总结。一门学问能立多高,取决于它的语法与语义对齐得多严。数理逻辑的全部力量来自一个朴素的事实:把「推出」写成符号,再用另一双眼睛逐行核对——这座桥修得越牢,数学就越不可能在无人察觉处塌方。此即「逻辑的建筑学」。
★★★★ 三条干线,一条金线。
三条干线。语法线从弗雷格的概念文字走到根岑的相继式,再走到马丁-洛夫的构造类型论,问的是「证明能被写成什么形状」;语义线从布尔的代数走到塔斯基的真定义,再走到模型论,问的是「真在什么结构里成立」;计算线从希尔伯特与阿克曼的判定问题走到图灵机、库克定理与证明助手,问的是「哪些问题有算法、哪些没有」。三条线各有一位旗手:语法线的根岑、语义线的塔斯基、计算线的图灵。它们并非三件事:能写的形状决定了能谈的真,能谈的真决定了能问的算法,而算法的边界又反过来限定了形状的用处。
一条金线:可检查性。贯穿三条干线的,是一个朴素得近乎技术性的要求——推理的每一步都必须能被另一双眼睛逐行核对。语法线为它提供对象(可检查的证明),语义线为它提供基准(结构中的真假),计算线为它提供执行者(机器)。这条金线的历史就是逻辑从「辩论术」长成「工程学」的历史:亚里士多德的三段论是给辩论规定的检查规则,希尔伯特纲领是给全部数学规定的检查规则,图灵机是给「检查」这件事本身造出的机器,证明助手是给当代数学准备的检查车间。逻辑最深的野心不是变得聪明,而是变得诚实——让每一步都摊在阳光下。
三处出口。合流之后,这门学问流向三个方向。数学基础:集合论、连续统假设的独立、逆向数学(把定理反推回它真正依赖的公理强度)、构造主义与单一性基础,都是逻辑给数学本身画的地图。计算机科学:可计算性、复杂度、程序验证、类型系统、数据库查询语言、人工智能的推理与证明,逻辑是它们共同的语法;一份写对类型的程序就是一份写对的证明。哲学与认知:什么是真、心灵能否被形式化、机器能否思考——这些问题在哥德尔定理之后都有了更精确的表述方式,尽管答案仍然敞开。一门从辩论起步的学问,最终在三个现代领域里都有座位。
一望前沿。把已知与未知并排看。已知:命题逻辑与一阶逻辑的理论极为完善,可判定片段(实闭域、Presburger 算术、初等欧氏几何)有确定的算法,哥德尔不完备定理划定的边界不会移动。未知与进行中:形式化数学仍在规模化(大型数学库、Flyspeck 一类工程把越来越深的结果搬进机器);同伦类型论试图给数学一个「证明即路径」的新基础,其地位尚未定论;人工智能辅助证明正把「提出猜想—搜索证明—机器核验」接成一条链,人与机器的分工仍在重新划分;而绝大多数「过筛但存亡未定」的可判定片段边界问题,依旧大片空白。
最后一次回望。本册从三段论出发,走到机器能逐行核验证明的今天。这一路上真正被反复使用的只有两样东西:一族符号,以及「换一双眼睛再核对一遍」这条纪律。合上书时,若还能记住一句话,愿它是这一句:逻辑的世界观,就是把「显然」换成「可检查」——把每一次「我觉得对」,都改写成「也能核对」。
★★★★ 全书一页收账,备查。
| 符号 | 读作 | 含义 |
|---|---|---|
| ¬ ∧ ∨ → ↔ | 非、与、或、蕴含、等价 | 命题联结词;→ 与 ¬ 可定义其余 |
| ∀ ∃ | 对所有、存在 | 量词;∃ 可由 ∀¬ 定义 |
| ⊢ | 可证 | 存在一个从公理出发的有限证明(语法侧) |
| ⊨ | 满足 / 蕴含 | 在结构(赋值)中为真(语义侧) |
| 𝒜, ℬ, ℳ | 花体字母 | 结构;带论域、关系与函数 |
| φ, ψ, χ | phi, psi, chi | 公式(合式公式) |
| ⊥, ⊤ | 假、真 | 空子句 / 恒真;⊥ 即矛盾 |
| PA · ZFC · LK | 正体 | 皮亚诺算术 · 集合论 · 相继式演算(系统名正体) |
| 核心定义 | 内容 | 章节 |
|---|---|---|
| 重言式 | 在一切赋值下都为真的公式;命题逻辑可经真值表判定 | 第一章 |
| 范式 | 主析取 / 主合取范式:每个公式唯一对应一组极小项或极大项 | 第一章 |
| 归结 | 由互补文字消去得新子句;导出空子句即不可满足 | 第二、三章 |
| 结构 / 满足 | 论域加解释;𝒜 ⊨ φ 记结构 𝒜 满足 φ | 第二章 |
| 相继式 | Γ ⇒ Δ:由 Γ 推出 Δ 的推理形状 | 第三章 |
| 切割消除 | 任一证明可化为不用切割规则的证明 | 第三章 |
| 图灵机 | 纸带 + 读写头 + 状态转移;刻画「可计算」的标准模型 | 第四章 |
| 哥德尔编码 | 符号编号 → 素幂乘积;公式与证明都变成自然数 | 第五章 |
| 公理系统 | 骨架 | 备注 |
|---|---|---|
| 命题希尔伯特系统 | K: φ→(ψ→φ);S、N 模式;规则仅 MP | 健全且完备;终极挑战的对象 |
| 皮亚诺算术 PA | 后继、加法、乘法、归纳公理模式 | 足够强 ⇒ 受不完备定理约束 |
| 希尔伯特几何 | 关联 · 顺序 · 合同 · 平行 · 连续五组公理 | 换掉平行公理即得罗氏几何 |
| ZFC 集合论 | 外延 · 空集 · 配对 · 并 · 幂 · 替换 · 无穷 · 选择 等 | 数学的通行地基;CH 与之独立 |
| 核心定理 | 陈述 | 年份 · 出处 |
|---|---|---|
| 可靠性 | ⊢ φ ⇒ ⊨ φ(可证者皆真) | 语法与语义的护栏 |
| 完备性(一阶) | ⊨ φ ⇒ ⊢ φ(到处为真者可证) | 哥德尔 1929 |
| 紧致性 | 理论可满足 ⟺ 每个有限子集可满足 | 完备性的推论 |
| 切割消除 | 任一相继式证明可去切割 | 根岑 1934 |
| 柯里-霍华德对应 | 证明 ≅ 程序;命题 ≅ 类型 | 第三章 |
| 停机问题 | 不存在判定任一程序是否停机的算法 | 图灵 1936 |
| 第一不完备定理 | 足够强又一致的系统存在不可判定的句子 | 哥德尔 1931 |
| 第二不完备定理 | 这样的系统证不了自身一致性 | 哥德尔 1931 |
| CH 独立 | 连续统假设既不可反驳(哥德尔 1938–40)也不可证明(科恩 1963) | 第五、六章 |
| 关键事实 | 数值 / 内容 |
|---|---|
| 真值表规模 | n 个变元共 2n 行;八行即穷尽三变元 |
| 归结反证 | 前提加结论否定 ⇒ 导出空子句,即得证明 |
| 哥德尔数(例) | 「(p→q)」 = 26·315·54·716·117 |
| 球面角盈 | 单位球上 三正交三角形:三角和 3π⁄2,角盈 π⁄2 = 面积 |
| 双曲角亏 | 边长 1 的等边三角形:三角和 ≈ 2.756,角亏 ≈ 0.385 = 面积 |
| 有限几何点线账 | AG(2,3): 9 点 12 线;PG(2,3): 13 点 13 线,两线恒交一点 |
| 干线 | 路径 | 关键定理 |
|---|---|---|
| 语法线 | 概念文字 → 相继式 · 切割消除 → 自然演绎 → 构造类型论 | 切割消除;柯里-霍华德对应 |
| 语义线 | 逻辑代数 → 真值表 · 结构 → 塔斯基真定义 → 模型论 | 完备性;紧致性 |
| 计算线 | 判定问题 → 图灵机 · 不可判定 → 复杂度 → 证明助手 | 停机问题的不可判定;库克定理 |
口诀。先写符号 → 再算真假 → 后搭证明 → 最后一台机器核对。
最后一行。逻辑是一件事:把「推出」变成可检查的符号。语法是它的正面,语义是它的反面,而「可检查」是贯穿两面的一条金线。