Ran Wei/数学系列
English
计算机科学与人工智能的数学基础 — Ran Wei

证明方法、归纳法与不变式

写出覆盖所有允许情况的论证。学习直接与间接证明、数与结构归纳,并分别证明程序结果正确和最终终止。

10 小时4 个时段3 个实验12 道练习与 2 道拓展10 道自测题

完成后你能够

  • 明确假设与结论并选择有效证明方法。
  • 写直接、逆否、反证、存在与唯一性论证。
  • 带明确基础情况完成普通或强归纳。
  • 利用递归定义与结构归纳,避免预先假定结果。
  • 用不变式证明搜索的部分正确性,用递减自然数度量证明终止。

开始之前

模块 02–03:量化陈述、反例、成员证明、关系与函数约定。回忆蕴含与逆否等价,以及相等和子集定义。

目录

学习计划

10 小时

时间包含练习,是估计值;可按需要拆分时段。可选拓展练习额外需要 25 分钟。进度保存在当前浏览器,中英文版本共享。

1

检验证据与证明回答不同问题

多项式 n2+n+41n^2+n+41 在整数零到三十九上都给出质数,很容易猜测它永远如此。但四十时得到 1681=4121681=41^2,因此无限主张为假。四十个成功例子为猜想提供有用证据,一个有效反例就能否定;更多成功测试不能修复该全称陈述。

证明的义务是从明确假设与定义出发,覆盖规定论域中的每种情况。程序证明还有另一层区别:说明返回答案正确,不保证程序最终会返回。若约定承诺完成,就需要结果论证与终止论证。

回忆检查:写蕴含的逆否,描述等价类,并用任意成员证明简单包含。按需复习模块 02与模块 03。使用经典逻辑、普通有限列表和含零自然数。未说明时,“所有列表”指所有有限列表。

2

陈述、假设与定义的作用

定理(theorem)是已证明陈述,假设(hypotheses)规定结论成立的前提,引理(lemma)是用于另一论证的已证明辅助结果,正确性标准相同。猜想(conjecture)还需要论证。成功例子可说明定理或支持猜想,不能替代无限主张的证明。

选方法前,明确论域与逻辑结构。“奇数相乘仍为奇数”意为任意整数 a、b,若两者奇则乘积奇。全称蕴含提示:取任意满足假设的整数,应用奇数定义。不必枚举整数或使用高级定理。

例题详解
定义把主张变成计算

取任意奇整数 a、b,按定义存在整数 k、l,使 a=2k+1,b=2l+1a=2k+1,b=2l+1。于是 ab=4kl+2k+2l+1=2(2kl+k+l)+1ab=4kl+2k+2l+1=2(2kl+k+l)+1。括号内是整数,因此乘积按定义为奇数。a、b 的任意性覆盖所有满足假设的配对,无需测试特定数字。

论证结构是:取任意允许输入,展开假设,做有理由的变换,识别结论定义。只写代数漏掉符号为何存在及括号为何整数;只说奇乘奇为奇则重复主张。证明要连接两者。

假设只在作用域内可用。证明 P⇒QP\Rightarrow Q 可以假设 P 推导 Q,不能先假设 Q 并把其后果当证明。反向计算有时可用,但必须每步可逆并说明。平方方程或乘可能为零的量可失去等价或引入候选;蕴含链不自动是等价链。

全称证明的输入须在论域内任意。“令 n=4”只证明四处事实。存在证明则可选具体值,但必须验证见证。集合相等通过任意成员的双向一致性确立。逻辑结构决定证据形式。

证明的结构从任意允许输入到假设、定义和有效规则,再到结论。任意允许输入展开假设应用定义与规则确立结论每个步骤都需要理由;输入的任意性决定覆盖范围
图 4.1

证明由输入与假设经过定义和有效步骤到结论。测试关注选定输入,证明链覆盖规定任意输入。

保持符号稳定。k 若代表奇数见证,不要突然改为列表索引或别的见证。不同存在假设提供的整数用不同名字,除非已证明相等。每个符号角色和每个结论理由清晰,证明更易审查;简短不能省略必要联系。

反例也须严格。否定 ∀x∈D,P(x)\forall x\in D,P(x) 要给 x∈Dx\in D 且 P 假。否定条件式要前提真、结论假。负输入不能反驳非负输入主张,前提不满足的例子不能反驳蕴含;它们可以说明范围,但应标明用途。

检验理解

检查五对奇数乘积就说证明,遗漏什么?若存在有效奇数对却有偶数乘积,为何一个例子足够?

查看答案

测试未覆盖任意配对,也未用定义连接所有乘积。有效奇数对的偶数乘积满足假设而违反结论,直接否定全称蕴含。

3

直接、分类、逆否与反证

直接证明(direct proof)由假设推出结论,奇数乘积就是例子。分类证明(proof by cases)把允许论域分为覆盖完整的情况,各自证明。可以重叠,不能漏掉输入。分类应依据定义或运算在不同区域的行为。

例题详解
按绝对值定义分类

任意实数 x,若 x≥0x\ge0,∣x∣=x|x|=x,故 ∣x∣2=x2|x|^2=x^2;若 x<0x<0,∣x∣=−x|x|=-x,故 ∣x∣2=(−x)2=x2|x|^2=(-x)^2=x^2。两情况覆盖所有实数,零在第一分支,恒等式成立。

证明 P⇒QP\Rightarrow Q 的逆否方法确立 ¬Q⇒¬P\neg Q\Rightarrow\neg P,模块 02 已证明等价。当非 Q 比 P 易表示时有用。不要与逆命题 Q⇒PQ\Rightarrow P 或否命题 ¬P⇒¬Q\neg P\Rightarrow\neg Q 混淆,它们通常是不同主张。

例题详解
通过逆否证明奇偶主张

主张:整数平方偶,则整数偶。证明逆否:n 非偶即奇,写 n=2k+1n=2k+1,k 整数。平方为 4k2+4k+1=2(2k2+2k)+14k^2+4k+1=2(2k^2+2k)+1,奇而非偶。这里明确使用每个整数非奇即偶的基本事实。逆否证明原蕴含。

反证法(proof by contradiction)假设前提与结论否定,推出不可能。在经典逻辑中,没有允许情况能一致满足这些假设,因此结论成立。应指出具体矛盾:陈述与其否定、严格大于又不大于,或违反已证明事实。

例题详解
不存在最大整数

假设最大整数 M 存在。整数 M+1>MM+1>M,与 M 至少不小于每个整数矛盾,故不存在最大整数。M+1M+1 依赖候选最大值,选一个固定大数不能排除所有可能 M。

逆否与反证相似但起点不同。逆否假设非 Q 来证明非 P;反证假设 P 且非 Q 来推出假。方法应简化论证,不应把待证结论隐藏于假设。

否定主张可用反例。“所有函数保持加法”被平方函数在二与三上否定;反向极端“没有函数保持加法”也为假,恒等函数保持。否定全称只是某个失败,不是所有对象都失败。

软件分类也要覆盖完整。搜索有成功位置与缺失标记两种返回,只验证成功分支不证明缺失。递归对象可能多个基础构造,只处理一个不覆盖其他对象。先列定义要求的情况,再审代数。

使用外部定理时明确陈述并检查前提。后续 AI 论证可能要求可微或凸,当前函数满足后才可使用结论。本模块依赖基本奇偶、整数算术及已证明逻辑规则;显式记录依赖可避免循环论证。

检验理解

证明“n 偶则平方偶”为何不足以证明“平方偶则 n 偶”?上面用的是哪个等价陈述?

查看答案

前者是逆命题。等价逆否为“n 非偶则平方非偶”,上面通过奇数表示确立它。

4

存在、唯一与构造性论证

存在陈述要求至少一个满足性质的对象。构造性证明(constructive proof)给对象或生成方法,再验证性质与论域。“应该有解”不是证据。代数若引入候选或改变定义域,须代回验证。

例题详解
存在与唯一是不同义务

实数方程 3x+5=173x+5=17:选 x=4x=4,验证 3⋅4+5=173\cdot4+5=17,得到存在。若 u、v 都满足方程,相减给 3(u−v)=03(u-v)=0,故 u=vu=v,得到唯一。前者找到解,后者排除两个不同解,合起来才恰好一个。

∃!x,P(x)\exists!x,P(x) 结合存在与至多一个。仅证明任意两解相同,只得至多一个,无解时也可成立。实数 x2=−1x^2=-1 无解,对两个假设解的条件比较不说明存在。只找到一个也不说明唯一,x2=1x^2=1 有正负一。

构造可以依赖给定输入。每个整数 x 有更大整数,可定义 x+1x+1 并验证,证明 ∀x∃y,y>x\forall x\exists y,y>x,不证明一个固定 y 超过全部 x。量词顺序在证明中仍重要;构造见证的算法应声明输入论域与保证。

有时存在通过间接论证确立:假设没有见证导致矛盾,在经典逻辑中可证明存在,却未给便于实现的构造。数学定理可能够用,要求实际返回对象的程序则还需操作方法与资源论证。

唯一论证常比较任意假设解。偏序两个最小元 a、b 互相在对方之下,反对称推出相等。它不证明每个偏序有最小元。模块 03 的不可比单元素集反驳存在。不要把唯一性引理扩大成存在定理。

定义可供构造:非空有限整数列表的最小值,可从首项开始,遇更小项更新。完整正确性需要“不变式:候选是已处理前缀最小值”,终止依赖有限项数。构造提示证明,却不能只说算法显然找到。

证明两个表示对应,可构造双向映射并验证复合恢复输入。记录与标识双射给唯一逆,多对一类别标签不能。构造逆必须同时覆盖逆论域并保证输出唯一。

反例也可构造:选择对象,验证确切违反点。“每个对称关系传递”被三对象接近关系否定:两已有配对、一个缺闭合。见证不需大或真实,只需满足前提;小见证更易保存与理解。

检验理解

证明任意两个满足 P 的对象相同,为什么 ∃!x,P(x)\exists!x,P(x) 仍未证明?给无实见证与两个实见证的性质。

查看答案

存在未证明。x2=−1x^2=-1 无实见证,x2=1x^2=1 有正负一。存在与唯一论证解决不同义务。

5

普通归纳、强归纳与良序

数学归纳(mathematical induction)证明自然数索引陈述族。对全部 n≥n0n\ge n_0,先证明基础 P(n0n_0),再对任意 k≥n0k\ge n_0,暂时假设 P(k),推导 P(k+1)。临时假设称归纳假设;它合法,因为归纳步证明蕴含,基础启动链。

例题详解
完整有限和归纳

主张:每个自然数 ∑i=1ni=n(n+1)/2\sum_{i=1}^n i=n(n+1)/2。基础零:空和,两侧零。任意 k≥0k\ge0 假设公式成立,则

∑i=1k+1i=(∑i=1ki)+(k+1)=k(k+1)2+(k+1)=(k+1)(k+2)2.\sum_{i=1}^{k+1}i=\left(\sum_{i=1}^k i\right)+(k+1)=\frac{k(k+1)}2+(k+1)=\frac{(k+1)(k+2)}2.

中间代入归纳假设,其他步骤拆和与代数化简。因此 P(k) 推出 P(k+1),与基础共同证明所有非负情况。

归纳链与缺失基础证明 P0 并通过逐项后继步覆盖全部自然数。错误奇数和的基础失败,尽管步一致。基础与后继步缺一不可P(0)P(1)P(2)P(3)…基础已证明每步:假设 P(k),推出 P(k+1)错误 n²+1:步能延续,但基础 0 ≠ 1
图 4.2

基础确立首项,归纳步把每个已成立情况连接到下一项。有有效连接但没有起点,不得到真理链。

缺基础可能留下假族但有一致代数步。错误奇数和 ∑i=0n−1(2i+1)=n2+1\sum_{i=0}^{n-1}(2i+1)=n^2+1 加 2n+12n+1 后仍得 (n+1)2+1(n+1)^2+1,多出的一持续传播。然而零处基础假,所以归纳不能成立。假前件的蕴含不会制造真结论。

强归纳(strong induction)允许假设 P(n0n_0) 到 P(k) 的全部较早情况来证明下一项,适合依赖多个或不紧邻较小输入。强归纳与普通归纳证明能力相同:普通归纳可跟踪更强命题“到 k 的全部情况成立”,得到下一步所需强假设。

每个整数 n≥2 都可表示为质数乘积。基础二为质数。强归纳步考虑 k+1:若质,已是一因子乘积;否则为 ab,2≤a,b<k+12\le a,b<k+1,假设给 a、b 的质数乘积,合并得到 k+1。这里只证明分解存在,不证明唯一,后者需要额外论证。

基础覆盖由向后依赖决定。若步向后减三,一个基础未必覆盖各余数链。例如全部 n≥8 可写 3a+5b3a+5b,a、b 非负:基础 8=3+5、9=3+3+3、10=5+5;n≥11 时 n−3≥8 已有表示,再加三。此特定论证需要三个基础。

良序原理(well-ordering principle)说自然数每个非空子集有最小成员。若陈述族有失败,选最小失败索引;它非已证明基础,较前索引成功,归纳步又使它成功,矛盾。这解释归纳,但依赖有下界的自然索引,不适用于没有最小元的任意集合。

明确起始索引、假设范围和归纳步目标。证明 P(k+1) 时假设 P(k+1) 是循环。只有 P(k) 到 P(k+2) 与基础零可能只覆盖偶数。测试可揭错误,书面证明仍须说明基础与步覆盖全部论域。

检验理解

只有 P(0) 与 P(k) 推出 P(k+2),能证明所有非负索引吗?再加哪个基础可使该步足够?

查看答案

只覆盖偶数链。加 P(1) 启动奇数链,就覆盖两种;也可改为直接后继步。

6

递归定义与结构归纳

有些对象由构造规则定义。有限列表或为空,或由头与更小尾组成;有限满二叉树或为叶,或为恰好两个子树的节点。递归定义必须给全部构造、允许较小部分与基础。这些规则定义结构证明的论域。

列表空写 [][],头 h 与尾 t 写 h::th::t。长度 ℓ([])=0\ell([])=0,ℓ(h::t)=1+ℓ(t)\ell(h::t)=1+\ell(t);拼接 []+ ⁣+b=b[]\mathbin{+\!+}b=b,(h::t)+ ⁣+b=h::(t+ ⁣+b)(h::t)\mathbin{+\!+}b=h::(t\mathbin{+\!+}b)。这不是 Python 语法;Python 列表 + 可实现有限行为,高效实现不必照搬递归定义。

结构归纳(structural induction)证明基础构造,再对每个复合构造,假设较小组成部分的性质并证明整体。它遵循对象语法,不能假设正在证明的整体性质。有限构造规则生成的每个对象都由这些情况覆盖。

例题详解
拼接列表的长度

任意有限 a、b,证明 ℓ(a+ ⁣+b)=ℓ(a)+ℓ(b)\ell(a\mathbin{+\!+}b)=\ell(a)+\ell(b)。对 a 结构归纳,b 保持任意。基础 a=[],左侧 ℓ(b)=0+ℓ(b)\ell(b)=0+\ell(b)。a=h::th::t 时,假设尾 t 对每个 b 成立,则 ℓ((h::t)+ ⁣+b)=1+ℓ(t+ ⁣+b)=1+ℓ(t)+ℓ(b)=ℓ(h::t)+ℓ(b)\ell((h::t)\mathbin{+\!+}b)=1+\ell(t\mathbin{+\!+}b)=1+\ell(t)+\ell(b)=\ell(h::t)+\ell(b)。每步由递归定义或较小尾假设支持。

列表结构归纳空列表基础长度零;头尾构造使用尾的假设并增加一个头。基础:空列表[]length = 0构造:头与较小尾h :: t归纳假设在 t 上length = 1 + length(t)证明构造保持性质,不假设整个新列表的结论
图 4.3

列表归纳有空基础与头—尾步。假设属于尾,长度定义为新头增加一。

树可能需两个假设。有限满二叉树叶数 L、内部节点数 I,主张 L=I+1。叶基础 L=1,I=0。两个子树 A、B 的节点,叶数相加,内部数 1+I(A)+I(B)1+I(A)+I(B);用两假设给 L(A)+L(B)=I(A)+I(B)+2=I(T)+1L(A)+L(B)=I(A)+I(B)+2=I(T)+1。“恰好两子”至关重要,一般树未必成立。

递归计算还需终止。有限非空列表递归调用尾,长度减一直到空;再次调用同一列表则无进展。终止度量取自然数并在每次调用严格减小,有限长度可用。任意实数递减不够,1,1/2,1/4,…1,1/2,1/4,\ldots 可永远递减而不为零。

整数递归需允许论域与可达基础。非负 n 的倒数,零为基础,n>0 时调用 n−1,在自然数中递减而终止。允许负数但无其他基础,反复减一可能远离零。有基础语句不够,全部允许调用路径必须到达已处理情况。

结构归纳与按大小归纳相关,但构造形状让假设更清楚。两子树需要各自假设,表达式语言多个构造就多个情况。漏一构造便留下论域一部分未证明,哪怕所有例子都来自已处理构造。

证明递归性质不保证实现快。正确性与操作数量不同。某语言的递归拼接可能反复复制,长度恒等式仍数学正确。模块 06 分析增长与递推;当前先证明定义良好、允许有限结构上终止且满足性质。

检验理解

满二叉树公式为什么两个归纳假设?给满二叉论域之外使 L=I+1 失败的树。

查看答案

构造有两个较小子树,计数用两者。根仅有一个叶子子节点时 L=1,I=1,1≠1+11\ne1+1,违反恰好两子假设。

7

循环不变式与独立终止论证

循环不变式(loop invariant)是在从前置条件可达的每次迭代指定点成立的谓词。正确性需要初始化、保持、退出结论。它无需描述每行,但观察点应一致。几次断言成功是工具反馈,不是一般证明。

考虑固定有限整数列表 a、长度 n、整数目标 t。i 从零开始,循环条件 i<n,若 ai=ta_i=t 返回 i,否则 i 加一;正常退出返回 −1。假设比较和访问会终止,列表搜索中不变。这明确状态模型,排除变化数据悄悄破坏论证。

循环头不变式为:

0≤i≤n∧∀k∈{0,…,i−1}, ak≠t.0\le i\le n\quad\land\quad\forall k\in\{0,\ldots,i-1\},\ a_k\ne t.

它表示合法边界及已处理前缀无匹配。初始 i=0,前缀空,两条件真。保持:假设不变式与 i<n,当前不匹配就加一。旧前缀无匹配,新加入的旧 i 也无匹配,所以新前缀无匹配,新边界至多 n。

例题详解
由不变式得到搜索后置条件

匹配分支返回 i 时,条件给 0≤i<n0\le i<n,分支给 ai=ta_i=t,不变式给之前无匹配,故首次。正常退出时条件假给 i≥ni\ge n,不变式给 i≤ni\le n,故 i=n,前缀覆盖全列表,−1 正确表示不存在。空列表同样满足初始化与退出论证。

搜索不变式与变式i 从零到四,已处理前缀扩大且无三,n−i 从四到零。a = [2, 5, 2, 7],目标 3 缺失i已处理前缀n − i042527132527222527312527402527前缀无目标始终成立;变式严格递减至零
图 4.4

目标缺失时,已处理前缀扩张,自然数度量 n−i 从四降到零。正确性用前缀谓词,终止用递减度量。

不变式给部分正确性:凡返回都符合约定。终止用变式(variant) V=n−iV=n-i,每个循环头为非负整数;不返回而继续的迭代使 i 加一,V 严格减一。非负整数不能无限严格下降,最多 n 次失败比较;成功分支立即终止。

不变式本身未必有进展。错误循环不断检查首个不匹配项,保持 i=0,“i 之前无匹配”永真,但可能不返回。部分正确性条件未必失败,完全正确性却失败。反过来,程序可以终止并返回错误位置,两义务独立。

交互演示

逐步检查存在、缺失、重复与空列表,观察循环头索引、前缀、不变式与变式。完整一般证明在上文,无需脚本。

检查一项后,处理区从小于 i 变成至多 i;增加索引后,同一区又可说小于新 i。混淆新旧值常导致保持错误。不清楚时使用 ioldi_{old} 与 inew=iold+1i_{new}=i_{old}+1,明确断言位置。

方法也适用于最小值、计数与累加。“累加器等于 i 前项和”的不变式用空和初始化,加下一项保持,退出给完整和;未处理数量变式给终止。每个算法需要自己的谓词,仅复制义务名称而不分析转换不是证明。

断言可揭不变式错误,边界测试可揭遗漏分支,证明则覆盖假设下任意允许有限输入。真实代码若改变列表、停止条件或返回后续重复项,须对照已证明转换规则,不能自动移用定理。

检验理解

非匹配迭代一直保持 i=0,搜索不变式是否仍真?变式是否证明终止?用缺失目标解释。

查看答案

空前缀不变式可永真,n−i 却始终 n。不空列表首项不匹配时重复不结束,完全正确性失败。

8

常见误解

症状 原因 修复
多例子被称全称证明 混淆证据与覆盖 任意输入或构造/索引覆盖
从待证结果开始代数 循环或未说明可逆 从假设出发,逐步说明方向
提交逆命题代替原式 反转条件方向 先写原式与逆否
至多一个称唯一存在 缺存在 给见证并比较任意两解
归纳缺基础或跳链 未检查步依赖 列基础与准确后继规则
递归重复同输入 无良基递减 自然数中严格减小且基础可达
不变式称终止证明 状态真与进展混淆 增加非负严格递减变式
9

实验设置与证明解释

使用 Python 3.11 或更新版本,全部标准库。运行方法见 Python 入门。每次预测、解释数学义务、诊断变化;十分分为预测三、解释四、故障三。断言验证实际执行,书面证明仍要覆盖任意允许输入。

10

实验 1 比较证据与证明

五十分钟:预测有限和与多项式首个反例,运行。解释九次成功和检查不能证明无限族,四十处却否定质数猜想。第二时段后重建第 4 节归纳。改变范围使其排除 n,找最小失败非负输入,保存反例并区分实现故障与假定理。

下载 lab1_evidence.py

"""Successful finite checks support debugging; one valid counterexample refutes."""
from math import isqrt


def prime(n):
    return n >= 2 and all(n % divisor for divisor in range(2, isqrt(n) + 1))


def main():
    for n in range(9):
        actual = sum(range(n + 1))
        expected = n * (n + 1) // 2
        assert actual == expected
        print(f"n={n}: sum={actual}, formula={expected}")
    first_failure = next(n for n in range(51) if not prime(n * n + n + 41))
    value = first_failure * first_failure + first_failure + 41
    assert first_failure == 40 and value == 41 * 41
    print("Polynomial prime claim passes n=0 through 39.")
    print(f"Counterexample n={first_failure}: value={value}=41*41")
    print("The sum checks cover n=0..8; its general proof is separate.")


if __name__ == "__main__":
    main()
输出
n=0: sum=0, formula=0
n=1: sum=1, formula=1
n=2: sum=3, formula=3
n=3: sum=6, formula=6
n=4: sum=10, formula=10
n=5: sum=15, formula=15
n=6: sum=21, formula=21
n=7: sum=28, formula=28
n=8: sum=36, formula=36
Polynomial prime claim passes n=0 through 39.
Counterexample n=40: value=1681=41*41
The sum checks cover n=0..8; its general proof is separate.
11

实验 2 为搜索加不变式检查

五十分钟,在第 6 节之后:预测晚匹配、缺失、首项重复与空列表的循环头行。运行并标注初始化、保持、成功返回与正常退出。区别不变式断言与变式递减断言。把增量一改成二,找跳过匹配的情况,解释旧保持论证为何不再覆盖整个已处理前缀。

下载 lab2_search_invariant.py

"""First-match search with assertions at the loop head and a separate variant."""


def first_match(items, target):
    n, i = len(items), 0
    while i < n:
        invariant = 0 <= i <= n and all(value != target for value in items[:i])
        assert invariant
        print(f"  head: i={i}, prefix={items[:i]}, invariant={invariant}, variant={n-i}")
        if items[i] == target:
            assert all(value != target for value in items[:i])
            return i
        previous_variant = n - i
        i += 1
        assert n - i < previous_variant
    assert i == n and all(value != target for value in items)
    print(f"  exit: i={i}, invariant=True, variant=0")
    return -1


def main():
    cases = [([2, 5, 2, 7], 7, 3), ([2, 5, 2, 7], 3, -1), ([4, 9, 4], 4, 0), ([], 9, -1)]
    for items, target, expected in cases:
        print("items=", items, "target=", target)
        result = first_match(items, target)
        assert result == expected
        print("  result=", result)
    print("Assertions check these executions; the lesson proves the general obligations.")


if __name__ == "__main__":
    main()
输出
items= [2, 5, 2, 7] target= 7
  head: i=0, prefix=[], invariant=True, variant=4
  head: i=1, prefix=[2], invariant=True, variant=3
  head: i=2, prefix=[2, 5], invariant=True, variant=2
  head: i=3, prefix=[2, 5, 2], invariant=True, variant=1
  result= 3
items= [2, 5, 2, 7] target= 3
  head: i=0, prefix=[], invariant=True, variant=4
  head: i=1, prefix=[2], invariant=True, variant=3
  head: i=2, prefix=[2, 5], invariant=True, variant=2
  head: i=3, prefix=[2, 5, 2], invariant=True, variant=1
  exit: i=4, invariant=True, variant=0
  result= -1
items= [4, 9, 4] target= 4
  head: i=0, prefix=[], invariant=True, variant=3
  result= 0
items= [] target= 9
  exit: i=0, invariant=True, variant=0
  result= -1
Assertions check these executions; the lesson proves the general obligations.
12

实验 3 暴露两种错误论证

五十分钟:错误奇数和有一致代数步却有假基础,预测四行并解释不能启动归纳。递归跟踪故意限制展示五次,避免实验挂起;重复相同 n 表示无进展。解释展示上限不是错误递归的终止证明,以及修复倒数为何有自然数度量。

下载 lab3_faulty_arguments.py

"""Expose a missing induction base and a non-decreasing recursive measure."""


def main():
    print("Proposed identity: sum of first n odd numbers = n^2 + 1")
    for n in range(4):
        actual = sum(2 * i + 1 for i in range(n))
        candidate = n * n + 1
        step_matches = candidate + 2 * n + 1 == (n + 1) ** 2 + 1
        print(f"n={n}: actual={actual}, candidate={candidate}, proposed step consistent={step_matches}")
    print("Base at n=0 fails: 0 != 1. A valid algebraic step does not supply a base.")
    faulty_trace = [5] * 5
    correct_trace = list(range(5, -1, -1))
    print("Bounded illustration of faulty calls countdown(n):", faulty_trace)
    print("Correct calls countdown(n-1):", correct_trace)
    faulty_decreases = all(b < a for a, b in zip(faulty_trace, faulty_trace[1:]))
    correct_decreases = all(b < a for a, b in zip(correct_trace, correct_trace[1:]))
    assert not faulty_decreases and correct_decreases
    print("Natural-number measure strictly decreases:", faulty_decreases, correct_decreases)
    print("Five displayed faulty calls are a trace limit, not termination of that recursion.")


if __name__ == "__main__":
    main()
输出
Proposed identity: sum of first n odd numbers = n^2 + 1
n=0: actual=0, candidate=1, proposed step consistent=True
n=1: actual=1, candidate=2, proposed step consistent=True
n=2: actual=4, candidate=5, proposed step consistent=True
n=3: actual=9, candidate=10, proposed step consistent=True
Base at n=0 fails: 0 != 1. A valid algebraic step does not supply a base.
Bounded illustration of faulty calls countdown(n): [5, 5, 5, 5, 5]
Correct calls countdown(n-1): [5, 4, 3, 2, 1, 0]
Natural-number measure strictly decreases: False True
Five displayed faulty calls are a trace limit, not termination of that recursion.
13

练习与完整解答

练习 1–12 预计 140 分钟,每题五分;两扩展额外 25 分钟。说明假设、范围与关键理由。只有空证明模板不满足义务。

练习 1★★★概念6 分钟

指出“两个奇整数乘积为奇”的假设、结论、论域,为何 3 与 5 不是完整证明?

查看解答

任意整数输入,假设两者奇,结论乘积奇。特定测试只覆盖一对;写成两倍整数加一并展开覆盖全部。

练习 2★★★概念6 分钟

写“四整除整数则为偶数”的逆否,区别逆命题。

查看解答

逆否:非偶整数不能被四整除,与原式等价。逆命题:偶整数能被四整除,在六失败。

练习 3★★★概念6 分钟

列非负整数归纳的组成。只有基础零与后继加二步有什么遗漏?

查看解答

基础 P(0)、任意 k≥0、临时 P(k)、推导 P(k+1)、全自然结论。加二仅覆盖偶数,奇数无起点。

练习 4★★★计算6 分钟

[2,5,2,7] 搜索 3,循环头 i=2 时写前缀、不变式、变式,下一头如何?

查看解答

前缀 [2,5] 无目标、边界合法,不变式真,变式二。当前二非三,下一头 i=3,前缀 [2,5,2],不变式真,变式一。

练习 5★★★proof15 分钟

带整数见证,直接证明两奇整数之和为偶。

查看解答

任意 a=2k+1,b=2l+1,k、l 整数。和为 2(k+l+1)2(k+l+1),两倍整数,故偶。假设供见证,整数封闭供结论。

练习 6★★★proof15 分钟

归纳证明全部 n≥0 的 ∑i=0n−1(2i+1)=n2\sum_{i=0}^{n-1}(2i+1)=n^2。

查看解答

零处空和零。任意 k≥0 假设 k 项和 k2k^2,加下一项 2k+12k+1 得 (k+1)2(k+1)^2。步到直接后继,与基础覆盖全自然。

练习 7★★★proof15 分钟

证明 n≥8 均为 3a+5b3a+5b,a、b 非负,并解释三个基础。

查看解答

基础八、九、十分别 3+5、3+3+3、5+5。n≥11 假设八至 n−1 全成立,n−3≥8 可写 3a+5b,再加三得 3(a+1)+5b3(a+1)+5b。减三到三种余数链,故此步需三个起点。

练习 8★★★application13 分钟

用结构归纳证明拼接长度为两长度之和,明确归纳对象。

查看解答

对首列表 a,b 任意。空基础为长度 b=0+长度 b;头尾步按定义一加尾拼接长度,用尾假设得一加尾长度加 b 长度,即 a 长度加 b 长度。覆盖两构造。

练习 9★★★application13 分钟

固定整数列表求和,i 已处理数量、s 累加器,写不变式、三正确性义务与变式。

查看解答

头部 0≤i≤n0\le i\le n 且 s=∑k=0i−1aks=\sum_{k=0}^{i-1}a_k。初始两零,用空和。步加当前项再增 i,覆盖新前缀。退出 i=n 给完整和。n−i 非负且每继续步减一,在有限访问与算术假设下终止。

练习 10★★★application13 分钟

完整幂集包含序的最小元,分别证明存在与唯一,区别极小。

查看解答

空集属于幂集且包含于全部成员,故存在最小。两个最小互相包含故相等,唯一。极小只排除不同更小成员,不保证与全部比较。

练习 11★★★diagnosis16 分钟

错误奇数和归纳用 n2+1n^2+1,给一致步却无基础。诊断修复。

查看解答

零处空和零而候选一,后继蕴含不能修假基础。改为 n2n^2,证明零基础及练习 6 的步,明确论域与临时假设,不假设下一项。

练习 12★★★diagnosis16 分钟

搜索非匹配后不改变 i,以保空前缀不变式,作者称正确且终止。分开主张并修进展。

查看解答

不变式可能支持实际返回的正确性,却可能永远重复。n−i 不减。非匹配后增 i,证明扩大前缀保持与非负变式减一;成功和正常退出还要分别后置论证。

练习 13★★★proof10 分钟

可选:结构归纳证明满二叉树叶数比内部节点多一。

查看解答

叶 L=1,I=0。两子节点假设各 L=I+1,则总叶 I(A)+I(B)+2I(A)+I(B)+2,内部 1+I(A)+I(B)1+I(A)+I(B),差一。两子前提必要。

练习 14★★★proof15 分钟

可选:严格递减正实数为何不足以终止,与自然数变式比较。

查看解答

1,1/2,1/4,…1,1/2,1/4,\ldots 永远正且递减。非负整数每次严格减至少一,初值限制步数。良基性而非仅递减保证终止。

14

自测题

九道选择自动反馈,书面证明概要自评后供第十分。答案应指出满足与尚未解决的义务。

1
P 蕴含 Q 的反例需要什么?
2
哪个方法证明 P 蕴含 Q 的等价式?
3
至多一个论证还缺什么才唯一存在?
4
归纳假设何时合法?
5
有有效步无基础得到什么?
6
质数乘积存在为何强归纳方便?
7
列表结构归纳需覆盖什么构造?
8
正确证明中不变式单独供什么?
9
哪个是有限搜索的有效终止度量?
查看答案

不变式:0≤i≤n0\le i\le n 且之前位置无目标。零处前缀空;非匹配加一保持;返回匹配 i 无更早匹配;退出 i=n,故全列表无匹配。变式 n−i 非负整数,每继续步减一,匹配立即返回。固定有限列表假设下,结果理由与独立递减度量都完整才得一分。

15

引导阅读

必读二十五分钟:在 MIT Mathematics for Computer Science 链接开放教材中阅读证明方法与归纳介绍,标记假设、基础、归纳假设与目标,比较直接和间接论证。

必读十一分钟:阅读递归数据/结构归纳,关注一种有限结构的构造,列准确基础与步,指出假设应用的较小对象。

必读九分钟:阅读状态机或不变式讨论,指出观察点,分别说明状态性质与进展/终止依据。三选段总计四十五分钟,较长证明可选。

选读:官方 Python assert 文档 说明可执行断言限制。本课证明与图为原创。

16

推理检查点与计数准备

证明遵循逻辑结构:全称取任意输入,存在给见证,唯一比较假设解,分段覆盖情况。归纳覆盖索引链或递归结构;程序正确性的不变式绑定程序点,终止另需良基度量。

综合早期思想的检查点:搜索请求列表第一个满足 admin∨(owner∧approved)admin\lor(owner\land approved) 的条目。用模块 02 翻译谓词,把搜索不变式中的“不等于目标”改为“谓词失败”。证明返回首个合格位置,−1 表示没有合格项。解释括号错误如何改变证明的规格,即使循环本身正确。

结业任务:不看例子完成直接证明、完整归纳及搜索正确性/终止论证。练习六十、实验三十、测验十分。缺基础、循环假设、进展失败都应修正并解释。模块 05 用这些工具证明计数,而非只套公式。

17

记法与双语术语

术语 含义 English
假设 / 结论 前提 / 待证结果 Hypothesis / conclusion
定理 / 引理 / 猜想 已证 / 辅助 / 未证 Theorem / lemma / conjecture
直接 / 逆否 / 反证 推结论 / 反向否定等价 / 推矛盾 Direct / contrapositive / contradiction
存在 / 唯一 有见证 / 存在且至多一 Existence / uniqueness
基础 / 归纳假设 / 步 起始真 / 较早临时假设 / 后继证明 Base / hypothesis / step
强 / 结构归纳 全部较早索引 / 对象构造 Strong / structural induction
良序 自然数非空子集有最小 Well-ordering
不变式 / 变式 状态性质 / 良基进展度量 Invariant / variant
部分 / 完全正确性 终止时正确 / 还会终止 Partial / total correctness