Frama-C-discuss mailing list archives

This page gathers the archives of the old Frama-C-discuss archives, that was hosted by Inria's gforge before its demise at the end of 2020. To search for mails newer than September 2020, please visit the page of the new mailing list on Renater.


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Frama-c-discuss] Assigns clause on multidimensional arrays, assertion before return vs ensure clause



Hello ?ric,

Le mar. 19 mai 2009 17:08:58 CEST,
JENN Eric <eric.jenn at fr.thalesgroup.com> a ?crit :

> EJN-1: "assigns" clauses
> 
> How do you express an assign clause when the variable is a multi-dimensional array ?

Your formulations are all correct. However, the normalization phase
performed by the jessie plugin is not compatible with multi-dimensional
arrays. This is a known bug (bts #32:
http://bts.frama-c.com/view.php?id=32)

> EJN-2: Ensure clause vs assertion
> In the following example, the post condition PO is discharged automatically whereas the assertion fails. I don't really undestand why.
> 
> int my_var[5];
> 
> /*@
>   requires \valid(my_var);
>   ensures  \forall integer i; (0 <= i <5) ==> my_var[i] == 0;
>  @*/
> void main()
> {
>  int i;
>  /*@ loop invariant 0 <= i <= 5; @*/
>  for ( i = 0; i<5; i++) { my_var[i] = 0; }
>  // The following assertion fails...
>  /*@ assert \forall integer i; (0 <= k < 5) ==> my_var[k] == 0; @*/
> }

I assume that you mean \forall integer k; ? Otherwise, the assertion is
ill-formed. The post-condition is proved because you have the assertion
as hypothesis when trying to prove it (an assertion can be seen as a
logical cut: you have to prove it at the point of program where it
appears, but in exchange, it can be used as an hypothesis for each
subsequent point). If you remove the assertion altogether, the ensures
is not proved anymore.
Now why isn't that proved in the first place? We are just after a loop,
so the first idea should be 'Is the loop invariant strong enough?' In
fact, the invariant does not speak about my_var, so nothing is known
outside of the loop for my_var. We must add something in the invariant:
  loop invariant \forall integer k; 0<=k<i ==> my_var[k] == 0;
seem appropriate.
> 
> If I replace the last  assertion by an explicit  verification of each entry of the array:
> 
> /*@ assert (my_array[0] == 0) && (my_array[1] == 0) ... (my_array[4] == 0); @*/
> 
> then all corresponding proof obligations are discharged.
> 
> If I replace the implies ("==>") by (what I suppose is) its logical equivalent :
>  
> /*@ assert \forall integer z; ( z>=5) || (z < 0) || (my_var[z] == 0); @*/
> 
> then again the proof obligation is discharged.

I'm not sure I'm following you. Even after changing my_array into my_var
(and filling the dots), I can't prove the assertions without the
loop invariant above. Did you use some other annotations?

> 
> EJN-3: On runtime checks
> 
> Have you (or anybody else) ever considered generating runtime checks of pre, post and invariants, in the same way it is done with JML?

I haven't heard of anything in this area yet. For a carefully chosen
subset of ACSL this shouldn't be too hard, though.

Best regards,
-- 
E tutto per oggi, a la prossima volta.
Virgile