predicate abstraction for software verification n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Predicate Abstraction for Software Verification PowerPoint Presentation
Download Presentation
Predicate Abstraction for Software Verification

Loading in 2 Seconds...

play fullscreen
1 / 38

Predicate Abstraction for Software Verification - PowerPoint PPT Presentation


  • 111 Views
  • Uploaded on

Predicate Abstraction for Software Verification. Shaz Qadeer Compaq Systems Research Center (joint work with Cormac Flanagan). Systems software. OS components file system, buffer cache manager Abstract from low-level to high-level operations tedious low-level programming detail

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Predicate Abstraction for Software Verification' - manon


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
predicate abstraction for software verification

Predicate Abstraction for Software Verification

Shaz Qadeer

Compaq Systems Research Center

(joint work with Cormac Flanagan)

systems software
Systems software
  • OS components
    • file system, buffer cache manager
  • Abstract from low-level to high-level operations
    • tedious low-level programming detail
  • Expected to work
    • with multiple concurrent clients
    • in the presence of crashes
outline
Outline
  • Background
    • verification condition
    • strongest postcondition
    • loop invariants
  • Inferring loop invariants
    • predicate abstraction
    • universally-quantified invariants
  • Frangipani
  • Related work
verification condition
Verification condition

x := a;

if (x < b) {

x := b;

}

assert x = max(a,b);

Program P

Check for validity:

sp(P,true)  x  a  x  b

guarded command language dijkstra 76
Guarded command language (Dijkstra 76)

Statement S

x := e

A ; B

assume e

A  B

while {I} e do B end

Variables have arbitrary values in program’s initial state

if e then A else B end

 (assume e ; A)

 (assumee ; B)

strongest postcondition semantics
Strongest postcondition semantics

sp(S,Q)

y.(Q[xy]  x=e[xy])

sp(B,sp(A,Q))

e  Q

sp(A,Q)  sp(B,Q)

Statement S

x := e

A ; B

assume e

A  B

Denote sp(S, true) by sp(S)

checking loop invariants
Checking loop invariants
  • Given loop
  • Need to check
    • Invariant holds on entry to loop
      • sp( C )  I
    • Invariant holds at end of every iteration
      • sp( C; H; assume I  e; B)  I

where H = havoc variables modified in B

C;

{I} while e do B end

desugaring loops
Desugaring loops

S = “while {I} e do B end”

H = havoc variables modified in B

desugar(S) =

assert I ; H ; assume I ;

( (assume e ; B; assert I; assume false)

 assume e)

example
Example

assume 0 < a.length;

i := 0;

while (i < a.length) {

a[i] := 0;

i := i + 1;

}

assert a[0] = 0;

{ int j; 0 <= j  j < i a[j] = 0, 0<=i}

translation
Translation

assume 0 < a.length;

i := 0;

assert  int j; 0 <= j  j < i a[j] = 0;

assert 0 <= i;

havoc a[*], i;

assume  int j; 0 <= j  j < i a[j] = 0;

assume 0 <= i;

( assume (i < a.length);

a[i] := 0;

i := i + 1;

assert  int j; 0 <= j  j < i a[j] = 0;

assert 0 <= i;

assume false;)



assume (i < a.length)

assert a[0] = 0;

esc java with loop invariants
ESC/Java with loop invariants

/*@ loop_invariant i >= 0;

loop_invariant 0 <= spot;

loop_invariant spot <= MAXDIRENTRY;

loop_invariant (\forall int j; 0 <= j && j < i &&

bdisk[addr].dirEntries[j].inum != DIRENTRY_UNUSED ==>

bdisk[addr].dirEntries[j].name != name);

loop_invariant (\forall int j; spot == MAXDIRENTRY && 0 <= j && j < i ==>

bdisk[addr].dirEntries[j].inum != DIRENTRY_UNUSED);

loop_invariant spot == MAXDIRENTRY ||

bdisk[addr].dirEntries[spot].inum == DIRENTRY_UNUSED;

loop_invariant (\forall DirEntry t; t != de ==> t.name == \old(t.name));

loop_invariant (\forall DirEntry t; t != de ==> t.inum == \old(t.inum));

loop_invariant (\forall DirEntry t; t.inum == FS.DIRENTRY_UNUSED ||

(0 <= t.inum && t.inum < FS.IMAX));

*/

for (i = 0; i < cwd.inode.length; i++) {

GetDirEntry(de, addr, i);

if (de.inum != DIRENTRY_UNUSED && de.name == name) {

return ERROR;

}

if (de.inum == DIRENTRY_UNUSED && spot == MAXDIRENTRY) {

spot = i;

}

}

outline1
Outline
  • Background
    • verification condition
    • strongest postcondition
    • loop invariants
  • Inferring loop invariants
    • predicate abstraction
    • universally-quantified invariants
  • Frangipani
  • Related work
inferring loop invariants
Inferring loop invariants

C;

{I} while e do B end

  • Could try
    • I0 = sp( C )
    • In+1 = In sp( C; H; assume In e; B)
  • In is an invariant for first n iterations
  • Problem: May not converge
divergence
Divergence

State Space

I0

I1

I2

In

...

...

predicate abstraction
Predicate abstraction
  • Invariant is boolean combination of predicates
  • Split problem into two parts
    • Find a suitable set of predicates
    • Find the boolean combination of these predicates
predicate abstraction contd
Predicate abstraction (contd.)
  • Predicates over program variables
    • a = expr1, b = expr2, c = expr3, d = expr4
  •  : boolean expression over {a,b,c,d}  formula over program variables
  • :formula over program variables  boolean expression over {a, b, c, d}
  • (F) = least boolean function G over {a,b,c,d} such that F  (G)
abstract state space
Abstract state space
  • Predicates {a, b, c, d}
  • They generate an abstract space of size 24 = 16

cd

cd

cd

cd

State Space

ab

(F)

ab

F

ab

ab

inferring loop invariants1
Inferring loop invariants
  • Compute
    • I0=(sp( C ))
    • In+1 =In(sp( C; H; assume E  (In); B))
  • Converges yielding valid loop invariant
    • Best loop invariant for the given predicates
method 1 slow
Method 1 (slow!)
  • Is F  a  b  c  dsatisfiable? No!
  • Can compute (F) by asking 2n such queries

cd

cd

cd

cd

ab

X

X

X

X

(F)

ab

X

X

X

F

ab

X

X

ab

X

X

method 2 das dill park 99

a

Fa

cd

cd

cd

cd

b

Fab

Fab

ab

X

X

X

X

c

(F)

Fabc

ab

X

X

X

F

ab

X

X

ab

X

X

Method 2 (Das-Dill-Park 99)

Order the variables: a < b < c < d

  • O(2n+1) queries
  • Sensitive to ordering
method 3 shankar saidi 99

.

.

Queries of size n: . . .

Number = nCn2n

Method 3 (Shankar-Saidi 99)

Queries of size 1: Fa, F a, Fb, etc.

Number = nC121

Queries of size 2: Fab, Fab, etc.

Number = nC222

  • O(3n) queries
  • No ordering required
new method
New method
  • F  a  c  d? No!
  • F  a  b  c  d? No!
  • F  c  d? No!
  • Removed 1/4 of state space in 3 queries!

cd

cd

cd

cd

ab

X

X

X

X

(F)

=  (c  d)

 (a  c)

 (a  b)

 ( c  d)

ab

X

X

X

F

ab

X

X

ab

X

X

universally quantified loop invariants
Universally-quantified loop invariants

/*@ loop_invariant i >= 0;

loop_invariant 0 <= spot;

loop_invariant spot <= MAXDIRENTRY;

loop_invariant (\forall int j; 0 <= j && j < i &&

bdisk[addr].dirEntries[j].inum != DIRENTRY_UNUSED ==>

bdisk[addr].dirEntries[j].name != name);

loop_invariant (\forall int j; spot == MAXDIRENTRY && 0 <= j && j < i ==>

bdisk[addr].dirEntries[j].inum != DIRENTRY_UNUSED);

loop_invariant spot == MAXDIRENTRY ||

bdisk[addr].dirEntries[spot].inum == DIRENTRY_UNUSED;

loop_invariant (\forall DirEntry t; t != de ==> t.name == \old(t.name));

loop_invariant (\forall DirEntry t; t != de ==> t.inum == \old(t.inum));

loop_invariant (\forall DirEntry t; t.inum == FS.DIRENTRY_UNUSED ||

(0 <= t.inum && t.inum < FS.IMAX));

*/

for (i = 0; i < cwd.inode.length; i++) {

GetDirEntry(de, addr, i);

if (de.inum != DIRENTRY_UNUSED && de.name == name) {

return ERROR;

}

if (de.inum == DIRENTRY_UNUSED && spot == MAXDIRENTRY) {

spot = i;

}

}

inferring quantified loop invariants
Inferring -quantified loop invariants

assume 0 < a.length;

i := 0;

/*@ loop_invariant

0 <= i,

 int j; 0 <= j  j < i a[j] = 0 */

while (i < a.length) {

a[i] := 0;

i := i + 1;

}

assert a[0] = 0;

inferring quantified loop invariants1
Inferring -quantified loop invariants

assume 0 < a.length;

i := 0;

/*@ loop_predicate

0 <= i,

 int j; 0 <= j  j < i a[j] = 0 */

while (i < a.length) {

a[i] := 0;

i := i + 1;

}

assert a[0] = 0;

inferring quantified loop invariants2
Inferring -quantified loop invariants

assume 0 < a.length;

i := 0;

/*@ skolem_constant int j */

/*@ loop_predicate

0 <= i,

0 <= j, j < i, a[j] = 0 */

while (i < a.length) {

a[i] := 0;

i := i + 1;

}

assert a[0] = 0;

inferring quantified loop invariants3

/*@ loop_predicate 0 <= i, 0 <= j, j < i, a[j] = 0 */

I0=(sp(i := 0))

In+1 =In(sp(i := 0;

havoc i, a[*];

assume In i < a.length;

a[i] := 0;

i := i+1))

I0

TFTF

TFTT

TTFF

TTFT

I1

TTTT

Inferring -quantified loop invariants
inferring quantified loop invariants4
Inferring -quantified loop invariants

/*@ loop_predicate 0 <= i, 0 <= j, j < i, a[j] = 0 */

I0

TFTF

TFTT

TTFF

TTFT

I1

TTTT

 0  i

 (0  j)  (j < i)  a[j] = 0

 0  j  j < i

inferring quantified loop invariants5
Inferring -quantified loop invariants

/*@ loop_predicate 0 <= i, 0 <= j, j < i, a[j] = 0 */

I0

TFTF

TFTT

TTFF

TTFT

I1

TTTT

 0  i

  int j; 0  j  j < i  a[j] = 0

  int j; 0  j  j < i

outline2
Outline
  • Background
    • verification condition
    • strongest postcondition
    • loop invariants
  • Inferring loop invariants
    • predicate abstraction
    • universally-quantified invariants
  • Frangipani
  • Related work
frangipani
Frangipani
  • Distributed file system (Thekkath, Mann, Lee 1997)
  • Built on top of Petal virtual disk (Lee, Thekkath 1996)
  • Implements the file abstraction from the virtual disk block abstraction
  • Exports file and directory operations - create, delete, rename etc. - to clients
verification
Verification
  • Loop invariant inference built on top of ESC/Java (Detlefs, Leino, Nelson, Saxe 1998)
  • ESC/Java uses automatic theorem prover Simplify (Nelson 81)
  • Frangipani data structures and “create” modeled abstractly in Java
  • Assume
    • single thread of execution
    • no crashes
slide33

. . .

. . .

. . .

. . .

. . .

. . .

Data structures on disk:

Inode {

int inum;

int addr;

int mode;

int length;

}

ibusy

F

T

F

T

F

F

idisk

addr

addr

bdisk

Block {

int addr;

Entry[] entries;

}

Entry {

String name;

int inum;

}

bbusy

F

T

F

F

T

F

Data structures in memory:

  • vArray contains inodes
  • distinct entries must contain
  • distinct inodes

vArray

vbusy

T

T

F

F

T

F

itov: int  int

slide34

/*@

invariant  int i, j: vbusy[i]  ((vArray[i].inum = j)  (itov[j] = i));

invariant  int i: ibusy[i]  bbusy[idisk[i].addr];

invariant idisk  bdisk;

invariant  int i: idisk[i]  null  idisk[i].inum = i;

.

.

*/

/*@ requires vbusy[num]  vArray[num].mode = DIR */

/*@ ensures \result = ERROR 

there is an entry with name s in directory vArray[num] */

int create(int num, String s) {

.

.

.

}

main loop in create
Main loop in “create”

/*@ loop_invariant i >= 0;

loop_invariant 0 <= spot;

loop_invariant spot <= MAXDIRENTRY;

loop_invariant (\forall int j; 0 <= j && j < i &&

bdisk[addr].dirEntries[j].inum != DIRENTRY_UNUSED ==>

bdisk[addr].dirEntries[j].name != name);

loop_invariant (\forall int j; spot == MAXDIRENTRY && 0 <= j && j < i ==>

bdisk[addr].dirEntries[j].inum != DIRENTRY_UNUSED);

loop_invariant spot == MAXDIRENTRY ||

bdisk[addr].dirEntries[spot].inum == DIRENTRY_UNUSED;

loop_invariant (\forall DirEntry t; t != de ==> t.name == \old(t.name));

loop_invariant (\forall DirEntry t; t != de ==> t.inum == \old(t.inum));

loop_invariant (\forall DirEntry t; t.inum == FS.DIRENTRY_UNUSED ||

(0 <= t.inum && t.inum < FS.IMAX));

*/

for (i = 0; i < cwd.inode.length; i++) {

GetDirEntry(de, addr, i);

if (de.inum != DIRENTRY_UNUSED && de.name == name) {

return ERROR;

}

if (de.inum == DIRENTRY_UNUSED && spot == MAXDIRENTRY) {

spot = i;

}

}

related work
Related work
  • Inferring/computing loop invariants
  • Predicate abstraction
    • Graf-Saidi 97
    • Bensalem-Lakhnech-Owre 98, Colon-Uribe 98
    • Saidi-Shankar 99, Das-Dill-Park 99
    • Ball-Majumdar-Millstein-Rajamani 2001
future work
Future Work
  • Heuristics for generating predicates
  • Multiple threads
    • locks, semaphores, ...
    • thread-modular reasoning
  • Linked lists, reachability
  • Target C