1 / 27

Predicate Abstraction for Software Verification

Predicate Abstraction for Software Verification. Cormac Flanagan Shaz Qadeer Compaq Systems Research Center. POPL02 The Continuing Saga of Predicate Abstraction . Extended Static Checking. Statically verify many correctness properties Type systems catch many errors

yama
Download Presentation

Predicate Abstraction for Software Verification

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. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Predicate Abstraction for Software Verification Cormac Flanagan Shaz Qadeer Compaq Systems Research Center

  2. POPL02The Continuing Saga of Predicate Abstraction

  3. Extended Static Checking • Statically verify many correctness properties • Type systems catch many errors • e.g. “Cannot multiply a number and a string” • Would like to catch additional errors • e.g. “Array index out of bounds at line 10” • And verify other correctness properties • assertions • object invariants • lightweight method specifications

  4. Checking loops with ESC/Java /*@ 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; } }

  5. Loop invariants C; while e do B end Set of reachable states at loop head is a loop invariant! C p sp(C, p)

  6. I0 I1 I2 In ... ... Abstract interpretation Cousot-Cousot 77 Ik = (Jk) (Ik) = Jk Predicate abstraction Graf-Saidi 97 Abstract states J0 J1 J2 Jn ... ... Concrete states

  7. Computing loop invariants C; while e do X; Y; end { I0 = (sp(C, true)) } { J0 = ((I0)  e) } { K0 = (sp(X, (J0))) } { L0 = (sp(Y, (K0))) }

  8. { J1 = ((I1)  e) } { K1 = (sp(X, (J1))) } { L1 = (sp(Y, (K1))) } Computing loop invariants C; while e do X; Y; end { I1 = I0  L0 }

  9. Predicate abstraction example /*@ requires a!=null && b!=null && a.length==b.length ensures \result==a.length || b[\result] */ int find(int[] a, boolean[] b) { int spot = a.length; for (int i=0; i < a.length; i++) { if (spot==a.length && a[i] != 0) spot = i; b[i] = (a[i] != 0); } return spot; } Ten predicates: a != null b != null a.length == b.length spot == a.length b[spot] spot < i 0 <= i i < a.length spot = i a[i] != 0

  10. Computing loop invariants C; while e do X; Y; end { I0 = (sp(C, true)) } { L0 = (sp(“X;Y”, (I0)e)) }

  11. Computing loop invariants C; while e do X; Y; end { I1 = I0  L0 } { L1 = (sp(“X;Y”, (I1)e)) }

  12. Predicate abstraction example /*@ requires a!=null && b!=null && a.length==b.length ensures \result==a.length || b[\result] */ int find(int[] a, boolean[] b) { int spot = a.length; for (int i=0; i < a.length; i++) { if (spot==a.length && a[i] != 0) spot = i; b[i] = (a[i] != 0); } return spot; } Seven predicates: a != null b != null a.length == b.length spot == a.length b[spot] spot < i 0 <= i i < a.length spot = i a[i] != 0

  13. H = havoc variables modified in X;Y P0 = “C;H;assume (I0)e;X;Y” Computing loop invariants C; while e do X; Y; end { I0 = (sp(C, true)) } { L0 = (sp(P0, true)) }

  14. Computing loop invariants H = havoc variables modified in X;Y C; while e do X; Y; end { I1 = I0  L0 } P1 = “C;H;assume (I1)e;X;Y” { L1 = (sp(P1, true)) }

  15. Predicate abstraction example /*@ requires a!=null && b!=null && a.length==b.length ensures \result==a.length || b[\result] */ int find(int[] a, boolean[] b) { int spot = a.length; for (int i=0; i < a.length; i++) { if (spot==a.length && a[i] != 0) spot = i; b[i] = (a[i] != 0); } return spot; } Four predicates: a != null b != null a.length == b.length spot == a.length b[spot] spot < i 0 <= i i < a.length spot = i a[i] != 0

  16. Predicate abstraction example /*@ requires a!=null && b!=null && a.length==b.length ensures ( int j; 0<=j && j<\result ==> !b[j]) */ int find(int[] a, boolean[] b) { int spot = a.length; for (int i=0; i < a.length; i++) { if (spot==a.length && a[i] != 0) spot = i; b[i] = (a[i] != 0); } return spot; }

  17. Invariant needed: ( int j; 0<=j && j<i && j<spot ==>!b[j]) First method: add predicate ( int j; 0<=j && j<i && j<spot ==> !b[j]) Better method: add skolem constant int j add predicates 0<=j, j<i, j<spot, !b[j] infer 0<=j && j<i && j<spot ==>!b[j] Magic:  int j; 0<=j && j<i && j<spot ==>!b[j]) -quantified loop invariants

  18. skolem_constant int sc Second set of predicates: 0 <= sc, sc < i, a[sc] != null Heuristics for guessing predicates for (int i = 0; i < a.length; i++) a[i] = null; Loop targets: i, a[*] First set of predicates: i <= \old(i), i >= \old(i) Inferred invariant: i >= 0   int sc; 0 <= sc  sc < i  a[sc] == null

  19. Javafe • front end to ESC/Java • annotated with lightweight specifications • 45KLOC, 2418 routines, 520 loops • no inference  warnings in 326 routines • with inference  warnings in 31 routines • several failing routines had array bound violations • not caught with loop unrolling

  20. Computing abstraction function C; {I?}while e do B end • Compute • I0=(sp(C, true)) • In+1 =In(sp(“C;H;assume (In)e;B”, true)) • Problem: Given F compute (F) • (F) = least boolean function G such that F  (G)

  21. cd cd cd cd State Space ab (F) ab F ab ab Abstract state space • Predicates {a, b, c, d} • They generate an abstract space of size 24 = 16

  22. X X X X  X X   X   X Naïve method (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 (F) ab F ab ab

  23. (F) New method • F  a  c  d? No! • F  c  d? No! • F  a  b  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 =  (c  d)  (a  c)  (a  b)  ( c  d) ab X X X F ab X X ab X X

  24. Other methods • Das-Dill-Park 99 (DDP) • Saidi-Shankar 99 (SS)

  25. Experiments

  26. Experiments (Javafe)

  27. Related work • Inferring/computing loop invariants • German-Wegbreit 75 • Katz-Manna 76 • Suzuki-Ishihata 77 • Predicate abstraction • Graf-Saidi 97 • Bensalem-Lakhnech-Owre 98, Colon-Uribe 98 • Saidi-Shankar 99, Das-Dill-Park 99 • Ball-Majumdar-Millstein-Rajamani 2001 • Henzinger-Jhala-Majumdar-Sutre 2002

More Related