Download presentation
Presentation is loading. Please wait.
Published byDamian McCarthy Modified over 9 years ago
1
Software Verification With Liquid Types Ranjit Jhala, UC San Diego (with Pat Rondon, Ming Kawaguchi)
2
int min_index(int [] a){ r = 0; n = a.length; for (i = 0; i < n; i++){ if (a[i] < a[r]) r = i; } return r; } Software Verification
3
int min_index(int [] a){ r = 0; n = a.length; for (i = 0; i < n; i++){ if (a[i] < a[r]) r = i; } return r; } Example: Memory Safety Access In Array Bounds ?
4
int min_index(int [] a){ r = 0; n = a.length; for (i = 0; i < n; i++){ if (a[i] < a[r]) r = i; } return r; } Example: Memory Safety How to prove assert ? assert (0<=r && r<n)
5
int min_index(int [] a){ r = 0; n = a.length; //@invariant: 0 · i Æ 0 · r Æ r<n for (i = 0; i < n; i++){ if (a[i] < a[r]) r = i; } return r; } Example: Memory Safety
6
int min_index(int [] a){ r = 0; n = a.length; //@invariant: 0 · i Æ 0 · r Æ r<n for (i = 0; i < n; i++){ if (a[i] < a[r]) r = i; } return r; } Invariants By Man [Floyd-Hoare] Or Machine [Cousot-Cousot]
7
But, what of … Closures Collections Polymorphism Data Structures …?
8
H-O Logics? Quantifiers? Induction? But, what of …
9
Automation
10
H-O Logics? Quantifiers? Induction? A Solution: Types
11
Part I Part II Part III Types and Invariants Closures, Collections, Generics Induction for Data Structures
12
Part I Types and Invariants
13
Part I Refinement Types [Zenger ’97, Owre-Rushby-Shankar ’98, Xi-Pfenning ’98]
14
let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 min_index: a:int array -> int
15
min_index: {a:int array|0 ≺ a.len} -> {v:int|0 ≼ v ≺ a.len} Type Refinement let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0
16
min_index: {a:int array|0 ≺ a.len} -> {v:int|0 ≼ v ≺ a.len} “Requires” let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0
17
min_index: {a:int array|0 ≺ a.len} -> {v:int|0 ≼ v ≺ a.len} “Ensures” let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0
18
{r:int|0 ≼ r ≺ a.len}->{i:int|0 ≼ i}->{v:int|0 ≼ v ≺ a.len} loop: let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0
19
{r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} loop: let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0
20
{r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} “Requires” loop: let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0
21
{r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} “Ensures” loop: let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0
22
Part I Refinement Types 1. Type-checking 2. Refine-checking 3. Refine-Inference
23
let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 loop : r:int -> i:int -> int Assume 1 loop : … r : int i : int Prove output is int r “subtype-of” int ⊢
24
let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 loop : r:int -> i:int -> int Assume 1 loop : … r : int i : int Prove output is int r <: int ⊢
25
loop : r:int -> i:int -> int Assume 1 2 let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 loop : … r : int i : int Prove index is int ⊢ i <: int
26
loop : r:int -> i:int -> int Assume 1 3 let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 2 loop : … i : int r : int r': int i': int Prove input is int ⊢ r' <: int
27
loop : r:int -> i:int -> int Assume loop r' i' <: int Prove output is int 1 3 4 let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 2 loop : … i : int r : int r': int i': int ⊢
28
loop : r:int -> i:int -> int AssumeProve input is int 1 3 4 let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 2 5 loop : … i : int r : int r': int i': int ⊢ 0 <: int
29
Part I Refinement Types 1. Type-checking 2. Refine-checking 3. Refine-Inference
30
let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 loop {r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} min_index {a:0 ≺ a.len}->{v:0 ≼ v ≺ a.len}
31
r :0 ≼ r ≺ a.len i :0 ≼ i Assume 1 let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 Prove output is ensured loop: {r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} 3 4 2 5 [i ≽ a.len]
32
r :0 ≼ r ≺ a.len i :0 ≼ i [i ≽ a.len] Assume 1 let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 Prove output is ensured ⊢ {v=r} <: {0 ≼ v ≺ a.len} loop: {r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len}
33
r :0 ≼ r ≺ a.len i :0 ≼ i [i ≽ a.len] Assume 1 let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 Prove output is ensured ⊢ {v=r} <: {0 ≼ v ≺ a.len} loop: {r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len}
34
Assume 1 let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 Prove output is ensured ⊢ {v=r} <: {0 ≼ v ≺ a.len} loop: {r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} 0 ≼ r ≺ a.len ⋀ 0 ≼ i ⋀ i ≽ a.len
35
Assume 1 let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 Prove output is ensured {v=r} <: {0 ≼ v ≺ a.len} loop: {r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} 0 ≼ r ≺ a.len ⋀ 0 ≼ i ⋀ i ≽ a.len ⋀
36
Assume 1 let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 Prove output is ensured loop: {r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} 0 ≼ r ≺ a.len ⋀ 0 ≼ i ⋀ i ≽ a.len ⋀ ⇒ v=r 0 ≼ v ≺ a.len
37
1 let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 loop: {r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} v=r 0 ≼ v ≺ a.len ⋀ 0 ≼ r ≺ a.len ⋀ 0 ≼ i ⋀ i ≽ a.len Is Valid? Yes. ⇒
38
Assume let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 r :0 ≼ r ≺ a.len i :0 ≼ i [i ≺ a.len] Prove index in bounds ⊢ {v=i} <: {0 ≼ v ≺ a.len} loop: {r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} 1 3 4 2 5 [i ≺ a.len]
39
let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 loop: {r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} ⇒ v=i 0 ≼ v ≺ a.len ⋀ 0 ≼ r ≺ a.len ⋀ 0 ≼ i ⋀ i ≺ a.len Is Valid? Yes. 2
40
let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 Prove input as required ⊢ {v=r'} <: {0 ≼ v ≺ a.len} loop: {r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} 1 3 4 2 5
41
Assume let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 r :0 ≼ r ≺ a.len i :0 ≼ i [i ≺ a.len] i':i'=i+1 Prove input as required ⊢ {v=r'} <: {0 ≼ v ≺ a.len} loop: {r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} 3 r':r'=i ∨ r'=r
42
let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 loop: {r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} 3 ⇒ v=r' 0 ≼ v ≺ a.len ⋀ Is Valid? Yes! 0 ≼ r ≺ a.len ⋀ 0 ≼ i ⋀ i ≺ a.len ⋀ r'=i ∨ r'=r ⋀ i'=i+1
43
let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 Prove output is ensured ⊢ {0 ≼ v ≺ a.len}<: {0 ≼ v ≺ a.len} loop: {r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} 1 3 4 2 5 Trivial.
44
Assume let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 a :0 ≺ a.len Prove input as required ⊢ {v=0}<: {0 ≼ v ≺ a.len} loop: {r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} 1 3 4 2 5
45
⇒ ⋀ let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 v=0 0 ≼ v ≺ a.len loop: {r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} 5 Is Valid? Indeed. 0 ≺ a.len
46
Part I Refinement Types 1. Type-checking 2. Refine-checking 3. Refine-Inference
47
let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 loop {r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} min_index {a:0 ≺ a.len}->{v:0 ≼ v ≺ a.len}
48
loop {r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} min_index {a:0 ≺ a.len}->{v:0 ≼ v ≺ a.len} Writing Types is Hard Work!
49
Automatic Refinement Inference Writing Types is Hard Work! loop: ???
50
Automatic Refinement Inference 1. Templates 2. Constraints 3. Fixpoint [MC/AI] loop: ???
51
Automatic Refinement Inference 1. Templates 2. Constraints 3. Fixpoint [MC/AI] loop : r:int -> i:int -> int
52
Automatic Refinement Inference 1. Templates 2. Constraints 3. Fixpoint [MC/AI] loop : {r:int| ? } -> {i:int| ? } -> {v:int| ? }
53
Automatic Refinement Inference 1. Templates 2. Constraints 3. Fixpoint [MC/AI] loop :{r:int| X r } -> {i:int| X i } -> {v:int| X out } Types + X for unknown refinements
54
Automatic Refinement Inference 1. Templates 2. Constraints 3. Fixpoint [MC/AI] loop :{r:int| X r } -> {i:int| X i } -> {v:int| X out }
55
Automatic Refinement Inference 1. Templates 2. Constraints 3. Fixpoint [MC/AI] Type Checking, but with Templates
56
r : X r i : X i [i ≽ a.len] Assume 1 let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 Prove output is ensured 3 4 2 5 loop :{r:int| X r } -> {i:int| X i } -> {v:int| X out } ⊢ {v=r} <: { X out }
57
1 let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 loop :{r:int| X r } -> {i:int| X i } -> {v:int| X out } ⋀ X r ⋀ X i ⋀ i ≽ a.len Is Valid? ⇒ v=r X out “It is too soon to say. ”
58
1 let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 3 4 2 5 loop :{r:int| X r } -> {i:int| X i } -> {v:int| X out } X r ⋀ X i ⋀ i ≽ a.len ⋀ v=r ⇒ X out Constraint 1
59
Assume let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 Prove index in bounds ⊢ {v=i} <: {0 ≼ v ≺ a.len} 1 3 4 2 5 loop :{r:int| X r } -> {i:int| X i } -> {v:int| X out } r : X r i : X i [i ≺ a.len]
60
let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 loop: {r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} 2 X r ⋀ X i ⋀ i ≺ a.len ⋀ v=i ⇒ 0 ≼ v ≺ a.len Constraint 2
61
let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 Prove input as required ⊢ {v:v=r'} <: {r:int| X r } 1 3 4 2 5 loop :{r:int| X r } -> {i:int| X i } -> {v:int| X out } Assume r : X r i : X i [i ≺ a.len] r':r'=i ∨ r'=r i':i'=i+1
62
let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 loop: {r:0 ≼ r ≺ a.len}->{i:0 ≼ i}->{v:0 ≼ v ≺ a.len} Constraint 3 X r ⋀ X i ⋀ i ≺ a.len ⋀ (r'=i ∨ r'=r) ⋀ v=r' X r [v/r ] ⇒
63
let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 Prove output is ensured 1 3 4 2 5 loop :{r:int| X r } -> {i:int| X i } -> {v:int| X out } Constraint 4 X r ⋀ X i ⋀ i ≺ a.len ⋀ (r'=i ∨ r'=r) ⋀ X out X out ⇒
64
let min_index a = let rec loop r i = if i >= a.length then r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loop r' i' loop 0 0 Prove input as required 1 3 4 2 5 loop :{r:int| X r } -> {i:int| X i } -> {v:int| X out } Constraint 5 0 ≺ a.len ⋀ v=0 X r [v/r ] ⇒
65
Automatic Refinement Inference 1. Templates 2. Constraints 3. Fixpoint [MC/AI] Type Checking, but with Templates
66
Automatic Refinement Inference 1. Templates 2. Constraints 3. Fixpoint [MC/AI] 0 ≺ a.len ⋀ v=0 ⇒ X r [v/r ] 1 X r ⋀ X i ⋀ i ≺ a.len ⋀ (r'=i ∨ r'=r) ⋀ X out ⇒ X out X r ⋀ X i ⋀ i ≺ a.len ⋀ (r'=i ∨ r'=r) ⋀ v=r' ⇒ X r [v/r ] X r ⋀ X i ⋀ i ≺ a.len ⋀ v=i ⇒ 0 ≼ v ≺ a.len X r ⋀ X i ⋀ i ≽ a.len ⋀ v=r ⇒ X out 2 3 4 5
67
Automatic Refinement Inference 1. Templates 2. Constraints 3. Fixpoint [MC/AI] X r ⋀ X i ⋀ i ≺ a.len ⋀ (r'=i ∨ r'=r) ⋀ X out ⇒ X out 4 ⋀ X i ⋀ P ⇒ X
68
Automatic Refinement Inference 1. Templates 2. Constraints 3. Fixpoint [MC/AI] X r ⋀ X i ⋀ i ≺ a.len ⋀ (r'=i ∨ r'=r) ⋀ X out ⇒ X out 4 ⋀ X i ⋀ P ⇒ X
69
Automatic Refinement Inference 1. Templates 2. Constraints 3. Fixpoint [MC/AI] X r ⋀ X i ⋀ i ≺ a.len ⋀ (r'=i ∨ r'=r) ⋀ X out ⇒ X out 4 ⋀ X i ⋀ P ⇒ X
70
Automatic Refinement Inference 1. Templates 2. Constraints 3. Fixpoint [MC/AI] 0 ≺ a.len ⋀ v=0 ⇒ X r [v/r ] 1 X r ⋀ X i ⋀ i ≺ a.len ⋀ (r'=i ∨ r'=r) ⋀ X out ⇒ X out X r ⋀ X i ⋀ i ≺ a.len ⋀ (r'=i ∨ r'=r) ⋀ v=r' ⇒ X r [v/r ] X r ⋀ X i ⋀ i ≽ a.len ⋀ v=r ⇒ X out 2 3 4 5 X r ⋀ X i ⋀ i ≺ a.len ⋀ v=i ⇒ 0 ≼ v ≺ a.len ⋀ X i ⋀ P ⇒ Q
71
Automatic Refinement Inference 1. Templates 2. Constraints 3. Fixpoint [MC/AI] 0 ≺ a.len ⋀ v=0 ⇒ X r [v/r ] 1 X r ⋀ X i ⋀ i ≺ a.len ⋀ (r'=i ∨ r'=r) ⋀ X out ⇒ X out X r ⋀ X i ⋀ i ≺ a.len ⋀ (r'=i ∨ r'=r) ⋀ v=r' ⇒ X r [v/r ] X r ⋀ X i ⋀ i ≽ a.len ⋀ v=r ⇒ X out 2 3 4 5 X r ⋀ X i ⋀ i ≺ a.len ⋀ v=i ⇒ 0 ≼ v ≺ a.len ⋀ X i ⋀ P ⇒ Q
72
Automatic Refinement Inference 1. Templates 2. Constraints 3. Fixpoint [MC/AI] 0 ≺ a.len ⋀ v=0 ⇒ X r [v/r ] 1 X r ⋀ X i ⋀ i ≺ a.len ⋀ (r'=i ∨ r'=r) ⋀ X out ⇒ X out X r ⋀ X i ⋀ i ≺ a.len ⋀ (r'=i ∨ r'=r) ⋀ v=r' ⇒ X r [v/r ] X r ⋀ X i ⋀ i ≽ a.len ⋀ v=r ⇒ X out 2 3 4 5 X r ⋀ X i ⋀ i ≺ a.len ⋀ v=i ⇒ 0 ≼ v ≺ a.len ⋀ X i ⋀ P ⇒ Q
73
Automatic Refinement Inference 1. Templates 2. Constraints 3. Fixpoint [MC/AI] ⋀ X i ⋀ P ⇒ Q ⋀ X i ⋀ P ⇒ X (Post*) (Safe)
74
Automatic Refinement Inference 1. Templates 2. Constraints 3. Fixpoint [MC/AI] ⋀ X i ⋀ P ⇒ X ⋀ X i ⋀ P ⇒ Q
75
Automatic Refinement Inference Fixpoint Solution ⋀ X i ⋀ P ⇒ X ⋀ X i ⋀ P ⇒ Q “Horn Clauses”
76
Automatic Refinement Inference Fixpoint Solution ⋀ X i ⋀ P ⇒ X ⋀ X i ⋀ P ⇒ Q “Positive Implications”
77
Automatic Refinement Inference Fixpoint Solution ⋀ X i ⋀ P ⇒ X ⋀ X i ⋀ P ⇒ Q “Non-Linear Implications”
78
Automatic Refinement Inference Fixpoint Solution ⋀ X i ⋀ P ⇒ X ⋀ X i ⋀ P ⇒ Q 1. Reduce to simple “first-order” program Reuse any abs-interpreter, model-checker e.g. Interproc, SLAM, BLAST, ARMC [CAV 11]
79
Automatic Refinement Inference Fixpoint Solution ⋀ X i ⋀ P ⇒ X ⋀ X i ⋀ P ⇒ Q 2. Monomial Predicate Abstraction (“Houdini”) Input : Candidates Q = {q 1 … q n } Output : X ↦ ⋀ q j satisfying constraints
80
Automatic Refinement Inference Fixpoint Solution ⋀ X i ⋀ P ⇒ X ⋀ X i ⋀ P ⇒ Q 2. Monomial Predicate Abstraction (“Houdini”) Input : Q = { ⋆≼ v, v ≼ ⋆, v ≺ ⋆, v ≺ ⋆.len } ⋆ = any variable or constant
81
Automatic Refinement Inference Fixpoint Solution ⋀ X i ⋀ P ⇒ X ⋀ X i ⋀ P ⇒ Q 2. Monomial Predicate Abstraction (“Houdini”) Input : Q = { ⋆≼ v, v ≼ ⋆, v ≺ ⋆, v ≺ ⋆.len } Output : X r = 0 ≼ v ⋀ v ≺ a.len X i = 0 ≼ v X out = 0 ≼ v ⋀ v ≺ a.len
82
2. Monomial Predicate Abstraction (“Houdini”) Input : Q = { ⋆≼ v, v ≼ ⋆, v ≺ ⋆, v ≺ ⋆.len } Output : X r = 0 ≼ v ⋀ v ≺ a.len X i = 0 ≼ v X out = 0 ≼ v ⋀ v ≺ a.len Automatic Refinement Inference Plug Solution In Template loop: {r:int| X r } -> {i:int| X i } -> {v:int| X out }
83
2. Monomial Predicate Abstraction (“Houdini”) Input : Q = { ⋆≼ v, v ≼ ⋆, v ≺ ⋆, v ≺ ⋆.len } Output : X r = 0 ≼ v ⋀ v ≺ a.len X i = 0 ≼ v X out = 0 ≼ v ⋀ v ≺ a.len Automatic Refinement Inference Plug Solution In Template loop: {r:int|0 ≼ r ≺ a.len}->{i:int|0 ≼ i}->{v:int|0 ≼ v ≺ a.len}
84
Automatic Refinement Inference loop: {r:int|0 ≼ r ≺ a.len}->{i:int|0 ≼ i}->{v:int|0 ≼ v ≺ a.len} Inferred Refinement Type
85
Automatic Refinement Inference loop: {r:int|0 ≼ r ≺ a.len}->{i:int|0 ≼ i}->{v:int|0 ≼ v ≺ a.len} Liquid Type of loop
86
Recap Program Templates Constraints AI, MC, PA … {i:int| X i } -> {v:int| X o } ⋀ X i ⋀ P ⇒ X
87
Part I Part II Part III Liquid Types Closures, Collections, Generics Induction for Data Structures
88
Part I Part II Part III Refinement Types Closures, Collections, Generics Induction for Data Structures
89
Closures / Higher-Order Functions let rec ffor l u f = if l < u then f l; ffor (l+1) u f
90
let rec ffor l u f = if l < u then ( f l; ffor (l+1) u f ) Type of f int ! unit
91
let rec ffor l u f = if l < u then ( f l; ffor (l+1) u f ) Template of f {v:int| X 1 } ! unit
92
let rec ffor l u f = if l < u then ( f l; ffor (l+1) u f ) Template of f {v:int| X 1 } ! unit Check: input l as required by f
93
let rec ffor l u f = if l < u then ( f l; ffor (l+1) u f ) Template of f {v:int| X 1 } ! unit l ≺ u ⊢ {v:int | v=l} <: {v:int |X 1 } l ≺ u Æ v=l ) X 1 Solution X 1 = l ≼ v Æ v ≺ u Reduces to
94
let rec ffor l u f = if l < u then ( f l; ffor (l+1) u f ) Template of f {v:int| X 1 } ! unit Solution X 1 = l ≼ v Æ v ≺ u Liquid Type of f {v:int|l ≼ v Æ v ≺ u} ! unit
95
Closures / Higher-Order Functions let rec ffor l u f = if l < u then f l; ffor (l+1) u f Liquid Type of ffor l:int ! u:int ! ( {v:int | l ≼ v ≺ u} ! unit ) ! unit Liquid Type of f {v:int|l ≼ v Æ v ≺ u} ! unit
96
let rec ffor l u f = if l < u then f l; ffor (l+1) u f let min_index a = let r = ref 0 ffor 0 a.len (fun i -> if a.(i) < a.(!r) then r := i ); !r Min-Index Revisited
97
Liquid Type of ffor l:int ! u:int ! ( {v:int | l ≼ v ≺ u} ! unit ) ! unit let min_index a = let r = ref 0 ffor 0 a.len (fun i -> if a.(i) < a.(!r) then r:= i) !r
98
Liquid Type of ffor 0 u:int ! ( {v:int | 0 ≼ v ≺ u} ! unit ) ! unit let min_index a = let r = ref 0 ffor 0 a.len (fun i -> if a.(i) < a.(!r) then r:= i) !r
99
Liquid Type of ffor 0 a.len ( {v:int | 0 ≼ v ≺ a.len} ! unit ) ! unit let min_index a = let r = ref 0 ffor 0 a.len (fun i -> if a.(i) < a.(!r) then r:= i) !r
100
Liquid Type of ffor 0 a.len ( {v:int | 0 ≼ v ≺ a.len} ! unit ) ! unit Template of (fun i ->...) {v:int| X i } ! unit let min_index a = let r = ref 0 ffor 0 a.len (fun i -> if a.(i) < a.(!r) then r:= i) !r
101
Liquid Type of ffor 0 a.len ( {v:int | 0 ≼ v ≺ a.len} ! unit ) ! unit Template of (fun i ->...) {v:int| X i } ! unit let min_index a = let r = ref 0 ffor 0 a.len (fun i -> if a.(i) < a.(!r) then r:= i) !r Check: input ( fun i... ) as required by ffor
102
Liquid Type of ffor 0 a.len ( {v:int | 0 ≼ v ≺ a.len} ! unit ) ! unit Template of (fun i ->...) {v:int| X i } ! unit { X i } ! unit <:{0 ≼ v ≺ a.len} ! unit Check: input ( fun i... ) as required by ffor
103
{0 ≼ v ≺ a.len} unit {Xi}{Xi} { X i } ! unit <:{0 ≼ v ≺ a.len} ! unit {0 ≼ v ≺ a.len} <: { X i } unit <: unit Trivial Function Subtyping Splits Into
104
{ X i } ! unit <:{0 ≼ v ≺ a.len} ! unit 0 ≼ v ≺ a.len ) X i
105
Solution X i = 0 ≼ v ≺ a.len
106
Template of (fun i ->...) {v:int| X i } ! unit
107
Solution X i = 0 ≼ v ≺ a.len Liquid Type of (fun i ->...) {v:int | 0 ≼ v ≺ a.len} ! unit
108
let min_index a = let r = ref 0 ffor 0 a.len (fun i -> if a.(i) < a.(!r) then r:= i) !r Liquid Type of r {v:int | 0 ≼ v ≺ a.len} ref Liquid Type of (fun i ->...) {v:int | 0 ≼ v ≺ a.len} ! unit
109
let min_index a = let r = ref 0 ffor 0 a.len (fun i -> if a.(i) < a.(!r) then r:= i) !r Liquid Type of r {v:int | 0 ≼ v ≺ a.len} ref Access Safe
110
let min_index a = let r = ref 0 ffor 0 a.len (fun i -> if a.(i) < a.(!r) then r:= i) !r Liquid Type of r {v:int | 0 ≼ v ≺ a.len} ref Liquid Type of min_index a:int array ! {v:int | 0 ≼ v ≺ a.len}
111
Part I Part II Part III Refinement Types Closures, Collections, Generics Induction for Data Structures
112
let rec range l u = if l < u then l :: (range (l+1) u) else [] Collections (e.g. Lists) Type of range l:int ! u:int ! int list
113
let rec range l u = if l < u then l :: (range (l+1) u) else [] Collections (e.g. Lists) Template of range l:int ! u:int ! {v:int| X out } list
114
let rec range l u = if l < u then l :: (range (l+1) u) else [] Template of range l:int ! u:int ! {v:int| X out } list Template of “ then ”: {v:int| X out } list
115
let rec range l u = if l < u then l :: (range (l+1) u) else [] Check: “head” and “tail” as required Template of “ then ”: {v:int| X out } list
116
let rec range l u = if l < u then l :: (range (l+1) u) else [] Check: “head” and “tail” as required l ≺ u ⊢ “head” <: {v:int |X out } Template of “ then ”: {v:int| X out } list
117
let rec range l u = if l < u then l :: (range (l+1) u) else [] Check: “head” and “tail” as required l ≺ u ⊢ “head” <: {v:int |X out } l ≺ u ⊢ “tail” <: {v:int |X out } list Template of “ then ”: {v:int| X out } list
118
let rec range l u = if l < u then l :: (range (l+1) u) else [] Check: “head” and “tail” as required l ≺ u ⊢ “head” <: {v:int |X out }
119
let rec range l u = if l < u then l :: (range (l+1) u) else [] l ≺ u Æ v=l ) X out Reduces To (1) Check: “head” and “tail” as required l ≺ u ⊢ {v:int | v=l} <: {v:int |X out }
120
let rec range l u = if l < u then l :: (range (l+1) u) else [] Check: “head” and “tail” as required l ≺ u ⊢ “tail” <: {v:int |X out } list
121
let rec range l u = if l < u then l :: (range (l+1) u) else [] Check: “head” and “tail” as required l ≺ u ⊢ { X out [l+1/l]} list <: { X out } list By List-Subtyping, Reduces To l ≺ u ⊢ { X out [l+1/l]} <: { X out }
122
Check: “head” and “tail” as required l ≺ u ⊢ { X out [l+1/l]} list <: { X out } list Reduces To (2) l ≺ u Æ X out [l+1/l] ) X out
123
(2) (1) Solution X out = l ≼ v ≺ u l ≺ u Æ v=l ) X out l ≺ u Æ X out [l+1/l] ) X out
124
let rec range l u = if l < u then l :: (range (l+1) u) else [] Collections (e.g. Lists) Template of range l:int ! u:int ! {v:int| X out } list Solution X out = l ≼ v ≺ u
125
let rec range l u = if l < u then l :: (range (l+1) u) else [] Collections (e.g. Lists) Liquid Type of range l:int ! u:int ! {v:int|l ≼ v ≺ u} list Solution X out = l ≼ v ≺ u
126
Part I Part II Part III Refinement Types Closures, Collections, Generics Induction for Data Structures
127
let rec range l u = if l < u then l :: (range (l+1) u) else [] Generics/Polymorphism
128
let rec range l u = if l < u then l :: (range (l+1) u) else [] let min_index a = let indices = range 0 a.len fold_left (fun r i -> if a.(i) < a.(r) then i else r) 0 indices Generics/Polymorphism
129
Instance Type a = int b = int Generic Type of fold_left (a ! b ! a) ! a ! b list ! a let min_index a = let indices = range 0 a.len fold_left (fun r i -> if a.(i) < a.(r) then i else r ) 0 indices
130
Generic Type of fold_left (a ! b ! a) ! a ! b list ! a Instance Template a = {v:int| X a } b = {v:int| X b } let min_index a = let indices = range 0 a.len fold_left (fun r i -> if a.(i) < a.(r) then i else r ) 0 indices
131
Instance Template of fold_left ( { X a } ! { X b } ! { X a } ) ! { X a } ! { X b }list ! { X a } Instance Template a = {v:int| X a } b = {v:int| X b } let min_index a = let indices = range 0 a.len fold_left (fun r i -> if a.(i) < a.(r) then i else r ) 0 indices
132
let min_index a = let indices = range 0 a.len fold_left (fun r i -> if a.(i) < a.(r) then i else r ) 0 indices Instance Template of fold_left ( { X a } ! { X b } ! { X a } ) ! { X a } ! { X b }list ! { X a } Template of r {v:int | X a }
133
let min_index a = let indices = range 0 a.len fold_left (fun r i -> if a.(i) < a.(r) then i else r ) 0 indices Instance Template of fold_left ( { X a } ! { X b } ! { X a } ) ! { X a } ! { X b }list ! { X a } Template of i {v:int | X b }
134
let min_index a = let indices = range 0 a.len fold_left (fun r i -> if a.(i) < a.(r) then i else r ) 0 indices Instance Template of fold_left ( { X a } ! { X b } ! { X a } ) ! { X a } ! { X b }list ! { X a } Template of min_index a:int array ! {v:int | X a }
135
let min_index a = let indices = range 0 a.len fold_left (fun r i -> if a.(i) < a.(r) then i else r ) 0 indices Instance Template of fold_left ( { X a } ! { X b } ! { X a } ) ! { X a } ! { X b }list ! { X a } Check: args as required
136
let min_index a = let indices = range 0 a.len fold_left (fun r i -> if a.(i) < a.(r) then i else r ) 0 indices Instance Template of fold_left ( { X a } ! { X b } ! { X a } ) ! { X a } ! { X b }list ! { X a } Check: args as required 1
137
let min_index a = let indices = range 0 a.len fold_left (fun r i -> if a.(i) < a.(r) then i else r ) 0 indices Instance Template of fold_left ( { X a } ! { X b } ! { X a } ) ! { X a } ! { X b }list ! { X a } Check: args as required 1 2
138
let min_index a = let indices = range 0 a.len fold_left (fun r i -> if a.(i) < a.(r) then i else r ) 0 indices Instance Template of fold_left ( { X a } ! { X b } ! { X a } ) ! { X a } ! { X b }list ! { X a } Check: args as required 1 2 3
139
let min_index a = let indices = range 0 a.len fold_left (fun r i -> if a.(i) < a.(r) then i else r ) 0 indices Constraints 1 2 3 r:int ! i:int ! {v=i ∨ v=r} <: { X a } ! { X b } ! { X a } {v:int | v=0} <: {v:int | X a } {v:int | 0 ≼ v ≺ a.len} list <: {v:int | X b } list 1 2 3
140
let min_index a = let indices = range 0 a.len fold_left (fun r i -> if a.(i) < a.(r) then i else r ) 0 indices Subtyping Reduces To Implications 1 2 3 r:int ! i:int ! {v=i ∨ v=r} <: { X a } ! { X b } ! { X a } {v:int | v=0} <: {v:int | X a } {v:int | 0 ≼ v ≺ a.len} list <: {v:int | X b } list X a [r/v] Æ X b [i/v] Æ ( v=i ∨ v=r ) ) X a v=0 ) X a 0 ≼ v ≺ a.len ) X b 1 2 3
141
let min_index a = let indices = range 0 a.len fold_left (fun r i -> if a.(i) < a.(r) then i else r ) 0 indices Solution X a, X b = 0 ≼ v ≺ a.len
142
let min_index a = let indices = range 0 a.len fold_left (fun r i -> if a.(i) < a.(r) then i else r ) 0 indices Solution X a, X b = 0 ≼ v ≺ a.len Templates r : {v:int| X a } i : {v:int| X b }
143
let min_index a = let indices = range 0 a.len fold_left (fun r i -> if a.(i) < a.(r) then i else r ) 0 indices Solution X a, X b = 0 ≼ v ≺ a.len Liquid Types r : {v:int| 0 ≼ v ≺ a.len} i : {v:int| 0 ≼ v ≺ a.len}
144
let min_index a = let indices = range 0 a.len fold_left (fun r i -> if a.(i) < a.(r) then i else r ) 0 indices Solution X a, X b = 0 ≼ v ≺ a.len Liquid Types r : {v:int| 0 ≼ v ≺ a.len} i : {v:int| 0 ≼ v ≺ a.len} Safe
145
let min_index a = let indices = range 0 a.len fold_left (fun r i -> if a.(i) < a.(r) then i else r ) 0 indices Solution X a, X b = 0 ≼ v ≺ a.len Template of min_index a:int array ! {v:int | X a }
146
let min_index a = let indices = range 0 a.len fold_left (fun r i -> if a.(i) < a.(r) then i else r ) 0 indices Solution X a, X b = 0 ≼ v ≺ a.len Liquid Type of min_index a:int array ! {v:int | 0 ≼ v ≺ a.len}
147
Part I Part II Part III Refinement Types Closures, Collections, Generics Induction for Data Structures
148
Part I Part II Part III Refinement Types Closures, Collections, Generics Induction for Data Structures
149
Part I Part II Part III Refinement Types Closures, Collections, Generics Induction for Data Structures
150
Data (Structure) Properties Piggyback Predicates On Types
151
[] :: {x:int|0<x} listint list 0<x Describes all elements x : int Representation
152
[] :: 0<x x : int Type Unfolding [] :: 0<h h : int [] :: 0<x x : int HeadTailEmpty PositiveProperty holds recursively List of positive integers
153
[] :: 0<x Describes all elements x : int x<v v Describes tail elements Representation
154
[] :: x<v x : int Type Unfolding [] :: h : int [] :: x<v x : int HeadTailEmpty Elements larger than head Property holds recursively List of sorted integers h<v Push Edge Predicate Into NodeRename Variable h<x
155
Piggyback Predicates On Types Data (Structure) Properties
156
[] :: x : int Unfold :: h : int [] :: x : int l:sorted listh:intt:sorted list & {h<x} list Instantiate tl match l with h :: t x<V h<x Quantifier Instantiation
157
Piggyback Predicates On Types Data (Structure) Properties
158
[] :: x : int Fold h : int [] :: x : int :: l:sorted listh:intt:sorted list & {h<x} list Generalize tl let l = h :: t in x<V h<x Quantifier Generalization
159
Another Example: Trees Leaf Node x : int x<V V<x
160
Node Leaf Node x : int Leaf Node x : int Node Leaf x<V V<x x<V V<x r<V V<r Another Example: Trees r : int Unfold
161
< RHS nodesLHS nodes < root Node Leaf Node x : int Leaf Node x : int Node Leaf x<V V<x x<V V<x r<x x<r Another Example: Trees r : int Push Edge Predicates Invariant: Binary Search Trees
162
Demo isort,bst
163
Part I Part II Part III Refinement Types Closures, Collections, Generics Induction for Data Structures
164
Piggyback Predicates On Types (Data) Structure Properties
165
measure len = | [] -> 0 | x::xs -> 1 + len xs Representation: List Length
166
8 l,x,xs. len([]) = 0 len(x::xs) = 1+len(xs)
167
Piggyback Predicates On Types (Data) Structure Properties
168
l:’a list h:’a t:’a list len(l)=1+len(t) Instantiate match l with h :: t Quantifier Instantiation 8 l,x,xs. len([]) = 0 len(x::xs) = 1+len(xs)
169
Piggyback Predicates On Types (Data) Structure Properties
170
h:’a t:’a list Quantifier Generalization 8 l,x,xs. len([]) = 0 len(x::xs) = 1+len(xs) Generalize let l = h :: t in h:’a t:’a list l:’a list len(l)=1+len(t)
171
Demo listlen, msortb
172
Part I Part II Part III Refinement Types Closures, Collections, Generics Induction for Data Structures
173
Part I Part II Part III Refinement Types Closures, Collections, Generics Induction for Data Structures
174
Leaf l r l = Left subtree r = Right subtree treeHeight H l = Left subtree’s height H r = Right subtree’s height measure H = | Leaf = 0 | Node(x,l,r) = 1 + max (H l) (H r) Height Balanced Tree | Hl–Hr |< 2 Node Height difference bounded at each node
175
Demo eval
176
Refinement Type Inference By Predicate Abstraction
177
0<x [] :: x : int x<v Automatic Inference Predicates Determine Invariant Let X 1, X 2,... = Unknown Predicates Complex Subtyping Between data types X1X1 X2X2 Reduces To Simple Implications Between X 1, X 2,... Solved by Predicate Abstraction Over atoms 0< ⋆, ⋆ <v,...
178
Part I Part II Part III Refinement Types Closures, Collections, Generics Induction for Data Structures
179
Program (ML)Verified Safety Properties List-based SortingSorted, Outputs Permutation of Input Finite MapBalance, BST, Implements a Set Red-Black TreesBalance, BST, Color StablesortSorted Extensible VectorsBalance, Bounds Checking, … Binary HeapsHeap, Returns Min, Implements Set Splay HeapsBST, Returns Min, Implements Set MallocUsed and Free Lists Are Accurate BDDsVariable Order Union FindAcyclicity Bitvector UnificationAcyclicity
180
Finite Maps (ML) 5: ‘cat’ 3: ‘cow’ 8: ‘tic’ 1: ‘doc’ 4: ‘hog’ 7: ‘ant’ 9: ‘emu’ From Ocaml Standard Library Implemented as AVL Trees Rotate/Rebalance on Insert/Delete Verified Invariants Binary Search Ordered Height Balanced Keys Implement Set
181
Binary Decision Diagrams (ML) X1X1 X2X2 X2X2 X3X3 X4X4 X4X4 1 Graph-Based Boolean Formulas [Bryant 86] X 1 X 2 X 3 X 4 Efficient Formula Manipulation Memoizing Results on Subformulas Verified Invariant Variables Ordered Along Each Path
182
Vec: Extensible Arrays (317 LOC) “Python-style” extensible arrays for Ocaml find, insert, delete, join etc. Efficiency via balanced trees Balanced Height difference between siblings ≤ 2 Dsolve found balance violation
183
Debugging via Inference Using Dsolve we found Where imbalance occurred (specific path conditions) How imbalance occurred (left tree off by up to 4) Leading to test and fix
184
Part I Part II Part III Refinement Types Closures, Collections, Generics Induction for Data Structures
185
Take Home Lessons Why is Verification difficult? Complex “Invariants” How to represent invariants? Factor into liquid type How to infer liquid type? Subtyping + Predicate Abstraction
186
“Back-End” Logic Constraint Solving Rich Decidable Logics Predicate Discovery… Much Work Remains…
187
“Front-End” Types Destructive Update Concurrency Objects & Classes Dynamic Languages… Much Work Remains…
188
User Interface The smarter your analysis, the harder to tell why it fails! Much Work Remains…
189
Details Ocaml (Pure functional) [PLDI 08] “Liquid Types” [PLDI 09] “Type-based Data-Structure Verification” Constraint Solving [CAV 11] “Hindley-Milner-Cousots” C (Pointers/Arithmetic, Aliasing, Mutation) [POPL 10] “Low-level Liquid Types”
190
POPL Lightning Talk/Demo Ocaml (Pure functional) [PLDI 08] “Liquid Types” [PLDI 09] “Type-based Data-Structure Verification” Constraint Solving [CAV 11] “Hindley-Milner-Cousots” C (Pointers/Arithmetic, Aliasing, Mutation) [POPL 10] “Low-level Liquid Types” Patrick Rondon (PhD ’12) Demo + Lightning Talk
191
http://goto.ucsd.edu/liquid source, papers, demo, etc.
192
ProgramLines DML Annot. Liquid Annot. Liquid Time(s) dotprod 730 0.3 bsearch 2430 0.5 queens 3070 0.7 insersort 33120 0.9 tower 3681 3.3 matmult 43100 1.8 heapsort 84110 0.5 fft 107131 9.1 simplex 118330 7.7 gauss 142221 3.1 Total 6321253 27.9 Evaluation: Array Bounds Checking
193
DML @ 20% LOC vs. Liquid @ 0.5% LOC
194
The end
195
let rec range l u = if l < u then l :: (range (l+1) u) else [] Template of “ then ”-expression {v:int| X out } list Check: “head” and “tail” as required l ≺ u ⊢ “head” <: {v:int |X out } l ≺ u ⊢ “tail” <: {v:int |X out } list
196
let rec range l u = if l < u then l :: (range (l+1) u) else [] Check: “head” as required l ≺ u ⊢ {v:int | v=l} <: {v:int |X out } l ≺ u Æ v=l ) X out Reduces To 1
197
let rec range l u = if l < u then l :: (range (l+1) u) else [] Check: “tail” as required Template of range l:int ! u:int ! {v:int| X out } list
198
let rec range l u = if l < u then l :: (range (l+1) u) else [] Check: “tail” as required Template of range (l+1) u:int ! {v:int| X out [l+1/l]} list
199
let rec range l u = if l < u then l :: (range (l+1) u) else [] Check: “tail” as required Template of range (l+1) u {v:int| X out [l+1/l][u/u]} list
200
let rec range l u = if l < u then l :: (range (l+1) u) else [] Check: “tail” as required Template of range (l+1) u {v:int| X out [l+1/l]} list { X out [l+1/l]} list <: then-“tail”
201
let rec range l u = if l < u then l :: (range (l+1) u) else [] Check: “tail” as required { X out [l+1/l]} list <: then-“tail” Template of “ then ”-expression {v:int| X out } list
202
let rec range l u = if l < u then l :: (range (l+1) u) else [] Check: “tail” as required { X out [l+1/l]} list <: { X out } list Template of “ then ”-expression {v:int| X out } list
203
let rec range l u = if l < u then l :: (range (l+1) u) else [] Check: “tail” as required { X out [l+1/l]} list <: { X out } list Template of range l:int ! u:int ! {v:int| X out } list
204
let rec range l u = if l < u then l :: (range (l+1) u) else [] Check: “tail” as required { X out [l+1/l]} list <: { X out } list Template of “ then ”-expression {v:int| X out } list
205
let rec range l u = if l < u then l :: (range (l+1) u) else [] Check: “tail” as required { X out [l+1/l]} list <: { X out } list Template of “ then ”-expression {v:int| X out } list
206
let rec range l u = if l < u then l :: (range (l+1) u) else [] Check: “tail” as required { X out [l+1/l]} list <: { X out } list Template of “ then ”-expression {v:int| X out } list
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.