0

I want to create a program which has the following prerequisites: invariant:

y = x ∗ x ∧ z = y ∗ x ∧ x ≤ n

variant:

n − x

Program structure is as follows:

while<cond>
   <invariant specification>
   <body>

How the program should looks like written in frama-c or why3?

EDIT: I modified your program by removing multiplication and adding addition instead. By doing this, I used two loops. I ran my program, but I got warnings. Here is the program:

#include <limits.h>

/*@ requires n < INT_MAX; // avoids overflow in computing z
*/
void f(unsigned long n) {
    unsigned long x = 0, y = 0, z = 0, contor, aux_x, aux_y;
    /*@ loop assigns x, y, z, contor, aux_x, aux_y;
      @ loop invariant y == x * x && z == y * x && x <= n;
      @ loop variant n - x;
      @ */
    while (x < n) {
        x++;
        contor = 1;
        aux_x = 0;
        aux_y = 0;
        /* @ loop assings contor, aux_x, aux_y;
           @ loop invariant 1 <= contor <= x;
           @ loop variant x - contor, x, y;
           @*/
        while (contor <= x) {
            aux_x += x;
            aux_y += y;
            contor++;
        }
        y = aux_x;
        z = aux_y;
    }
}

And thoose are the warnings:

[kernel] Parsing loop.c (with preprocessing)
[rte] annotating function f
[wp] loop.c:20: Warning: Missing assigns clause (assigns 'everything' instead)
[wp] 6 goals scheduled
[wp] [Alt-Ergo 2.4.1] Goal typed_f_loop_assigns_part2 : Timeout (Qed:6ms) (10s) (cached)
[wp] [Alt-Ergo 2.4.1] Goal typed_f_loop_variant_decrease : Timeout (Qed:16ms) (10s) (cached)
[wp] [Alt-Ergo 2.4.1] Goal typed_f_loop_invariant_established : Timeout (Qed:3ms) (10s)
[wp] [Alt-Ergo 2.4.1] Goal typed_f_loop_invariant_preserved : Timeout (Qed:11ms) (10s)
[wp] [Cache] found:2, updated:2
[wp] Proved goals:    2 / 6
  Qed:               2  (7ms)
  Alt-Ergo 2.4.1:    0  (interrupted: 4) (cached: 2)
[wp:pedantic-assigns] loop.c:5: Warning: 
  No 'assigns' specification for function 'f'.
  Callers assumptions might be imprecise.

Can you explain me why I got those nasty warnings even if I specified the invariant and the variant for inner loop?

yontu
  • 37
  • 5

1 Answers1

2

It is quite unclear what you want to achieve, but here is a C program that can be proved with frama-c -wp loop.c and has the appropriate invariant and variant:

/*@ requires n < 2097152; // avoids overflow in computing z
 */
void f(unsigned long n) {
  unsigned long x = 0, y = 0, z = 0;
  /*@ loop invariant y == x * x && z == y * x && x <= n;
      loop assigns x,y,z;
      loop variant n - x;
  */
  while (x < n) {
    x++;
    y = x * x;
    z = y * x;
  }
}

NB: the requires is not the most general one one can write to avoid an overflow while computing z, but it is easier to compute 2^21 than taking the cubic root of 2^64-1.

Virgile
  • 9,724
  • 18
  • 42
  • Thank you so much. That's exactly what I wanted. I made some changes and I got some warning. I edited my post. Can you explain me why I got those warnings even if I specified the invariant and the variant for inner loops? Thank you in advance! – yontu Jan 14 '22 at 09:29
  • 1
    @yontu Generally speaking, on stack overflow, it is better if you start a new question rather than edit the original one, since it concerns a rather different problem. As a quick answer, there are two issues in the code you just posted. First, the inner loop is _not_ annotated: an ACSL annotation must begin with `/*@` (or `//@` for single-line annotations), _without_ a space between the `*` and the `@`. Otherwise, it is considered as a normal comment. Second, there's a typo: `assings` should be `assigns`. If you have other issues, feel free to open a new question. – Virgile Jan 14 '22 at 10:39
  • Thank you, sir. The problem has been fixed. Didn't know that space between /* and @ is required. – yontu Jan 14 '22 at 10:56