I'm new to ACSL and I tried to replicate the function contract of this copy function provided by "ACSL by Example" from the Fraunhofer Society. The Code below works perfectly and every goal gets proven.
/*@
predicate IsValidRange(uint8_t* a, integer n) =
(0 <= n) && \valid(a+(0.. n-1));
*/
/*@
predicate
IsEqual{A,B}(uint8_t* a, integer n, uint8_t* b) =
\forall integer i; 0 <= i < n ==>
\at(a[i], A) == \at(b[i], B);
*/
/*@
requires IsValidRange(a, n);
requires IsValidRange(b, n);
requires \separated(a+(0..n-1), b+(0..n-1));
assigns b[0..n-1];
ensures IsEqual{Here,Here}(a, n, b);
*/
void copy(const uint8_t *a, uint8_t n, uint8_t *b)
{
uint8_t i = 0;
/*@
loop invariant 0 <= i <= n;
loop invariant IsEqual{Here,Here}(a, i, b);
loop assigns b[0..n-1], i;
loop variant n-i;
*/
while (i < n)
{
b[i] = a[i];
++i;
//@ assert 0 < i <= n;
}
}
I tried to adjust the specifications to fit my slightly different copy function. This one cannot be proven. Am I missing some important assertions that would assist the automatic prover or is my approach fundamentally flawed?
/*@
requires IsValidRange(src, len);
requires IsValidRange(dst, len);
requires len != 0;
requires \separated(src+(0 .. len-1), dst+(0 .. len-1));
assigns dst[0 .. \old(len)-1];
ensures IsEqual{Here,Here}(src, \old(len), dst);
*/
void Copybytes(
uint8_t const *src,
uint8_t *dst,
uint8_t len
)
{
uint8_t temp;
//@ assert 0 != len;
/*@
loop invariant bound: 0 <= len <= \at(len,LoopEntry);
loop invariant equal: IsEqual{Here,Here}(src, \at(len,LoopEntry)-len, dst);
loop assigns dst, src, len, temp;
loop variant len;
*/
do
{
temp = *src;
src++;
*dst = temp;
dst++;
//@ assert 0 < len <= \at(len,LoopEntry);
} while (--len != 0u);
}
This is the wp output I get after running the code:
[wp] 17 goals scheduled
[wp] [Alt-Ergo 2.4.0] Goal typed_Copybytes_ensures : Timeout (Qed:11ms) (10s)
[wp] [Alt-Ergo 2.4.0] Goal typed_Copybytes_loop_invariant_equal_prese
rved : Timeout (Qed:9ms) (10s)
[wp] [Alt-Ergo 2.4.0] Goal typed_Copybytes_assigns_part4 : Timeout (Qed:6ms) (10s) (cached)
[wp] [Alt-Ergo 2.4.0] Goal typed_Copybytes_assert_2 : Timeout (Qed:6ms) (10s)
[wp] [Alt-Ergo 2.4.0] Goal typed_Copybytes_loop_assigns_part2 : Timeout (Qed:7ms) (10s)
[wp] [Cache] found:3, updated:6
[wp] Proved goals: 12 / 17
Qed: 8 (1ms-3ms-7ms)
Alt-Ergo 2.4.0: 4 (16ms-31ms) (86) (interrupted: 5) (cached: 3)