Skip to content

定义Definition

算法正确性

Algorithm correctness · Partial and total correctness

所有合法执行都符合规格,并在完全正确时保证终止。

形式陈述 ​

设 P 是初始状态的前置条件,C 是程序,Q 是可同时提及初始和终止状态的关系式规格。以 ⟨C,σ⟩⇓σ′ 表示一次从 σ 到 σ′ 的终止执行。部分正确性定义为

∀σ,σ′.P(σ)∧⟨C,σ⟩⇓σ′⇒Q(σ,σ′).

对非确定程序,这里量化所有终止执行,而不是仅某条成功路径。完全正确性还要求每个满足 P 的初始状态下,所有允许执行都终止并满足 Q。确定函数式算法是只产生一个结果的特例。Hoare 三元组的前后置条件是当前状态的一元谓词。要表示这里的关系式 Q,先用不可变逻辑变量或 ghost 快照 σ0 保存初态,再对每个固定 σ0 写成 {P(σ)∧σ=σ0}C{Q(σ0,σ)};断言里的 σ 始终指当前状态,程序不能修改 σ0。这样终态断言就是以初态快照为参数的一元谓词。完全正确性还需独立的终止证明。

正确性永远相对于已经写明的规格。离散算法常能直接断言输出值;数值算法还要指定误差度量、算术模型和停止条件,学习算法则须把“按样本正确求解目标”与对未知分布的统计保证分开。它们只是扩展了 Q 所表达的内容或概率量词,并不改变部分正确性与终止性必须分别证明这一基本结构。

直觉

测试只观察有限多次执行,规格中的量词却覆盖全部合法执行。循环不变量把这个无限要求拆成三个局部检查:进入循环前成立;假定某轮开始时成立,执行一轮后仍成立;退出时,不变量与退出条件一起推出后置条件。第二步以一轮为归纳步,把任意有限轮的状态连接起来。

这些检查仍没有说明循环一定退出。终止性还要找到一个落在良基集合中的变体,例如非负整数,并证明每轮严格下降。仅有“数值越来越小”不够:正实数序列 1,1/2,1/4,… 可以无限下降。因此,不变量与递减量分别承担结果正确和执行终止的证明。

部分正确性与终止性
例子与边界

二分查找怎样分别证明答案与终止 ​

设输入数组非降序排列,搜索值为 v。二分查找从 l=0,r=n 开始,保持 0≤l≤r≤n,并保持“若数组含有 v,则当前区间 [l,r) 至少含有一次出现”。当 l<r,令 m=l+⌊(r−l)/2⌋。若 A[m]=v 就返回 m;若 A[m]<v,有序性说明所有下标不超过 m 的值都太小,故更新 l=m+1;否则更新 r=m。每次删去的部分都不含目标,因此不变量得以保持。

退出时 l=r,候选区间为空,不变量便证明目标不存在。另一方面,循环开始时的整数 r−l>0,两种更新都让它严格下降,且始终非负,因此只能执行有限轮。这分别完成部分正确性与终止性。

例如在 [2,5,9] 中查找 7,区间依次为 [0,3)、[2,3)、[2,2),最后报告不存在。若在小于目标的分支错写 l = m,当区间只含一个小于目标的元素时会原地不动;被排除区域的论证仍可能成立,终止义务却已失败。

while true do skip 没有终止执行,因而对任意 P,Q 都真空地满足部分正确性,只要 P 允许至少一个初始状态,就不满足完全正确性。

规格审查还要确认 Q 是否表达了实际需求:程序证明保证执行符合 Q,需求审查保证这个目标本身合适。

对任意程序自动判定终止性是不可能的,这是停机问题的直接边界。

推论与应用

循环不变式与 最弱前置条件把结果证明分解为可检查的局部义务,良基关系上的递减量负责终止。模型检查若发现失败,可用反例轨迹见证某条允许执行违反规格;若给出证明证书,检查器则验证证书是否满足相应证明规则。证书算法把这种分工落实为求解器与独立检查器:接受一份证书能确认当前答案,却不能代替求解器对所有输入的终止证明。

当算法允许近似、随机错误或在线交互时,必须把扩展保证写进规格:近似算法说明允许的数值偏差,随机算法说明坏事件及其概率,在线算法固定输入揭示方式和比较对象。运行时间、空间与通信量描述计算成本,与输出规格一起构成算法的完整保证。非确定程序仍需覆盖所有允许执行;并发程序往往把完整调用—返回历史而非单个终态作为规格对象。

参考资料
  • Thomas H. Cormen et al., Introduction to Algorithms, 4th ed., MIT Press, 2022, §2.1–2.2.
  • Edsger W. Dijkstra, A Discipline of Programming, Prentice Hall, 1976, Chapter 4.
  • Cornell University,CS 2112,Loop invariants,2015:初始化、保持、退出条件与二分查找证明。
关系图谱76 个相邻概念 · 2 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系