“设并行程序为 $S 1\parallel\cdots\parallel S n$。Owicki–Gries 方法先为每个 $S i$ 构造局部正确的顺序 proof outline:入口断言…”
形式陈述 ​
考虑命令 while B do C。若断言
则可在部分正确性语义下推出
中间的 Hoare 三元组 要求每次循环体若终止,都会在下一次判断 guard 前重新建立
可靠性证明按实际执行的迭代次数归纳。零轮执行时,初态满足
直觉
循环可以跑一百万轮,但证明不必抄写一百万次状态变换。循环不变式是每次回到同一控制点时仍成立的摘要;保持义务把所有可能的一轮压缩成一个通用步骤。它像在螺旋楼梯每层同一位置设置检查门:只要入口过关,而且从一扇门走到下一扇门总能恢复同一条件,就能覆盖任意有限层数。
有证明价值的不变式通常同时记录已处理部分、未处理部分与守恒量。恒真式容易初始化和保持,却往往无法在退出时推出任何有用结论;把最终后置原样当不变式又常常太强,在第一轮之前便不成立。规则把“是真的”和“足够强”分成可定位的义务。
不变式中的每个合取项承担不同角色。一个合取项可能负责防止数组越界,另一个记录结果的代数含义;保持证明要恢复全部合取,退出证明却可能只使用其中一部分。删除“看似辅助”的界限条件,有时仍能通过代数保持,却使退出状态无法被收紧到目标。
例子与边界
在数学整数上计算前
i := 0
s := 0
while i < n do
i := i + 1
s := s + i
前置为
初始化后
退出时
若只保留 s:=s+i、再 i:=i+1,新值满足
不变式只要求在循环头成立;两条赋值之间代数关系可以暂时失效。带 continue 的程序必须在每条回边恢复 break 和异常则需要各自的退出后置。若把更新写成 i := i,三项部分正确性义务仍可能成立,但循环在
推论与应用
循环规则把无限展开变成初始化、保持和退出三类 验证条件,因此是自动验证器处理用户注解的核心接口。求解器能够检查给定不变式,却不会自动保证候选足够强;抽象解释、插值和模板合成产生的候选仍须回到这三项语义义务接受检验。
若要总正确性,还需在
嵌套循环可以在内层使用依赖外层索引的不变式,再在外层把内层完整规格当作一条命令使用。直接把两个循环的所有控制点揉成一个巨型断言并非更强;分层规则能让每个不变式只承担自己循环头的事实,同时通过顺序规则传递中间后置。
参考资料
- C. A. R. Hoare, “An Axiomatic Basis for Computer Programming,” Communications of the ACM 12(10), 1969, pp. 576–580, 583。
- Robert W. Floyd, “Assigning Meanings to Programs,” in Mathematical Aspects of Computer Science, AMS, 1967, pp. 19–32。
- Glynn Winskel, The Formal Semantics of Programming Languages, MIT Press, 1993, Ch. 7。
- Krzysztof R. Apt, Frank S. de Boer, and Ernst-Rüdiger Olderog, Verification of Sequential and Concurrent Programs, 3rd ed., Springer, 2009, Chs. 3–4。