假设FramaC中的语句建模

时间:2015-02-03 17:04:06

标签: frama-c

我想使用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;} ,但没有成功。 请帮助我,谢谢。

1 个答案:

答案 0 :(得分:3)

约束selection的最简单方法是使用assert(这当然不会被价值证明)。如果您想要区分assert实际上是您要验证的assert假设,可以使用ACSL的命名机制,例如

//@ assert assumption: selection > 5;

并验证唯一未知的assert是名为assumption的<{1}}。

使用assume函数无法正常工作,因为它只会将a参数的可能值减少为非零。值无法推断aassume的值与selectionmain的值之间的关系。但是,它可以帮助它一点点。首先,-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)。