You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不展开循环:将while循环转化为SMT-LIB公式以验证正确性

不展开循环验证该while循环的SMT-LIB转化方案

要完整验证这个while循环的正确性,需要分别证明部分正确性(循环终止时断言成立)和终止性(循环必然会结束),以下是具体的SMT-LIB转化方案:

一、验证部分正确性(循环终止则断言成立)

部分正确性的核心是定义循环不变式——一个在循环全程始终成立的谓词,需满足三个条件:初始状态成立、循环体执行后保持成立、循环终止时可推导出目标断言。

选择合适的循环不变式

针对该循环,选取不变式 I(x) = 0 ≤ x ≤ 10:

  • 初始状态x=0显然满足0 ≤ 0 ≤10;
  • 若当前x满足I(x)且循环条件x≥0 ∧ x<10成立,执行x=x+1后,x的范围变为1 ≤ x ≤10,仍满足I(x);
  • 循环终止时,循环条件x≥0 ∧ x<10不成立,结合I(x)的x≥0可推出x≥10,再结合I(x)的x≤10,必然得到x=10,符合断言要求。

对应的SMT-LIB公式

我们通过断言“部分正确性的否定不可满足”来证明其永真性,代码如下:

; 声明整数变量
(declare-fun x () Int)

; 断言部分正确性的否定,若check-sat返回unsat,则部分正确性成立
(assert (not (and
  ; 1. 初始状态满足不变式
  (implies (= x 0) (and (>= x 0) (<= x 10)))
  ; 2. 循环体执行后不变式保持
  (forall ((x Int))
    (implies (and (and (>= x 0) (<= x 10)) (and (>= x 0) (< x 10)))
             (and (>= (+ x 1) 0) (<= (+ x 1) 10))))
  ; 3. 循环终止时不变式推导出断言
  (forall ((x Int))
    (implies (and (and (>= x 0) (<= x 10)) (not (and (>= x 0) (< x 10))))
             (= x 10))))))

; 检查可满足性
(check-sat)
; 返回unsat则说明部分正确性成立

二、验证终止性(循环必然会结束)

终止性的核心是找到度量函数(映射到良序集,比如自然数),需满足:循环条件成立时函数值为正,每次执行循环体后函数值严格递减。

选择合适的度量函数

针对该循环,选取度量函数 f(x) = 10 - x:

  • 当循环条件x≥0 ∧ x<10成立时,10-x的取值范围是1~10,均为正自然数;
  • 执行循环体x=x+1后,f(x') = 10 - (x+1) = 9 -x,显然f(x') < f(x),严格递减。

由于自然数集是良序集,严格递减的正自然数序列必然会终止,因此循环一定能结束。

对应的SMT-LIB公式

通过断言“终止性条件的否定不可满足”来证明,代码如下:

; 声明整数变量
(declare-fun x () Int)

; 断言终止性条件的否定,若check-sat返回unsat,则终止性成立
(assert (not (forall ((x Int))
  (implies (and (>= x 0) (< x 10))
           (and (>= (- 10 x) 1) ; 循环条件成立时度量函数为正
                (< (- 10 (+ x 1)) (- 10 x))))))) ; 执行循环体后度量函数严格递减

; 检查可满足性
(check-sat)
; 返回unsat则说明终止性成立

三、综合结论

当上述两个SMT查询均返回unsat时,即可证明:该循环必然终止,且终止后断言x==10成立。

内容的提问来源于stack exchange,提问作者newlogic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 14:36:20