2.06k likes | 2.18k Views
Software Verification With Liquid Types. Ranjit Jhala , UC San Diego (with Pat Rondon , Ming Kawaguchi). Software Verification. i nt min_index ( int [] a){ r = 0; n = a.length ; for (i = 0; i < n; i++){ if (a[i] < a[r]) r = i; } return r; }.
E N D
Software Verification With Liquid Types RanjitJhala, UC San Diego (with Pat Rondon, Ming Kawaguchi)
Software Verification intmin_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 intmin_index(int [] a){ r = 0; n = a.length; for (i = 0; i < n; i++){ if (a[i] < a[r]) r = i; } return r; } • Access In Array Bounds ?
Example: Memory Safety intmin_index(int [] a){ r = 0; n = a.length; for (i = 0; i < n; i++){ if (a[i] < a[r]) r = i; } return r; } assert (0<=r && r<n) • How to prove assert ?
Example: Memory Safety intmin_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 intmin_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; } • By Man [Floyd-Hoare] • Or Machine[Cousot-Cousot]
But, what of … Closures Collections Polymorphism Data Structures …?
But, what of … H-O Logics? Quantifiers? Induction?
H-O Logics? Quantifiers? Induction? A Solution: Types
Part I • Types and Invariants • Part II • Closures, Collections, Generics • Part III • Induction for Data Structures
Part I • Types and Invariants
Part I • Refinement Types [Zenger ’97, Owre-Rushby-Shankar ’98, Xi-Pfenning ’98]
let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 min_index:a:intarray->int
let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 Refinement min_index:{a:intarray|0≺ a.len}->{v:int|0≼v≺a.len} Type
let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 “Requires” min_index:{a:intarray|0≺ a.len}->{v:int|0≼v≺a.len}
let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 “Ensures” min_index:{a:intarray|0≺ a.len}->{v:int|0≼v≺a.len}
let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 loop: {r:int|0≼ r≺ a.len}->{i:int|0≼i}->{v:int|0≼ v≺ a.len}
let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 loop: {r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len}
let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 loop: {r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len} “Requires”
let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 loop: {r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len} “Ensures”
Part I • Refinement Types • 1. Type-checking • 2. Refine-checking • 3. Refine-Inference
loop : r:int -> i:int -> int let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 1 Assume Prove output is int • loop : … • r : int • i: int ⊢ r “subtype-of” int
loop : r:int -> i:int -> int let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 1 Assume Prove output is int • loop : … • r : int • i: int ⊢ r <: int
loop : r:int -> i:int -> int let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 1 2 Assume Prove index is int • loop : … • r : int • i: int ⊢ i <: int
loop : r:int -> i:int -> int let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 1 2 3 Assume Prove input is int • loop : … • i : int • r : int • r': int • i': int ⊢ r' <: int
loop : r:int -> i:int -> int let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 1 2 3 4 Assume Prove output is int • loop : … • i : int • r : int • r': int • i': int ⊢ loopr'i'<: int
loop : r:int -> i:int -> int let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 1 2 3 4 5 Assume Prove input is int • loop : … • i : int • r : int • r': int • i': int ⊢ 0 <: int
Part I • Refinement Types • 1. Type-checking • 2. Refine-checking • 3. Refine-Inference
let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 min_index {a:0≺a.len}->{v:0≼v≺ a.len} loop {r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len}
loop:{r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len} let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 1 2 3 4 5 Assume Prove output is ensured • r :0≼ r≺ a.len • i :0≼ i • [i≽ a.len]
loop:{r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len} let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 1 Assume Prove output is ensured • r :0≼ r≺ a.len • i :0≼ i • [i≽ a.len] ⊢ {v=r}<:{0≼ v≺ a.len}
loop:{r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len} let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 1 Assume Prove output is ensured • r :0≼ r≺ a.len • i :0≼ i • [i≽ a.len] ⊢ {v=r}<:{0≼ v≺ a.len}
loop:{r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len} let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 1 Assume Prove output is ensured 0≼ r≺ a.len ⋀0≼ i ⋀i≽ a.len ⊢ {v=r}<:{0≼ v≺ a.len}
loop:{r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len} let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 1 Assume Prove output is ensured 0≼ r≺ a.len ⋀0≼ i ⋀i≽ a.len ⋀ {v=r}<:{0≼ v≺ a.len}
loop:{r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len} let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 1 Assume Prove output is ensured 0≼ r≺ a.len ⋀0≼ i ⋀i≽ a.len ⇒ ⋀ v=r0≼ v≺ a.len
loop:{r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len} let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 1 0≼ r≺ a.len ⋀0≼ i ⋀i≽ a.len Is Valid? Yes. ⇒ ⋀ v=r0≼ v≺ a.len
loop:{r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len} let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 1 2 4 3 5 Assume Prove index in bounds • r :0≼ r≺ a.len • i :0≼ i • [i≺ a.len] ⊢ {v=i}<:{0≼ v≺ a.len} • [i≺ a.len]
loop:{r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len} let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 2 0≼ r≺ a.len ⋀0≼ i ⋀i≺ a.len Is Valid? Yes. ⇒ ⋀ v=i0≼ v≺ a.len
loop:{r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len} let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 1 2 4 3 5 Prove input as required ⊢ {v=r'}<:{0≼ v≺ a.len}
loop:{r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len} let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 3 Assume Prove input as required • r :0≼ r≺ a.len • i :0≼ i • [i≺ a.len] • i':i'=i+1 ⊢ {v=r'}<:{0≼ v≺ a.len} r':r'=i∨r'=r
loop:{r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len} let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 3 • 0≼ r≺ a.len • ⋀ 0≼ i • ⋀i≺ a.len • ⋀ r'=i∨r'=r • ⋀ i'=i+1 Is Valid? Yes! ⇒ ⋀ v=r'0≼ v≺ a.len
loop:{r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len} let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 1 2 4 3 5 Prove output is ensured ⊢ {0≼ v≺a.len}<:{0≼ v≺a.len} Trivial.
loop:{r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len} let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 1 2 4 3 5 Assume Prove input as required ⊢ {v=0}<:{0≼ v≺a.len} • a :0≺ a.len
loop:{r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len} let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 5 Is Valid? Indeed. ⇒ ⋀ v=0 0≼ v≺a.len • 0≺ a.len
Part I • Refinement Types • 1. Type-checking • 2. Refine-checking • 3. Refine-Inference
let min_indexa = let rec loopr i = if i>= a.lengththen r else let r' = a[i] < a[r] ? i : r let i' = i + 1 loopr' i' loop 0 0 min_index {a:0≺a.len}->{v:0≼v≺ a.len} loop {r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len}
Writing Types is Hard Work! min_index {a:0≺a.len}->{v:0≼v≺ a.len} loop {r:0≼ r≺a.len}->{i:0≼i}->{v:0≼v≺ a.len}
Automatic Refinement Inference • Writing Types is Hard Work! loop:???
Automatic Refinement Inference • 1. Templates • 2. Constraints • 3. Fixpoint[MC/AI] loop:???