我想使用Frama-C(Neon版本)的值分析插件的用户断言,但是我有一些问题想出合适的assume
语句模型,对我来说非常有用,可以应用特定的约束,例如,这是我的测试代码:
#include "/usr/local/share/frama-c/builtin.h"
int main(void)
{
int selection = Frama_C_interval(0,10);
int a;
assume(selection > 5);
if (selection > 5)
{
a = 2;
}
else
{
a = 1;
}
//@ assert a == 2;
return 0;
}
我希望在selection
语句之后assume
的值大于5,以便断言有效。
我最初的尝试是写这个功能
void assume(int a){ while(!a); return;}
,但没有成功。
请帮助我,谢谢。
答案 0 :(得分:3)
约束selection
的最简单方法是使用assert
(这当然不会被价值证明)。如果您想要区分assert
实际上是您要验证的assert
假设,可以使用ACSL的命名机制,例如
//@ assert assumption: selection > 5;
并验证唯一未知的assert
是名为assumption
的<{1}}。
使用assume
函数无法正常工作,因为它只会将a
参数的可能值减少为非零。值无法推断a
中assume
的值与selection
中main
的值之间的关系。但是,它可以帮助它一点点。首先,-slevel
允许并行传播几个抽象状态。其次,在析取中给出的assert
将强制Value分裂其状态(如果-slevel
足够大则可以这样做)。因此,使用以下代码
#include "builtin.h"
void assume(int a) { while(!a); return; }
int main(void)
{
int selection = Frama_C_interval(0,10);
int a;
/*@ assert selection > 5 || selection <= 5; */
assume(selection > 5);
if (selection > 5)
{
a = 2;
}
else
{
a = 1;
}
//@ assert a == 2;
return 0;
}
和以下命令行:
frama-c -cpp-extra-args="-I$(frama-c -print-share-path)" -val -slevel 2
在第一个assert
(显然有效)之后,Frama-C将分别传播两个状态:一个状态selection > 5
,另一个状态selection <= 5
。在第一种情况下,使用assume
作为参数调用1
,因此立即返回,并且then
的{{1}}分支被采用,因此第二个{{1} }} 已验证。在第二个状态中,使用if
调用assert
,并且永远不会返回。因此,对于控制到达第二个assume
的所有情况,它都是有效的。
请注意,您确实需要在0
的正文中添加第一个assert
,并在ACSL中复制传递给assert
的参数。否则,状态分裂不会发生(更确切地说,您将分开main
,而不是assume
)。