2

I tried to prove a example from frama-c-wp-tutorial That example is at Sect.6.2.4, but I modified some code.

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define size    150
/*@
    axiomatic Counter{
        logic integer counter{L}(bool arr[size], integer begin, integer end) reads arr[0 .. (size-1)];
        
        axiom count_empty_range{L}:
            \forall bool arr[size], integer begin, integer end;
                begin<0 || begin>=end || end>size
                    ==> counter{L}(arr, begin, end) == 0;
                    
        axiom count_others{L}:
            \forall bool arr[size], integer begin, integer end;
                0 <= begin < end <= size && arr[end-1] != true
                    ==> counter{L}(arr, begin, end) == counter{L}(arr, begin, end-1);
        
        axiom count_true{L}:
            \forall bool arr[size], integer begin, integer end;
                0 <= begin < end <= size && arr[end-1] == true
                    ==> counter{L}(arr, begin, end) == counter{L}(arr, begin, end-1) + 1;
    }
    
    lemma counter_range{L}:
        \forall bool arr[size], integer begin, integer end;
            0 <= begin < end <= size
                ==> 0 <= counter(arr, begin, end) <= end-begin;
*/

The result was obtained with Frama-c 25.0, Alt-Ergo 2.4.2, cvc4 1.8 and Z3 4.8.6.

$ frama-c -wp -wp-rte -wp-prover alt-ergo,cvc4,z3 test.c
[kernel] Parsing test.c (with preprocessing)
[wp] 1 goal scheduled
[wp] [Failed] Goal typed_lemma_counter_range
  Z3 4.8.6: Timeout (10s) (cached)
  CVC4 1.8: Timeout (10s) (cached)
  Alt-Ergo 2.4.2: Timeout (10s) (cached)
[wp] [Cache] found:3
[wp] Proved goals:    0 / 1
  Alt-Ergo 2.4.2:    0  (interrupted: 1) (cached: 1)
  CVC4 1.8:          0  (interrupted: 1) (cached: 1)
  Z3 4.8.6:          0  (interrupted: 1) (cached: 1)

The thing that I can't understand is it will be proved successfully if I change the size into 14 (or even less).Is there anything wrong?

蔡登瑞
  • 47
  • 4

2 Answers2

2

The thing is that SMT solvers usually cannot performa reasoning by induction. So in the most general case, this proof is beyond what they can do. However, when you force a really small size (for example in your case 14), they can exhaustively unfold the definition axiomatic definition in the limit of the timeout. This is not really an efficient proof, but it works.

This is why the tutorial indicates that in the (presented) general case, the lemma cannot be proved automatically using SMT solvers. However, one thing that has changed since the release of the tutorial is that there is now a tactic called Induction in the interactive theorem prover of WP. So Coq is not necessary anymore to finish the proof.

On the failed goal, select the end_0 term, then select the Induction tactical and set the base parameter to begin_0, and start the tactical:

enter image description here

It generates three cases:

enter image description here

  • end_0 == begin_0 (trivial by the axiom empty)
  • end_0 < begin_0 (+ induction hypothesis) (trivial)
  • end_0 > begin_0 (+ induction hypothesis) proved thanks to the other axioms.

The script can then be saved for future proof replay using the prover script on the command line.

Ksass'Peuk
  • 538
  • 2
  • 12
2

I suspect that with a smaller size the provers are able to exhaustively unfold all possible instantiations of the axioms count_others and count_true until they can apply count_empty_range, while this becomes of course impossible for a larger value.

In fact, what you want to do is a proof by induction, something first order automated solvers can't really do. Fortunately, there's a tactic dedicated to that in WP's interactive prover in Frama-C's GUI (see WP manual, section 2.2). Namely, while editing the script corresponding to the proof of the lemma, you can select the end_0 variable, and then the induction tactic:

script editing panel with induction tactic

(NB: the list of tactics on the right side of the panel depends on the context, hence you won't see the induction tactic until you select an integer variable).

Launching the tactic should complete the proof. You can then save the script and replay it later with frama-c -wp -wp-rte -wp-prover script,alt-ergo,z3,cvc4 test.c

Virgile
  • 9,724
  • 18
  • 42