了解Frama-C切片器的结果

时间:2013-07-10 13:47:02

标签: slice frama-c

我想知道是否可以使用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)...”但问题仍然是“其他......”

2 个答案:

答案 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语言不允许在后置状态中引用形式变量的值,主要是因为从调用者的角度来看这是没有意义的。 (呼叫终止后会弹出被叫方的堆栈帧。)