“逻辑编程、项重写、定理证明和模式匹配也依赖统一;算法正确性需要同时证明返回替换确为统一子、最一般,并在不可统一时可靠失败。”
形式陈述
设
对非确定程序,这里量化所有终止执行,而不是仅某条成功路径。完全正确性还要求每个满足
正确性永远相对于已经写明的规格。离散算法常能直接断言输出值;数值算法还要指定误差度量、算术模型和停止条件,学习算法则须把“按样本正确求解目标”与对未知分布的统计保证分开。它们只是扩展了
直觉
测试只观察有限多次执行,规格中的量词却覆盖全部合法执行。循环不变量把这个无限要求拆成三个局部检查:进入循环前成立;假定某轮开始时成立,执行一轮后仍成立;退出时,不变量与退出条件一起推出后置条件。第二步以一轮为归纳步,把任意有限轮的状态连接起来。
这些检查仍没有说明循环一定退出。终止性还要找到一个落在良基集合中的变体,例如非负整数,并证明每轮严格下降。仅有“数值越来越小”不够:正实数序列
例子与边界
二分查找怎样分别证明答案与终止
设输入数组非降序排列,搜索值为
退出时
例如在 l = m,当区间只含一个小于目标的元素时会原地不动;被排除区域的论证仍可能成立,终止义务却已失败。
while true do skip 没有终止执行,因而对任意
规格审查还要确认
对任意程序自动判定终止性是不可能的,这是停机问题的直接边界。
推论与应用
循环不变式与 最弱前置条件把结果证明分解为可检查的局部义务,良基关系上的递减量负责终止。模型检查若发现失败,可用反例轨迹见证某条允许执行违反规格;若给出证明证书,检查器则验证证书是否满足相应证明规则。证书算法把这种分工落实为求解器与独立检查器:接受一份证书能确认当前答案,却不能代替求解器对所有输入的终止证明。
当算法允许近似、随机错误或在线交互时,必须把扩展保证写进规格:近似算法说明允许的数值偏差,随机算法说明坏事件及其概率,在线算法固定输入揭示方式和比较对象。运行时间、空间与通信量描述计算成本,与输出规格一起构成算法的完整保证。非确定程序仍需覆盖所有允许执行;并发程序往往把完整调用—返回历史而非单个终态作为规格对象。
参考资料
- 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:初始化、保持、退出条件与二分查找证明。