3

I want to use user assertion of value analysis plugin of Frama-C (Neon version), however I have some problem to come up with the suitable model of assume statement, which is very useful for me to apply particular constraints, for example, here is my test code:

#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;
}

I want that the value of selection will be greater than 5 after this assume statement so that the assertion will be valid. My initial attempt was to write this function void assume(int a){ while(!a); return;} , but it was unsuccessful. Please help me, thanks.

  • 1
    Maybe you would be interested in http://blog.frama-c.com/index.php?post/2012/08/03/assume-and-assert , which argues that “assume” and “assert” should both be the same construct (“assert”) in a multi-technique framework such as Frama-C. – Pascal Cuoq Feb 05 '15 at 08:51

1 Answers1

3

The easiest way to constrain selection would be to use an assert (which of course won't be proved by Value). If you want to distinguish between the assert that are in fact hypotheses you make from the assert that you want to verify, you can use ACSL's naming mechanism, such as

//@ assert assumption: selection > 5;

and verify that the only assert that are unknown are the ones named assumption.

Using an assume function cannot work as such, because it will only reduce the possible value of the a parameter to be non-zero. Value is not able to infer the relation between the value of a in assume and the value of selection in main. However, it is possible to help it a little bit. First, -slevel allows to propagate several abstract state in parallel. Second, an assert given in an disjunctive will force Value to split its state (if the -slevel is big enough to do so). Thus, with the following code

#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;
}

and the following command line:

frama-c -cpp-extra-args="-I$(frama-c -print-share-path)" -val -slevel 2

After the first assert (which obviously valid), Frama-C will propagate separately two states: one in which selection > 5 and one in which selection <= 5. In the first case, assume is called with 1 as argument, thus returns immediately, and the then branch of the if is taken, so that the second assert is valid. In the second state, assume is called with 0, and never returns. Thus for all cases where control reaches the second assert, it is valid.

Note that you really need to add the first assert inside the body of main, and to copy in ACSL the argument you pass to assume. Otherwise, the state split won't occur (more precisely, you will split on a, not on selection).

Virgile
  • 9,724
  • 18
  • 42
  • Thank you for your prompt answer. – Trúc Nguyễn Lâm Feb 03 '15 at 19:45
  • Following your answer, is it correct if I model `assume(cond)` as `//@ assert cond || !cond; assume(cond)` for all the assume statements ? ( with `cond` in assert in ACSL and sufficient large`-slevel`). Are there any exceptions? Thanks in advanced. – Trúc Nguyễn Lâm Feb 09 '15 at 14:35
  • 1
    Yes, this should work, provided `cond` is something Value Analysis can handle (i.e. something like `x<=42`, `*p>36`, `p <= &x + 12`, ... the latter possibly leading to an alarm if `p` is too imprecise and can have several base addresses). – Virgile Feb 10 '15 at 12:56