2.06k likes | 2.18k Views
This work by Ranjit Jhala and collaborators from UC San Diego explores advanced techniques in software verification using liquid types. The paper discusses the formulation of algorithms, such as `min_index`, along with their formal specifications and invariants to ensure memory safety. It delves into critical aspects of verification, including type-checking, refinement types, and inductive reasoning. By leveraging liquid types, the authors provide a framework for verifying properties of collections, polymorphism, and data structures, making a significant contribution to the field.
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:???