Ich habe Probleme, 2 Schleifeninvarianten zu beweisen:
Schleifeninvariante \forall Integer i; 0 <= i < (\at(n, Pre) - n) ==> ((char*)m2)[i] == \at(((char*)m1)[i], Pre);
Schleifeninvariante \forall Integer i; 0 <= i < (\at(n, Pre) - n) ==> ((char*)m1)[i] == \at(((char*)m2)[i], Pre);
Ich vermute, dass \at für Arrays nicht funktioniert, wie ich es erwarte.
Es gibt eine ähnliche Funktion in ACSL by Example (Seite 68, swap_ranges), die dies verwendet, aber, wie angegeben, konnten sie diese bestimmte Funktion nicht mit dem WP-Plugin beweisen. Ich habe es auf meinem Computer probiert und tatsächlich kann die gleiche Invariante nicht bewiesen werden.
Vollständiger Code
/*
* memswap()
*
* Tauscht die Inhalte zweier nicht überlappender Speicherbereiche.
* Das könnte wirklich schneller gemacht werden...
*/
#include "string.h"
/*@
requires n >= 1;
requires \valid(((char*)m1)+(0..n-1));
requires \valid(((char*)m2)+(0..n-1));
requires \separated(((char*)m1)+(0..n-1), ((char*)m2)+(0..n-1));
assigns ((char*)m1)[0..n-1];
assigns ((char*)m2)[0..n-1];
ensures \forall Integer i; 0 <= i < n ==> ((char*)m1)[i] == \old(((char*)m2)[i]);
ensures \forall Integer i; 0 <= i < n ==> ((char*)m2)[i] == \old(((char*)m1)[i]);
@*/
void memswap(void *m1, void *m2, size_t n)
{
char *p = m1;
char *q = m2;
char tmp;
/*@
loop invariant 0 <= n <= \at(n, Pre);
loop invariant p == m1+(\at(n, Pre) - n);
loop invariant q == m2+(\at(n, Pre) - n);
loop invariant (char*)m1 <= p <= (char*)m1+\at(n, Pre);
loop invariant (char*)m2 <= q <= (char*)m2+\at(n, Pre);
loop invariant \forall Integer i; 0 <= i < (\at(n, Pre) - n) ==> ((char*)m2)[i] == \at(((char*)m1)[i], Pre);
loop invariant \forall Integer i; 0 <= i < (\at(n, Pre) - n) ==> ((char*)m1)[i] == \at(((char*)m2)[i], Pre);
loop assigns n, tmp, ((char*)m1)[0..\at(n,Pre)-1], ((char*)m2)[0..\at(n, Pre)-1], p, q;
loop variant n;
@*/
while (/*n--*/ n) {
tmp = *p;
*p = *q;
*q = tmp;
p++;
q++;
n--; // eingefügter Code
}
}
EDIT
Ich verwende Frama-C Oxygen-Version und habe automatisches Beweisen mit alt-ergo(0.94) und cvc3(2.4.1) versucht
Ausgabe von Frama-C:
cvc3:
[wp] [Cvc3] Goal store_memswap_loop_inv_7_established : Valid
[wp] [Cvc3] Goal store_memswap_loop_inv_6_established : Valid
[wp] [Cvc3] Goal store_memswap_loop_inv_7_preserved : Unbekannt
[wp] [Cvc3] Goal store_memswap_loop_inv_6_preserved : Unbekannt
alt-ergo:
[wp] [Alt-Ergo] Goal store_memswap_loop_inv_7_established : Gültig
[wp] [Alt-Ergo] Goal store_memswap_loop_inv_6_established : Gültig
[wp] [Alt-Ergo] Goal store_memswap_loop_inv_7_preserved : Zeitüberschreitung
[wp] [Alt-Ergo] Goal store_memswap_loop_inv_6_preserved : Zeitüberschreitung