我想知道是否可以使用Frama-C进行某种前向条件切片,我正在玩一些例子来了解如何实现这一点。
我有这个简单的例子,这似乎导致了一个不精确的切片,我无法理解为什么。这是我要切片的功能:
int f(int a){
int x;
if(a == 0)
x = 0;
else if(a != 0)
x = 1;
return x;
}
如果我使用此规范:
/*@ requires a == 0;
@ ensures \old(a) == a;
@ ensures \result == 0;
*/
然后Frama-C返回以下切片(这是精确的),使用“f -slice-return”标准,f作为入口点:
/*@ ensures \result ≡ 0; */
int f(void){
int x;
x = 0;
return x;
}
但使用此规范时:
/*@ requires a != 0;
@ ensures \old(a) == a;
@ ensures \result == 1;
*/
然后所有指令(& annotations)都保留(当我等待返回此切片时:
/*@ ensures \result ≡ 1; */
int f(void){
int x;
x = 1;
return x;
}
)
在最后一种情况下,切片不精确吗?在这种情况下,可能是什么原因?
此致
罗曼
编辑:我写了“else if(a!= 0)...”但问题仍然是“其他......”
答案 0 :(得分:4)
在Frama-C中,切片插件依赖于称为值分析的初步静态分析插件的结果。
此值分析可以表示变量a
的值a == 0
(在这种情况下,值的集合{ 0 }
),但很难表示{{a
的值1}}当知道a != 0
时。在后一种情况下,如果尚未知道a
是正数还是负数,则值分析插件需要近似a
的值集。如果已知a
为正数,例如,如果它是unsigned int
,则非零值可以表示为间隔,但值分析插件不能表示“类型{的所有值{1}}除了0“。
如果您愿意更改前置条件,可以使用值分析插件更容易理解的形式(以及值分析选项int
)来编写它:
-slevel
答案 1 :(得分:2)
这与您的主要问题无关,但您的ensures a == \old(a)
条款没有达到预期效果。如果您使用选项-print
精确打印源代码,您会看到它已被静默转换为ensures \old(a) == \old(a)
。
ACSL语言不允许在后置状态中引用形式变量的值,主要是因为从调用者的角度来看这是没有意义的。 (呼叫终止后会弹出被叫方的堆栈帧。)