How to make frama-c -wp
verify the example from the wp manual - a trivial swap
function (swap.c):
/* @ requires \valid(a) && \valid(b);
@ ensures A: *a == \old(*b);
@ ensures B: *b == \old(*a);
@ assigns *a,*b;
@*/
void swap(int * a, int * b);
void swap(int * a, int * b) {
int tmp = * a;
*a = *b;
*b = tmp;
return ;
}
The invocation
$ frama-c -wp -wp-rte swap.c
gives:
[kernel] Parsing FRAMAC_SHARE/libc/__fc_builtin_for_normalization.i (no preprocessing)
[kernel] Parsing swap.c (with preprocessing)
[wp] Running WP plugin...
[wp] Collecting axiomatic usage
[rte] annotating function swap
[wp] 4 goals scheduled
[wp] [Alt-Ergo] Goal typed_swap_assert_rte_mem_access_4 : Unknown (174ms)
[wp] [Alt-Ergo] Goal typed_swap_assert_rte_mem_access_2 : Unknown (160ms)
[wp] [Alt-Ergo] Goal typed_swap_assert_rte_mem_access : Unknown (154ms)
[wp] [Alt-Ergo] Goal typed_swap_assert_rte_mem_access_3 : Unknown (220ms)
[wp] Proved goals: 0 / 4
Alt-Ergo: 0 (unknown: 4)
I wonder why
cvc3
, gappa
, simplify
, verit
, yices
, z3
) was not able to discard any of these 4 proof obligations? I use the latest OPAM installation:
frama-c
: Sodium-20150201alt-ergo
: 0.95.2 (from ubuntu 14.04 main repository package alt-ergo
)why3
: 0.86.1An example of proof obligations, passed to alt-ergo
by wp
:
goal swap_assert_rte_mem_access:
forall t : int farray.
forall a_1,a : addr.
linked(t) ->
(region(a.base) <= 0) ->
(region(a_1.base) <= 0) ->
valid_rd(t, a, 1)
You made a mistake when you copied the specification of swap
from the WP manual. (The next version will use a font that permits copy-pasting.) There must be no space between the beginning of the C comment and the @
in the ACSL specifications; otherwise the comment is interpreted as a simple comment. Thus, you are effectively trying to prove
void swap(int * a, int * b);
void swap(int * a, int * b) {
int tmp = * a;
*a = *b;
*b = tmp;
return ;
}
which is course impossible because a
and b
may not be valid pointers.
The correct specification is
/*@ requires \valid(a) && \valid(b);
@ ensures A: *a == \old(*b);
@ ensures B: *b == \old(*a);
@ assigns *a,*b;
@*/
void swap(int * a, int * b);
When using Frama-C on small examples, you should probably be using the GUI interface (frama-c-gui
). This way, you will see your source code after normalization, what RTE have been added, etc.