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

Frama-C使用ensures注解证明while循环后置条件失败问题

问题根源

Frama-C的WP插件验证循环逻辑时,所有循环退出后成立的程序属性,都必须明确写在循环不变式中。WP不会自动推导循环内部的执行效果,只会检查你提供的不变式是否在循环入口成立、是否每次循环迭代后都保持成立,再结合循环退出条件(这里是count == 0)推导循环后的状态。

你当前写的循环不变式只约束了count的取值范围,完全没有提到x的取值规则。WP分析到循环结束位置时,对x的值没有任何有效约束,自然无法证明后置条件里的x == 5。
你把x=5移到循环外可以验证通过,是因为循环外的赋值属于直线控制流,WP可以直接追踪赋值效果,不需要依赖循环不变式传递状态。

修复方案

在循环不变式中补充x的取值约束即可。结合你的代码逻辑:只要执行过至少一次循环体,x就会被赋值为5;而循环初始count=3,必然会进入循环体执行,因此新增一条对应不变式:

/*@
loop invariant 0 <= count <= \at(count, Pre);
loop invariant count < \at(count, Pre) ==> x == 5; // 新增约束
loop assigns accept,x,count; 
loop variant count;
*/

这条不变式的逻辑完全匹配代码执行流程:

  1. 首次进入循环、还未执行循环体时,count等于初始值3,count < \at(count, Pre)不成立,蕴含式自动为真,满足不变式初始成立要求
  2. 每执行完一次循环体,count比初始值小,此时x已经被赋值为5,蕴含式保持成立
  3. 循环退出时count=0,必然小于初始值3,因此可以直接推导出x == 5,WP会用这个结论完成后置条件的证明
验证操作

修改完代码后,重新执行你原来的验证命令frama-c-gui -wp -rte testp4.c,即可看到后置条件、所有循环标注均显示为Valid状态。

补充提示:你定义的函数名abs和C标准库内置的绝对值函数重名,当前代码因为没有引入<stdlib.h>不会触发冲突,但编写正式验证代码时建议避开标准库函数名,减少不必要的干扰。

内容的提问来源于stack exchange,提问作者Uğur B

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 00:36:28