Skip to content

循环不变式

Loop invariant

在循环初始化后成立,并在每次循环迭代后继续成立的断言。

条目类型
原则

形式陈述

考虑循环 while B do C,其中 B 是循环条件,C 是循环体。状态断言 I 是循环不变式,指它满足两项义务:

  1. **初始化:**进入第一次条件判断前,I 成立;
  2. **保持:**从任意满足 IB 的状态执行一次 C,若该次执行正常终止,则得到的状态仍满足 I,即
{IB} C {I}.

这两项决定 I 是否为不变式。若要用它证明循环的部分正确性,还必须另行验证它足够强:对目标后置条件 Q

I¬BQ.

因此恒真命题可以是合法的不变式,却通常不足以推出有意义的结果。若要证明总正确性,还需给出良基变式量或其他终止论证,排除循环永远执行的可能。

直觉

循环不变式是每个迭代边界都为真的状态摘要。它把“循环可能执行任意多轮”压缩成一次归纳:先证明起点成立,再证明任意一轮都保持。一个有证明价值的不变式通常同时描述已经处理的部分、尚未处理的部分,以及二者之间仍保持的关系。太弱的不变式虽然为真,却无法在退出时推出目标;太强的断言则可能根本无法初始化或保持。它不是对最终结果的愿望,而是每条循环路径执行后都必须重新建立的事实。

循环不变式三阶段
例子与边界

插入排序外层第 i 轮开始时,可取不变式:“子数组 A[0..i) 已按非降序排列,并且恰好包含输入数组原前 i 个元素。”初始 i=1 时单元素前缀显然满足断言;把 A[i] 插入已排序前缀后,新前缀仍有序且没有增删元素,故不变式保持;退出时 i=n,不变式与退出条件共同说明整个数组有序且是输入的一个排列。另一方面,变式量 ni 每轮严格减少并下界为零,才负责证明循环终止。

“数组最终会有序”不是有效不变式,因为循环中未必成立。只证明保持而忘记终止也不能得到总正确性;若循环可能无限执行,不变式最多证明部分正确性。修改多个变量时必须检查所有会回到循环头的分支,包括 continue;若异常直接离开循环,则应另行证明异常后置条件,只有被循环体捕获并继续迭代的异常路径才必须重建 I

推论与应用

循环不变式用于排序、图遍历、动态规划和数据结构操作的正确性证明。

它是 算法正确性 的基本证明工具,其初始化与保持正是一种 数学归纳法。更一般的归纳不变式把循环头看作状态集合上的切点:初始化对应初始状态纳入集合,保持对应循环回边下封闭;这一区分也解释了为何所有可达状态都满足的真性质,未必已经是可直接归纳证明的不变式。二分搜索的候选区间、图遍历的已访问集合和流算法的可行性都可写成不变式;在程序逻辑中,Hoare 三元组的 while 规则把“初始化、保持、退出推出后置条件”明确拆成独立验证义务,SMT 验证可以求解生成的逻辑条件,却不会替代不变式的语义选择。

高级动态结构常需跨多次公开操作的不变量。去摊还化在迁移期同时维护新旧版本与复制进度;Link–Cut Tree区分 represented forest 和 auxiliary splay,并在 access 后恢复 preferred-path 表示;Buffer Tree允许更新暂存在缓冲区,却保证批量下推后查询语义。它们说明不变量不只写在单个 for 循环顶部,还可覆盖后台队列、延迟工作和多层表示;终止/发布点仍须单独证明。

参考资料
  • Thomas H. Cormen et al., Introduction to Algorithms, 4th ed., MIT Press, 2022, §2.1.
  • C. A. R. Hoare, “An Axiomatic Basis for Computer Programming,” 1969.
关系图谱7 个相邻概念 · 2 类关系

拖动节点调整位置。

显示关系

显示:依赖

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

上位 / 更一般

下位 / 直接特例

暂未标注直接特例。