- 144 Views
- Uploaded on

Download Presentation
## Automatic verification of summations

**An Image/Link below is provided (as is) to download presentation**

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript

### Automatic verification of summations

K. Rustan M. Leino

IFIP WG 2.3 meeting 46Sydney, Australia11 January 2007

Goal: prove the following program

{ 0 ≤ N }s := 0; n := 0;while n < Ninvariant 0 ≤ n ≤ N s = (Σi | 0 ≤ i < n :: a[i])do s := s + a[n]; n := n + 1end{ s = (Σi | 0 ≤ i < N :: a[i]) }

… automatically, using a VC generator and an SMT solver

Need feedback on

- Related work
- More clever encoding
- Some completeness argument/thoughts
- Decision procedure to fit into an SMT solver
- More examples
- useful ones
- contrived ones

Arrays

- x := a[i] is treated as x := select(a, i)
- a[i] := x is treated as a := store(a, i, x)
- wp(a[i] := 5; assert a[k] = 12, true )=wp(a[i] := 5, select(a, k) = 12 )=select(store(a, i, 5), k) = 12

Assignment-free form

- a[i] := 5; assert a[k] = 12is rewritten into:
- assume a1 = store(a0, i, 5);assert select(a1, k) = 12whose wpis:
- a1 = store(a0, i, 5) select(a1, k) = 12

Example

wp( havoc b;assume (n :: n ≠ i b[n] = a[n]) b[i] = 5; a := b;assert a[k] = 12, true ) = (n :: n ≠ i b1[n] = a0[n]) b1[i] = 5 a2 = b1 select(a2, k) = 12

Term sets

- All equalities and congruences are represented explicitly, but other derived facts may not be
- Examples:
- given: x ≤ y, y ≤ x also represents: x = y
- given: x ≤ y, y ≤ z may not represent: x ≤ z
- given: x = 3, y = x+1 may not represent: y = 4

Quantifiers

- Instantiation via e-graph matching
- A matching pattern (trigger) is a set of terms that together mention all the bound variables, and none of which is just a bound variable by itself
- Examples:
- (x :: { f(x) } 0 ≤ f(x))
- (x,y :: { g(x,y) } f(x) < g(x,y))

More examples

- (x,y :: { f(x), f(y) } x ≤ y f(x) ≤ f(y))
- (x :: { f(x) } x ≠ null f(x) ≤ f(next(x)))
- (x :: { f(next(x)) } x ≠ null f(x) ≤ f(next(x)))
- (x :: { f(x+1) } f(x) ≤ f(x+1))
- (x,y,z :: { x*(y+z) } x*(y+z) = x*y + x*z)
- (x,y :: { P(x,y) } x = y P(x,y) = 10)
- (x :: { P(x,x) } P(x,x) = 10)

sum0 (rendered in BoogiePL)

var a: [int]int; // map from int to int

procedure Sum(N: int) returns (s: int)

requires 0 <= N;

ensures s == qsum(0, N, a);

{

var n: int;

entry:

n := 0;

s := 0;

goto Head;

Head:

assert 0 <= n && n <= N && s == qsum(0, n, a); // loop invariant

goto Body, Done;

Body:

assume n < N; // loop guard

s := s + a[n];

n := n + 1;

goto Head;

Done:

assume !(n < N); // negation of loop guard

return;

}

functionqsum(lo: int, hi: int, A: [int]int) returns (int);

axiom (forall lo: int, hi: int, A: [int]int ::

{ qsum(lo, hi, A) }

hi <= lo ==> qsum(lo, hi, A) == 0);

axiom (forall lo: int, hi: int, A: [int]int ::

{ qsum(lo, hi+1, A) }

lo <= hi ==> qsum(lo, hi+1, A) == qsum(lo, hi, A) + A[hi]);

This program (and the ones on the following slides) verifies with Boogie, using Simplify as the underlying SMT solver

sum1

var a: [int]int;

procedure Sum(N: int) returns (s: int)

requires 0 <= N;

modifies a;

ensures s == qsum(0, N, old(a));

{

var n: int;

entry:

n := 0;

s := 0;

goto Head;

Head:

assert 0 <= n && n <= N && s == qsum(0, n, a); // loop invariant

assert (foralli: int :: 0 <= i && i < N ==> a[i] == old(a)[i]);

goto Body, Done;

Body:

assume n < N; // loop guard

s := s + a[n];

a[-2] := s; // assignment outside a[0,..N]

n := n + 1;

goto Head;

Done:

assume !(n < N); // negation of loop guard

return;

}

functionqsum(lo: int, hi: int, A: [int]int) returns (int);

axiom (forall lo: int, hi: int, A: [int]int ::

{ qsum(lo, hi, A) }

hi <= lo ==> qsum(lo, hi, A) == 0);

axiom (forall lo: int, hi: int, A: [int]int ::

{ qsum(lo, hi+1, A) }

lo <= hi ==> qsum(lo, hi+1, A) == qsum(lo, hi, A) + A[hi]);

axiom (forall lo: int, hi: int, A: [int]int, B: [int]int ::

{ qsum(lo, hi, A), qsum(lo, hi, B) }

(forall j: int :: lo <= j && j < hi ==> A[j] == B[j])

==>

qsum(lo, hi, A) == qsum(lo, hi, B));

inc.bpl

var a: [int]int;

procedure Inc(j: int, N: int, x: int)

requires 0 <= j && j < N;

modifies a;

ensuresqsum(0, N, a) == old(qsum(0, N, a)) + x;

{

entry:

a[j] := a[j] + x;

return;

}

functionqsum(lo: int, hi: int, A: [int]int) returns (int);

axiom (forall lo: int, hi: int, A: [int]int ::

{ qsum(lo, hi, A) }

hi <= lo ==> qsum(lo, hi, A) == 0);

axiom (forall lo: int, hi: int, A: [int]int ::

{ qsum(lo, hi+1, A) }

lo <= hi ==> qsum(lo, hi+1, A) == qsum(lo, hi, A) + A[hi]);

axiom (forall lo: int, hi: int, A: [int]int, B: [int]int ::

{ qsum(lo, hi, A), qsum(lo, hi, B) }

(forall j: int :: lo <= j && j < hi ==> A[j] == B[j])

==>

qsum(lo, hi, A) == qsum(lo, hi, B));

axiom (forall lo: int, hi: int, k: int, A: [int]int, B: [int]int ::

{ qsum(lo, hi, A), qsum(lo, hi, B), A[k] }

(forall j: int :: lo <= j && j < k ==> A[j] == B[j]) &&

(forall j: int :: k < j && j < hi ==> A[j] == B[j])

==>

qsum(lo, hi, A) - A[k] == qsum(lo, hi, B) - B[k]);

swap.bpl

var a: [int]int;

procedure Swap(i: int, j: int, N: int)

requires 0 <= i && i < N;

requires 0 <= j && j < N;

modifies a;

ensuresqsum(0, N, a) == old(qsum(0, N, a));

{

vartmp: int;

entry:

tmp := a[i];

a[i] := a[j];

assertqsum(0, N, a) == qsum(0, N, a);

a[j] := tmp;

return;

}

functionqsum(lo: int, hi: int, A: [int]int) returns (int);

axiom (forall lo: int, hi: int, A: [int]int ::

{ qsum(lo, hi, A) }

hi <= lo ==> qsum(lo, hi, A) == 0);

axiom (forall lo: int, hi: int, A: [int]int ::

{ qsum(lo, hi+1, A) }

lo <= hi ==> qsum(lo, hi+1, A) == qsum(lo, hi, A) + A[hi]);

axiom (forall lo: int, hi: int, A: [int]int, B: [int]int ::

{ qsum(lo, hi, A), qsum(lo, hi, B) }

(forall j: int :: lo <= j && j < hi ==> A[j] == B[j])

==>

qsum(lo, hi, A) == qsum(lo, hi, B));

axiom (forall lo: int, hi: int, k: int, A: [int]int, B: [int]int ::

{ qsum(lo, hi, A), qsum(lo, hi, B), A[k] }

(forall j: int :: lo <= j && j < k ==> A[j] == B[j]) &&

(forall j: int :: k < j && j < hi ==> A[j] == B[j])

==>

qsum(lo, hi, A) - A[k] == qsum(lo, hi, B) - B[k]);

Download Presentation

Connecting to Server..