1.07k likes | 1.29k Views
Higher-Order Verification With Liquid Types. Ranjit Jhala , UC San Diego (with Pat Rondon , Ming Kawaguchi). Part I. First-Order Verification. Part II. Higher-Order Verification. First-Order Verification. char* rev_copy ( char* a, int n){ i = 0; j = n – 1; b = malloc (n);
E N D
Higher-Order Verification • With Liquid Types RanjitJhala, UC San Diego (with Pat Rondon, Ming Kawaguchi)
Part I • First-Order Verification • Part II • Higher-Order Verification
First-Order Verification char* rev_copy(char* a, int n){ i = 0; j = n – 1; b = malloc(n); while(0<=j){ b[i] = a[j]; i++; j--; } return b; }
Example: Memory Safety char* rev_copy(char* a, int n){ i = 0; j = n – 1; b = malloc(n); while(0<=j){ b[i] = a[j]; i++; j--; } return b; } • Access Within Array Bounds
char* rev_copy(char* a, int n){ i = 0; j = n – 1; b = malloc(n); while(j>=0){ b[i] = a[j]; i++; j--; } return b; } 0: 0: i = 0; j = n–1; 1: while (0<=j){ 2: assert(i<n); i = i+1; j = j–1; } 1: 2: assert(i<n); assert(0<=i && i<n); • Access Within Array Bounds • How to prove assert never fails ?
How to prove asserts? • Invariants [Floyd-Hoare]
Invariant Proves Assert Invariants 0: i = 0; j = n–1; 1: while (0<=j){ 2: assert(i<n); i = i+1; j = j–1; } true • Predicate that is always true • @ Program Location i+j=n-1 i+j=n-1Æ0·j
How to Find Invariants? • How to Prove Asserts?
What are Invariants ? 0: i = 0; j = n–1; 1: while (0<=j){ 2: assert(i<n); i = i+1; j = j–1; } ? ? ?
What are Invariants ? • Let Xi= Invariant @ location i
What are Invariants ? ? X0 0: i = 0; j = n–1; 1: while (0<=j){ 2: assert(i<n); i = i+1; j = j–1; } X1 ? • Properties of X0,X1,X2? X2 ?
What are Invariants ? X0 0: i = 0; j = n–1; 1: while (0<=j){ 2: assert(i<n); i = i+1; j = j–1; } • X0= true • Initial Values Arbitrary
What are Invariants ? 0: i = 0; j = n–1; 1: while (0<=j){ 2: assert(i<n); i = i+1; j = j–1; } true X1 • i=0Æj=n-1 )X1
What are Invariants ? 0: i = 0; j = n–1; 1: while (0<=j){ 2: assert(i<n); i = i+1; j = j–1; } X1 X2 0·jÆX1)X2
What are Invariants ? 0: i = 0; j = n–1; 1: while (0<=j){ 2: assert(i<n); i = i+1; j = j–1; } X2 X2)i<n
What are Invariants ? 0: i = 0; j = n–1; 1: while (0<=j){ 2: assert(i<n); i = i+1; j = j–1; } X1 X2 i=io+1Æj=jo-1Æ[io/i][jo/j]X2)X1
What are Invariants ? • Predicates X1, X2s.t. • i=0Æj=n-1 )X1 0·jÆX1)X2 X2)i<n …Æ[io/i][jo/j]X2)X1
What are Invariants ? • Predicates X1, X2s.t. • Idea: Lazy Abstraction • How to Infer Invariants? • How to Solve forX1, X2? • i=0Æj=n-1 )X1 0·jÆX1)X2 X2)i<n …Æ[io/i][jo/j]X2)X1
Idea: Lazy Abstraction • Tree of executions over atomic predicates i+j=n-1 Nodes: X1, X2 0·j Edges: X1)X2
Lazy Predicate Abstraction Tree Root Root X(i.e. non-RHS) X0 true Atoms: i+j=n-1,0·j • i=0Æj=n-1ÆX0)X1 0·jÆX1)X2 X2)i<n …[io/i][jo/j]X2)X1
Lazy Predicate Abstraction Tree Edge “Unrolled” Implication X0 true X1 Atoms: i+j=n-1,0·j • i=0Æj=n-1ÆX0)X1 0·jÆX1)X2 X2)i<n …[io/i][jo/j]X2)X1
Lazy Predicate Abstraction Theorem Prover X0 true • i=0Æj=n-1Ætrue) i+j=n-1 Valid ? X1 Atoms: i+j=n-1,0·j • i=0Æj=n-1ÆX0)X1
Lazy Predicate Abstraction Theorem Prover X0 true • i=0Æj=n-1Ætrue) 0·j ? X1 i+j=n-1 Invalid Atoms: i+j=n-1,0·j • i=0Æj=n-1ÆX0)X1 0·jÆX1)X2 X2)i<n …[io/i][jo/j]X2)X1
Lazy Predicate Abstraction X0 true X1 i+j=n-1 Atoms: i+j=n-1,0·j ? X2 i+j=n-1Æ0·j • i=0Æj=n-1ÆX0)X1 0·jÆX1)X2 X2)i<n …[io/i][jo/j]X2)X1
Lazy Predicate Abstraction Theorem Prover X0 true 0·jÆi+j=n-1) i<n X1 Valid i+j=n-1 Atoms: i+j=n-1,0·j X2 i+j=n-1Æ0·j • i=0Æj=n-1ÆX0)X1 0·jÆX1)X2 i<n X2)i<n …[io/i][jo/j]X2)X1
Lazy Predicate Abstraction X0 true X1 i+j=n-1 Atoms: i+j=n-1,0·j X2 i+j=n-1Æ0·j • i=0Æj=n-1ÆX0)X1 0·jÆX1)X2 ? X1 i<n i+j=n-1 X2)i<n …[io/i][jo/j]X2)X1
Lazy Predicate Abstraction X0 true Proved Asserts… …not so fast! Fixpoint Stop Unrolling Inferred Invariants X1 i+j=n-1 • Constraints Solved Atoms: i+j=n-1,0·j X2 i+j=n-1Æ0·j • i=0Æj=n-1ÆX0)X1 0·jÆX1)X2 X1 i<n i+j=n-1 X2)i<n …[io/i][jo/j]X2)X1
Lazy Abstraction [popl 02] Safety Invariants C Program + Asserts Atoms How to get good atoms? e.g. i+j=n-1 If we have bad atoms... e.g. i=0, j=n-1, 0·j
Abstraction With Bad Atoms... …Yields Counterexample “Path” X0 true i:=0 j:=n–1 X1 i=0 Æ j=n-1 0<=j? Assert Holds X2 i<n i=0Æj=n-1Æ0·j i:=i+1 j:=j-1 Not a fixpoint X1 true 0<=j? Assert Fails X2 i<n true
Path Atoms Lazy Abstraction [popl 02] Safety Invariants C Program + Asserts Atoms Path Counterexample Analysis Unsafe Paths “Counterexample Guided Abstraction Refinement” [Kurshan 94, Clarke et al. 00, Ball & Rajamani 00]
Path Formula Proof Atoms X0 i:=0 j:=n–1 i:=0 j:=n–1 X1 How to compute good atoms from paths? 0<=j? 0<=j? X2 i:=i+1 j:=j-1 i:=i+1 j:=j-1 Good Atoms Relationships from past Prove safety of future X1 0<=j? 0<=j? X2 i<n
Path Formula Proof Atoms X0 Æi0 = 0 Æ j0 = n–1 i:=0 j:=n–1 Formula Unsatisfiable iff Assert Holds at Path End X1 Rename Variables (SSA) Æ 0·j0 0<=j? Æ i1 = i0 + 1 Æ j1 = j0 - 1 X2 i:=i+1 j:=j-1 Æ 0·j1 X1 Negate Assert 0<=j? Æ n·i1¸ X2 Formula Unsatisfiableiff Assert Holds i<n
Path Formula Proof Atoms X0 0·j1 Æi0=0 Æ j0=n–1 Æi0 = 0 Æ j0 = n–1 i:=0 j:=n–1 + 0·j0-1 X1 Æ 0·j0 j1=j0-1 Æ 0·j0 0<=j? + 0·n-2 Æ i1 = i0 + 1 Æ j1 = j0 - 1 X2 j0=n-1 Æ i1=i0+1 Æ j1=j0-1 i:=i+1 j:=j-1 + False 0·-1 Æ 0·j1 i0=0 X1 + 0<=j? n·1 Æ i1¸n Æ 0·j1 n·i1 X2 + n·i0+1 Æ n·i1 i1=i0+1 i<n
Path Formula Proof Atoms Good Atoms Relationships from past Prove safety of future 0·j1 + 0·j0-1 j1=j0-1 + 0·n-2 j0=n-1 + False i0=0 i+j=n-1 + + n·1 n·i1 + n·i0+1 i1=i0+1
X0 i:=0 j:=n–1 X1 Atom = Craig Interpolant Of Past, Future Formulas 0<=j? 0<=j? X2 i:=i+1 j:=j-1 Extracted from proof Of path unsatifiability Inferred Good Atom i+j=n-1 X1 0<=j? X2 i<n
Recap • How to verify safety ? • Compute invariantsX1, X2... • How to solve for X1, X2... ? • Tree of executions over atoms • How to find good atoms ? • Interpolants of path formulas
Recap Safety Invariants X0, X1 • Implications • X0)X1 AI, PA, CEGAR,…
Part I • First-Order (by Logic) • Part II Higher-Order Verification
Key Problem: Invariants for… Collections? Closures? Polymorphism? Recursive Data?
Idea: LiquidTypes • Idea: Logically Qualified Types • Factor Invariant to Logic x Type
Logic • Describes Individual Data • Type • Quantifies over Structure
8i:0 ·i<table.length)-1· table[i] Logic Type • factored into table::{v:int|-1·v}array
8x:next*(root,x))-1·x.data Logic Type • factored into root::{v:int|-1·v}list
Functions: Array.get • Pre-Condition ’aarray ->int -> ’a x:’aarray ->{v:int|0·v<lenx} -> ’a • Post-Condition
Higher-Order: ffor • lo:int • ->hi:{int|lo·v} • ->({v:int|lo·v<hi}->unit) • -> unit • int • ->int • ->(int->unit) • -> unit
Logic • Describes Individual Data • Theorem Prover • Reasoning about Individual Data • Type System • Quantified Reasoning about Structure • Type • Quantifies over Structure
Demo “Map-Reduce”
“Map-Reduce” • map :: (e -> (k, v) list) • -> elist • -> (k, v)list • group :: (k, v)list • -> (k, v list)table • reduce :: (v-> v-> v) • -> (k, vlist)table • -> (k, v) table