Top Banner
Software Verification With Liquid Types Ranjit Jhala, UC San Diego (with Pat Rondon, Ming Kawaguchi)
206

Software Verification With Liquid Types

Feb 22, 2016

Download

Documents

tillie

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; }. - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Software Verification With Liquid Types

Software VerificationWith Liquid Types

Ranjit Jhala, UC San Diego(with Pat Rondon, Ming Kawaguchi)

Page 2: Software Verification With Liquid Types

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

Page 3: Software Verification With Liquid Types

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 ?

Page 4: Software Verification With Liquid Types

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)

Page 5: Software Verification With Liquid Types

int min_index(int [] a){ r = 0; n = a.length; //@invariant: 0·iÆ 0·r Æ

r<nfor (i = 0; i < n; i++){

if (a[i] < a[r]) r = i; } return r;}

Example: Memory Safety

Page 6: Software Verification With Liquid Types

int min_index(int [] a){ r = 0; n = a.length; //@invariant: 0·iÆ 0·r Æ

r<nfor (i = 0; i < n; i++){

if (a[i] < a[r]) r = i; } return r;}

Invariants

By Man [Floyd-Hoare]Or Machine [Cousot-Cousot]

Page 7: Software Verification With Liquid Types

But, what of …

ClosuresCollections

PolymorphismData Structures …?

Page 8: Software Verification With Liquid Types

H-O Logics?Quantifiers?

Induction?

But, what of …

Page 9: Software Verification With Liquid Types

Automation

Page 10: Software Verification With Liquid Types

H-O Logics?Quantifiers?

Induction?A Solution: Types

Page 11: Software Verification With Liquid Types

Part I

Part II

Part III

Types and Invariants

Closures, Collections, Generics

Induction for Data Structures

Page 12: Software Verification With Liquid Types

Part ITypes and Invariants

Page 13: Software Verification With Liquid Types

Part IRefinement Types

[Zenger ’97, Owre-Rushby-Shankar ’98, Xi-Pfenning ’98]

Page 14: Software Verification With Liquid Types

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

Page 15: Software Verification With Liquid Types

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

Page 16: Software Verification With Liquid Types

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

Page 17: Software Verification With Liquid Types

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

Page 18: Software Verification With Liquid Types

{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

Page 19: Software Verification With Liquid Types

{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

Page 20: Software Verification With Liquid Types

{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

Page 21: Software Verification With Liquid Types

{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

Page 22: Software Verification With Liquid Types

Part IRefinement Types

1. Type-checking2. Refine-checking3. Refine-Inference

Page 23: Software Verification With Liquid Types

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⊢

Page 24: Software Verification With Liquid Types

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⊢

Page 25: Software Verification With Liquid Types

loop : r:int -> i:int -> int

Assume

12

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 0loop : … r : int i : int

Prove index is int⊢ i <: int

Page 26: Software Verification With Liquid Types

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

Page 27: Software Verification With Liquid Types

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

Page 28: Software Verification With Liquid Types

loop : r:int -> i:int -> int

Assume Prove 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

Page 29: Software Verification With Liquid Types

Part IRefinement Types

1. Type-checking2. Refine-checking3. Refine-Inference

Page 30: Software Verification With Liquid Types

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}

Page 31: Software Verification With Liquid Types

r :0≼ r≺ a.leni :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]

Page 32: Software Verification With Liquid Types

r :0≼ r≺ a.leni :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}

Page 33: Software Verification With Liquid Types

r :0≼ r≺ a.leni :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}

Page 34: Software Verification With Liquid Types

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

Page 35: Software Verification With Liquid Types

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 ⋀

Page 36: Software Verification With Liquid Types

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

Page 37: Software Verification With Liquid Types

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.lenIs Valid?Yes. ⇒

Page 38: Software Verification With Liquid Types

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.leni :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]

Page 39: Software Verification With Liquid Types

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.lenIs Valid?Yes.

2

Page 40: Software Verification With Liquid Types

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

Page 41: Software Verification With Liquid Types

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 0r :0≼ r≺ a.leni :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

Page 42: Software Verification With Liquid Types

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

Page 43: Software Verification With Liquid Types

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.

Page 44: Software Verification With Liquid Types

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.lenProve 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

Page 45: Software Verification With Liquid Types

⇒⋀

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

Page 46: Software Verification With Liquid Types

Part IRefinement Types

1. Type-checking2. Refine-checking3. Refine-Inference

Page 47: Software Verification With Liquid Types

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}

Page 48: Software Verification With Liquid Types

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!

Page 49: Software Verification With Liquid Types

Automatic Refinement Inference

Writing Types is Hard Work!

loop: ???

Page 50: Software Verification With Liquid Types

Automatic Refinement Inference

1. Templates2. Constraints 3. Fixpoint [MC/AI]

loop: ???

Page 51: Software Verification With Liquid Types

Automatic Refinement Inference

1. Templates2. Constraints 3. Fixpoint [MC/AI]

loop : r:int -> i:int -> int

Page 52: Software Verification With Liquid Types

Automatic Refinement Inference

1. Templates2. Constraints 3. Fixpoint [MC/AI]

loop : {r:int|?} -> {i:int|?} ->

{v:int|?}

Page 53: Software Verification With Liquid Types

Automatic Refinement Inference

1. Templates2. Constraints 3. Fixpoint [MC/AI]

loop :{r:int|Xr} -> {i:int|Xi} -> {v:int|Xout}

Types + X for unknown refinements

Page 54: Software Verification With Liquid Types

Automatic Refinement Inference

1. Templates2. Constraints 3. Fixpoint [MC/AI]

loop :{r:int|Xr} -> {i:int|Xi} -> {v:int|Xout}

Page 55: Software Verification With Liquid Types

Automatic Refinement Inference

1. Templates2. Constraints 3. Fixpoint [MC/AI]Type Checking, but with Templates

Page 56: Software Verification With Liquid Types

r : Xr

i : Xi

[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|Xr} -> {i:int|Xi} -> {v:int|Xout}

⊢ {v=r} <:

{Xout}

Page 57: Software Verification With Liquid Types

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|Xr} -> {i:int|Xi} -> {v:int|Xout}

⋀ Xr ⋀ Xi ⋀ i≽ a.lenIs Valid? ⇒ v=r Xout

“It is too soon to say. ”

Page 58: Software Verification With Liquid Types

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|Xr} -> {i:int|Xi} -> {v:int|Xout}

Xr ⋀ Xi ⋀ i≽ a.len ⋀ v=r ⇒ XoutConstraint 1

Page 59: Software Verification With Liquid Types

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|Xr} -> {i:int|Xi} -> {v:int|Xout}

r : Xr

i : Xi

[i≺ a.len]

Page 60: Software Verification With Liquid Types

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

Xr ⋀ Xi ⋀i≺ a.len ⋀ v=i ⇒ 0≼ v≺ a.lenConstraint 2

Page 61: Software Verification With Liquid Types

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|Xr}

1

3 4

2

5

loop :{r:int|Xr} -> {i:int|Xi} -> {v:int|Xout}

Assume r :Xr

i :Xi

[i≺ a.len]r':r'=i ∨ r'=ri':i'=i+1

Page 62: Software Verification With Liquid Types

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

Xr ⋀ Xi ⋀ i≺ a.len ⋀ (r'=i∨ r'=r) ⋀ v=r' Xr[v/r ]⇒

Page 63: Software Verification With Liquid Types

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|Xr} -> {i:int|Xi} -> {v:int|Xout}

Constraint 4

Xr ⋀ Xi ⋀ i≺ a.len ⋀ (r'=i∨ r'=r) ⋀ Xout Xout⇒

Page 64: Software Verification With Liquid Types

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|Xr} -> {i:int|Xi} -> {v:int|Xout}

Constraint 5 0≺ a.len ⋀ v=0 Xr[v/r ]⇒

Page 65: Software Verification With Liquid Types

Automatic Refinement Inference

1. Templates2. Constraints 3. Fixpoint [MC/AI]Type Checking, but with Templates

Page 66: Software Verification With Liquid Types

Automatic Refinement Inference

1. Templates2. Constraints 3. Fixpoint [MC/AI]

0≺ a.len ⋀ v=0 ⇒ Xr[v/r ]

1

Xr ⋀ Xi ⋀ i≺ a.len ⋀ (r'=i∨ r'=r) ⋀ Xout ⇒ Xout

Xr ⋀ Xi ⋀ i≺ a.len ⋀ (r'=i∨ r'=r) ⋀ v=r' ⇒ Xr[v/r ]

Xr ⋀ Xi ⋀i≺ a.len ⋀ v=i ⇒ 0≼ v≺ a.lenXr ⋀ Xi ⋀ i≽ a.len ⋀ v=r ⇒ Xout

2345

Page 67: Software Verification With Liquid Types

Automatic Refinement Inference

1. Templates2. Constraints 3. Fixpoint [MC/AI]

Xr ⋀ Xi ⋀ i≺ a.len ⋀ (r'=i∨ r'=r) ⋀ Xout ⇒ Xout 4

⋀Xi ⋀ P ⇒ X

Page 68: Software Verification With Liquid Types

Automatic Refinement Inference

1. Templates2. Constraints 3. Fixpoint [MC/AI]

Xr ⋀ Xi ⋀ i≺ a.len ⋀ (r'=i∨ r'=r) ⋀ Xout ⇒ Xout 4

⋀Xi ⋀ P ⇒ X

Page 69: Software Verification With Liquid Types

Automatic Refinement Inference

1. Templates2. Constraints 3. Fixpoint [MC/AI]

Xr ⋀ Xi ⋀ i≺ a.len ⋀ (r'=i∨ r'=r) ⋀ Xout ⇒ Xout 4

⋀Xi ⋀ P ⇒ X

Page 70: Software Verification With Liquid Types

Automatic Refinement Inference

1. Templates2. Constraints 3. Fixpoint [MC/AI]

0≺ a.len ⋀ v=0 ⇒ Xr[v/r ]

1

Xr ⋀ Xi ⋀ i≺ a.len ⋀ (r'=i∨ r'=r) ⋀ Xout ⇒ Xout

Xr ⋀ Xi ⋀ i≺ a.len ⋀ (r'=i∨ r'=r) ⋀ v=r' ⇒ Xr[v/r ]

Xr ⋀ Xi ⋀ i≽ a.len ⋀ v=r ⇒ Xout

2345

Xr ⋀ Xi ⋀i≺ a.len ⋀ v=i ⇒ 0≼ v≺ a.len⋀Xi ⋀ P ⇒ Q

Page 71: Software Verification With Liquid Types

Automatic Refinement Inference

1. Templates2. Constraints 3. Fixpoint [MC/AI]

0≺ a.len ⋀ v=0 ⇒ Xr[v/r ]

1

Xr ⋀ Xi ⋀ i≺ a.len ⋀ (r'=i∨ r'=r) ⋀ Xout ⇒ Xout

Xr ⋀ Xi ⋀ i≺ a.len ⋀ (r'=i∨ r'=r) ⋀ v=r' ⇒ Xr[v/r ]

Xr ⋀ Xi ⋀ i≽ a.len ⋀ v=r ⇒ Xout

2345

Xr ⋀ Xi ⋀i≺ a.len ⋀ v=i ⇒ 0≼ v≺ a.len⋀Xi ⋀ P ⇒ Q

Page 72: Software Verification With Liquid Types

Automatic Refinement Inference

1. Templates2. Constraints 3. Fixpoint [MC/AI]

0≺ a.len ⋀ v=0 ⇒ Xr[v/r ]

1

Xr ⋀ Xi ⋀ i≺ a.len ⋀ (r'=i∨ r'=r) ⋀ Xout ⇒ Xout

Xr ⋀ Xi ⋀ i≺ a.len ⋀ (r'=i∨ r'=r) ⋀ v=r' ⇒ Xr[v/r ]

Xr ⋀ Xi ⋀ i≽ a.len ⋀ v=r ⇒ Xout

2345

Xr ⋀ Xi ⋀i≺ a.len ⋀ v=i ⇒ 0≼ v≺ a.len⋀Xi ⋀ P ⇒ Q

Page 73: Software Verification With Liquid Types

Automatic Refinement Inference

1. Templates2. Constraints 3. Fixpoint [MC/AI]

⋀Xi ⋀ P ⇒ Q⋀Xi ⋀ P ⇒ X (Post*)

(Safe)

Page 74: Software Verification With Liquid Types

Automatic Refinement Inference

1. Templates2. Constraints 3. Fixpoint [MC/AI]⋀Xi ⋀ P ⇒ X⋀Xi ⋀ P ⇒ Q

Page 75: Software Verification With Liquid Types

Automatic Refinement Inference

Fixpoint Solution ⋀Xi ⋀ P ⇒ X⋀Xi ⋀ P ⇒ Q

“Horn Clauses”

Page 76: Software Verification With Liquid Types

Automatic Refinement Inference

Fixpoint Solution ⋀Xi ⋀ P ⇒ X⋀Xi ⋀ P ⇒ Q

“Positive Implications”

Page 77: Software Verification With Liquid Types

Automatic Refinement Inference

Fixpoint Solution ⋀Xi ⋀ P ⇒ X⋀Xi ⋀ P ⇒ Q

“Non-Linear Implications”

Page 78: Software Verification With Liquid Types

Automatic Refinement Inference

Fixpoint Solution ⋀Xi ⋀ P ⇒ X⋀Xi ⋀ P ⇒ Q

1. Reduce to simple “first-order” program Reuse any abs-interpreter, model-checker e.g. Interproc, SLAM, BLAST, ARMC [CAV 11]

Page 79: Software Verification With Liquid Types

Automatic Refinement Inference

Fixpoint Solution ⋀Xi ⋀ P ⇒ X⋀Xi ⋀ P ⇒ Q

2. Monomial Predicate Abstraction (“Houdini”) Input : Candidates Q = {q1…qn} Output : X ↦ ⋀qj satisfying constraints

Page 80: Software Verification With Liquid Types

Automatic Refinement Inference

Fixpoint Solution ⋀Xi ⋀ P ⇒ X⋀Xi ⋀ P ⇒ Q

2. Monomial Predicate Abstraction (“Houdini”) Input : Q = {⋆≼ v, v≼ ⋆, v≺ ⋆, v≺ ⋆.len} ⋆ = any variable or constant

Page 81: Software Verification With Liquid Types

Automatic Refinement Inference

Fixpoint Solution ⋀Xi ⋀ P ⇒ X⋀Xi ⋀ P ⇒ Q

2. Monomial Predicate Abstraction (“Houdini”) Input : Q = {⋆≼ v, v≼ ⋆, v≺ ⋆, v≺ ⋆.len} Output : Xr = 0≼ v ⋀ v≺ a.len

Xi = 0≼ v Xout = 0≼ v ⋀ v≺ a.len

Page 82: Software Verification With Liquid Types

2. Monomial Predicate Abstraction (“Houdini”) Input : Q = {⋆≼ v, v≼ ⋆, v≺ ⋆, v≺ ⋆.len} Output : Xr = 0≼ v ⋀ v≺ a.len

Xi = 0≼ v Xout = 0≼ v ⋀ v≺ a.len

Automatic Refinement Inference

Plug Solution In Template

loop:{r:int|Xr} -> {i:int|Xi} -> {v:int|Xout}

Page 83: Software Verification With Liquid Types

2. Monomial Predicate Abstraction (“Houdini”) Input : Q = {⋆≼ v, v≼ ⋆, v≺ ⋆, v≺ ⋆.len} Output : Xr = 0≼ v ⋀ v≺ a.len

Xi = 0≼ v Xout = 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}

Page 84: Software Verification With Liquid Types

Automatic Refinement Inference

loop:{r:int|0≼r≺a.len}->{i:int|0≼ i}->{v:int|0≼

v≺a.len}Inferred Refinement Type

Page 85: Software Verification With Liquid Types

Automatic Refinement Inference

loop:{r:int|0≼r≺a.len}->{i:int|0≼ i}->{v:int|0≼

v≺a.len}Liquid Type of loop

Page 86: Software Verification With Liquid Types

RecapProgram

Templates

Constraints

AI, MC, PA …

{i:int|Xi} -> {v:int|Xo}

⋀Xi ⋀ P ⇒ X

Page 87: Software Verification With Liquid Types

Part I

Part II

Part III

Liquid Types

Closures, Collections, Generics

Induction for Data Structures

Page 88: Software Verification With Liquid Types

Part I

Part II

Part III

Refinement Types

Closures, Collections, Generics

Induction for Data Structures

Page 89: Software Verification With Liquid Types

Closures / Higher-Order Functions

let rec ffor l u f = if l < u then f l; ffor (l+1) u f

Page 90: Software Verification With Liquid Types

let rec ffor l u f =

if l < u then ( f l; ffor (l+1) u f )

Type of f

int ! unit

Page 91: Software Verification With Liquid Types

let rec ffor l u f =

if l < u then ( f l; ffor (l+1) u f )

Template of f

{v:int|X1}!unit

Page 92: Software Verification With Liquid Types

let rec ffor l u f =

if l < u then ( f l; ffor (l+1) u f )

Template of f

{v:int|X1}!unit

Check: input l as required by f

Page 93: Software Verification With Liquid Types

let rec ffor l u f =

if l < u then ( f l; ffor (l+1) u f )

Template of f

{v:int|X1}!unit

l≺ u ⊢ {v:int|v=l} <: {v:int|X1}

l≺ u Æ v=l ) X1

Solution X1 = l≼ v Æ v≺ u

Reduces to

Page 94: Software Verification With Liquid Types

let rec ffor l u f =

if l < u then ( f l; ffor (l+1) u f )

Template of f

{v:int|X1}!unitSolution

X1 = l≼ v Æ v≺ u

Liquid Type of f

{v:int|l≼ v Æ v≺ u} ! unit

Page 95: Software Verification With Liquid Types

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

Page 96: Software Verification With Liquid Types

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

Page 97: Software Verification With Liquid Types

Liquid Type of fforl: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

Page 98: Software Verification With Liquid Types

Liquid Type of ffor 0u: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

Page 99: Software Verification With Liquid Types

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

Page 100: Software Verification With Liquid Types

Liquid Type of ffor 0 a.len

({v:int|0 ≼ v≺ a.len}!unit)!unit

Template of (fun i ->...)

{v:int|Xi} ! unit

let min_index a = let r = ref 0 ffor 0 a.len (fun i -> if a.(i) < a.(!r) then r:= i)

!r

Page 101: Software Verification With Liquid Types

Liquid Type of ffor 0 a.len

({v:int|0 ≼ v≺ a.len}!unit)!unit

Template of (fun i ->...)

{v:int|Xi} ! unit

let min_index a = let r = ref 0 ffor 0 a.len (fun i -> if a.(i) < a.(!r) then r:= i)

!rCheck: input (fun i... ) as required by

ffor

Page 102: Software Verification With Liquid Types

Liquid Type of ffor 0 a.len

({v:int|0 ≼ v≺ a.len}!unit)!unit

Template of (fun i ->...)

{v:int|Xi} ! unit

{Xi}!unit <:{0≼v≺a.len}!unit

Check: input (fun i... ) as required by ffor

Page 103: Software Verification With Liquid Types

{0≼v≺a.len}

unit{Xi} unit{Xi}!unit <:{0≼v≺a.len}!unit

{0≼v≺a.len} <:

{Xi}unit <: unit

Trivial

Function Subtyping Splits Into

Page 104: Software Verification With Liquid Types

Function Subtyping Splits Into

{Xi}!unit <:{0≼v≺a.len}!unit

0≼v≺ a.len ) Xi

Page 105: Software Verification With Liquid Types

0≼v≺ a.len ) Xi

Solution Xi = 0≼v≺ a.len

Page 106: Software Verification With Liquid Types

Solution Xi = 0≼v≺ a.lenTemplate of (fun i ->...)

{v:int|Xi} ! unit

Page 107: Software Verification With Liquid Types

Solution Xi = 0≼v≺ a.lenLiquid Type of (fun i ->...)

{v:int | 0≼v≺ a.len} ! unit

Page 108: Software Verification With Liquid Types

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

Page 109: Software Verification With Liquid Types

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

Page 110: Software Verification With Liquid Types

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_indexa:int array ! {v:int | 0≼v≺ a.len}

Page 111: Software Verification With Liquid Types

Part I

Part II

Part III

Refinement Types

Closures, Collections, Generics

Induction for Data Structures

Page 112: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u)

else []

Collections (e.g. Lists)

Type of rangel:int ! u:int ! int list

Page 113: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u)

else []

Collections (e.g. Lists)

Template of rangel:int ! u:int ! {v:int|Xout} list

Page 114: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u)

else []

Template of rangel:int ! u:int ! {v:int|Xout} list

Template of “then”: {v:int|Xout} list

Page 115: Software Verification With Liquid Types

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|Xout} list

Page 116: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u)

else []

Check: “head” and “tail” as requiredl≺ u ⊢ “head” <: {v:int|Xout}

Template of “then”: {v:int|Xout} list

Page 117: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u)

else []

Check: “head” and “tail” as requiredl≺ u ⊢ “head” <: {v:int|Xout}l≺ u ⊢ “tail” <: {v:int|Xout} list

Template of “then”: {v:int|Xout} list

Page 118: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u)

else []

Check: “head” and “tail” as requiredl≺ u ⊢ “head” <: {v:int|Xout}

Page 119: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u)

else []

l≺ u Æ v=l ) Xout

Reduces To(1)

Check: “head” and “tail” as requiredl≺ u ⊢ {v:int|v=l} <: {v:int|Xout}

Page 120: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u)

else []

Check: “head” and “tail” as requiredl≺ u ⊢ “tail” <: {v:int|Xout} list

Page 121: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u)

else []

Check: “head” and “tail” as requiredl≺ u ⊢ {Xout[l+1/l]} list <: {Xout }

list By List-Subtyping, Reduces Tol≺ u ⊢ {Xout[l+1/l]} <: {Xout

}

Page 122: Software Verification With Liquid Types

Check: “head” and “tail” as requiredl≺ u ⊢ {Xout[l+1/l]} list <: {Xout }

list Reduces To(2)l≺ u Æ Xout[l+1/l] ) Xout

Page 123: Software Verification With Liquid Types

(2)(1)

Solution Xout = l≼v≺ ul≺ u Æ v=l ) Xout

l≺ u Æ Xout[l+1/l] ) Xout

Page 124: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u)

else []

Collections (e.g. Lists)

Template of rangel:int ! u:int ! {v:int|Xout} list

Solution Xout = l≼v≺ u

Page 125: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u)

else []

Collections (e.g. Lists)

Liquid Type of rangel:int!u:int!{v:int|l≼v≺ u} list

Solution Xout = l≼v≺ u

Page 126: Software Verification With Liquid Types

Part I

Part II

Part III

Refinement Types

Closures, Collections, Generics

Induction for Data Structures

Page 127: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u) else []

Generics/Polymorphism

Page 128: Software Verification With Liquid Types

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

Page 129: Software Verification With Liquid Types

Instance Typea = intb = 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

Page 130: Software Verification With Liquid Types

Generic Type of fold_left(a ! b! a) ! a ! b list ! a

Instance Templatea = {v:int| Xa }b = {v:int| Xb }

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

Page 131: Software Verification With Liquid Types

Instance Template of fold_left({Xa}!{Xb}!{Xa})!{Xa}!{Xb}list!{Xa}

Instance Templatea = {v:int| Xa }b = {v:int| Xb }

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

Page 132: Software Verification With Liquid Types

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 indicesInstance Template of fold_left

({Xa}!{Xb}!{Xa})!{Xa}!{Xb}list!{Xa}

Template of r{v:int | Xa }

Page 133: Software Verification With Liquid Types

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 indicesInstance Template of fold_left

({Xa}!{Xb}!{Xa})!{Xa}!{Xb}list!{Xa}

Template of i{v:int | Xb }

Page 134: Software Verification With Liquid Types

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 indicesInstance Template of fold_left

({Xa}!{Xb}!{Xa})!{Xa}!{Xb}list!{Xa}

Template of min_indexa:int array ! {v:int | Xa }

Page 135: Software Verification With Liquid Types

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 indicesInstance Template of fold_left

({Xa}!{Xb}!{Xa})!{Xa}!{Xb}list!{Xa}

Check: args as required

Page 136: Software Verification With Liquid Types

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 indicesInstance Template of fold_left

({Xa}!{Xb}!{Xa})!{Xa}!{Xb}list!{Xa}

Check: args as required

1

Page 137: Software Verification With Liquid Types

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 indicesInstance Template of fold_left

({Xa}!{Xb}!{Xa})!{Xa}!{Xb}list!{Xa}

Check: args as required

12

Page 138: Software Verification With Liquid Types

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 indicesInstance Template of fold_left

({Xa}!{Xb}!{Xa})!{Xa}!{Xb}list!{Xa}

Check: args as required

123

Page 139: Software Verification With Liquid Types

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

123

r:int!i:int!{v=i ∨ v=r} <: {Xa}!{Xb}!{Xa}

{v:int | v=0} <: {v:int | Xa}

{v:int | 0≼ v≺ a.len} list <: {v:int | Xb}

list

123

Page 140: Software Verification With Liquid Types

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

123

r:int!i:int!{v=i ∨ v=r} <: {Xa}!{Xb}!{Xa}

{v:int | v=0} <: {v:int | Xa}

{v:int | 0≼ v≺ a.len} list <: {v:int | Xb}

list

Xa[r/v]Æ Xb[i/v]Æ (v=i ∨ v=r) ) Xav=0 ) Xa

0≼ v≺ a.len ) Xb

123

Page 141: Software Verification With Liquid Types

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 Xa , Xb = 0≼ v≺ a.len

Page 142: Software Verification With Liquid Types

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 Xa , Xb = 0≼ v≺ a.lenTemplates

r : {v:int|Xa}i : {v:int|Xb}

Page 143: Software Verification With Liquid Types

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 Xa , Xb = 0≼ v≺ a.lenLiquid Types

r : {v:int| 0≼ v≺ a.len}i : {v:int| 0≼ v≺ a.len}

Page 144: Software Verification With Liquid Types

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 Xa , Xb = 0≼ v≺ a.lenLiquid Types

r : {v:int| 0≼ v≺ a.len}i : {v:int| 0≼ v≺ a.len}

Safe

Page 145: Software Verification With Liquid Types

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 Xa , Xb = 0≼ v≺ a.lenTemplate of min_index

a:int array ! {v:int | Xa }

Page 146: Software Verification With Liquid Types

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 Xa , Xb = 0≼ v≺ a.lenLiquid Type of min_index

a:int array ! {v:int | 0≼v≺ a.len}

Page 147: Software Verification With Liquid Types

Part I

Part II

Part III

Refinement Types

Closures, Collections, Generics

Induction for Data Structures

Page 148: Software Verification With Liquid Types

Part I

Part II

Part III

Refinement Types

Closures, Collections, Generics

Induction for Data Structures

Page 149: Software Verification With Liquid Types

Part I

Part II

Part III

Refinement Types

Closures, Collections, Generics

Induction for Data Structures

Page 150: Software Verification With Liquid Types

Data (Structure) Properties

Piggyback Predicates On Types

Page 151: Software Verification With Liquid Types

[] ::

{x:int|0<x} listint list0<x Describes all elementsx:int

Representation

Page 152: Software Verification With Liquid Types

[] ::

0<xx:int

Type Unfolding

[] ::

0<hh:int

[] ::

0<xx:int

Head TailEmptyPositive Property holds recursivelyList of positive integers

Page 153: Software Verification With Liquid Types

[] ::

0<x Describes all elementsx:int

x<v v Describes tail elements

Representation

Page 154: Software Verification With Liquid Types

[] ::x<v

x:int

Type Unfolding

[] ::

h:int

[] ::x<v

x:int

Head TailEmptyElements larger than head Property holds recursively

List of sorted integers

h<v

Push Edge Predicate Into NodeRename Variable

h<x

Page 155: Software Verification With Liquid Types

Piggyback Predicates On Types

Data (Structure) Properties

Page 156: Software Verification With Liquid Types

[] ::

x:intUnfold

::

h:int

[] ::

x:int

l:sorted list h:int t:sorted

list & {h<x}

list

Instantiate

tl

match l with

h::t

x<Vx<V

h<x

Quantifier Instantiation

Page 157: Software Verification With Liquid Types

Piggyback Predicates On Types

Data (Structure) Properties

Page 158: Software Verification With Liquid Types

[] ::

x:intFold

h:int

[] ::

x:int

::

l:sorted list h:int t:sorted

list & {h<x}

listGeneralize

tllet l = h::t in

x<Vx<V

h<x

Quantifier Generalization

Page 159: Software Verification With Liquid Types

Another Example: Trees

Leaf

Node

x:int

x<VV<x

Page 160: Software Verification With Liquid Types

Node

Leaf

Node

x:int

Leaf

Node

x:int

Node

Leaf

x<VV<x x<VV<x

r<VV<r

Another Example: Trees

r:int

Unfold

Page 161: Software Verification With Liquid Types

< RHS nodesLHS nodes < root

Node

Leaf

Node

x:int

Leaf

Node

x:int

Node

Leaf

x<VV<x x<VV<x

r<xx<r

Another Example: Trees

r:int

Push Edge Predicates

Invariant: Binary Search Trees

Page 162: Software Verification With Liquid Types

Demoisort,bst

Page 163: Software Verification With Liquid Types

Part I

Part II

Part III

Refinement Types

Closures, Collections, Generics

Induction for Data Structures

Page 164: Software Verification With Liquid Types

Piggyback Predicates On Types

(Data) Structure Properties

Page 165: Software Verification With Liquid Types

measure len =| [] -> 0 | x::xs -> 1 + len xs

Representation: List Length

Page 166: Software Verification With Liquid Types

Representation: List Length

8l,x,xs. len([]) = 0 len(x::xs) = 1+len(xs)

Page 167: Software Verification With Liquid Types

Piggyback Predicates On Types

(Data) Structure Properties

Page 168: Software Verification With Liquid Types

l:’a listl:’a listh:’at:’a listlen(l)=1+len(t)

Instantiate

match l with

h::t

Quantifier Instantiation

8l,x,xs. len([]) = 0 len(x::xs) = 1+len(xs)

Page 169: Software Verification With Liquid Types

Piggyback Predicates On Types

(Data) Structure Properties

Page 170: Software Verification With Liquid Types

h:’at:’a list

Quantifier Generalization

8l,x,xs. len([]) = 0 len(x::xs) = 1+len(xs)

Generalize

let l = h::t in h:’at:’a listl:’a listlen(l)=1+len(t)

Page 171: Software Verification With Liquid Types

Demolistlen, msortb

Page 172: Software Verification With Liquid Types

Part I

Part II

Part III

Refinement Types

Closures, Collections, Generics

Induction for Data Structures

Page 173: Software Verification With Liquid Types

Part I

Part II

Part III

Refinement Types

Closures, Collections, Generics

Induction for Data Structures

Page 174: Software Verification With Liquid Types

Leaf

l r

l = Left subtreer = Right subtree

treeHeight

H l = Left subtree’s heightH 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

Page 175: Software Verification With Liquid Types

Demoeval

Page 176: Software Verification With Liquid Types

Refinement Type InferenceBy Predicate Abstraction

Page 177: Software Verification With Liquid Types

0<x

[] ::

x:int

x<v

Automatic Inference

Predicates Determine InvariantLet X1, X2, ... = Unknown Predicates

Complex Subtyping Between data types

X1

X2

Reduces To Simple Implications Between X1, X2, ...

Solved by Predicate AbstractionOver atoms 0<⋆, ⋆<v, ...

Page 178: Software Verification With Liquid Types

Part I

Part II

Part III

Refinement Types

Closures, Collections, Generics

Induction for Data Structures

Page 179: Software Verification With Liquid Types

Program (ML) Verified Safety PropertiesList-based Sorting Sorted, Outputs Permutation of Input

Finite Map Balance, BST, Implements a SetRed-Black Trees Balance, BST, Color

Stablesort SortedExtensible Vectors Balance, Bounds Checking, …

Binary Heaps Heap, Returns Min, Implements SetSplay Heaps BST, Returns Min, Implements Set

Malloc Used and Free Lists Are AccurateBDDs Variable Order

Union Find AcyclicityBitvector Unification Acyclicity

Page 180: Software Verification With Liquid Types

Finite Maps (ML)5: ‘cat’

3: ‘cow’ 8: ‘tic’

1: ‘doc’ 4: ‘hog’ 7: ‘ant’ 9: ‘emu’From Ocaml Standard Library

Implemented as AVL TreesRotate/Rebalance on Insert/Delete

Verified InvariantsBinary Search Ordered

Height BalancedKeys Implement Set

Page 181: Software Verification With Liquid Types

Binary Decision Diagrams (ML)X1

X2 X2

X3

X4 X4

1

Graph-Based Boolean Formulas [Bryant 86]

X1ÛX2 Ù X3ÛX4 Efficient Formula Manipulation

Memoizing Results on SubformulasVerified Invariant

Variables Ordered Along Each Path

Page 182: Software Verification With Liquid Types

Vec: Extensible Arrays (317 LOC)

“Python-style” extensible arrays for Ocamlfind, insert, delete, join

etc.

Efficiency via balanced trees

Balanced

Height difference between siblings ≤ 2

Dsolve found balance violation

Page 183: Software Verification With Liquid Types

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

Page 184: Software Verification With Liquid Types

Part I

Part II

Part III

Refinement Types

Closures, Collections, Generics

Induction for Data Structures

Page 185: Software Verification With Liquid Types

Take Home LessonsWhy is Verification difficult?Complex “Invariants”

How to represent invariants? Factor into liquid type

How to infer liquid type?Subtyping + Predicate Abstraction

Page 186: Software Verification With Liquid Types

“Back-End” LogicConstraint Solving

Rich Decidable Logics Predicate Discovery…

Much Work Remains…

Page 187: Software Verification With Liquid Types

“Front-End” TypesDestructive Update

ConcurrencyObjects & Classes

Dynamic Languages…

Much Work Remains…

Page 188: Software Verification With Liquid Types

User InterfaceThe smarter your analysis,

the harder to tell why it fails!

Much Work Remains…

Page 189: Software Verification With Liquid Types

DetailsOcaml (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”

Page 190: Software Verification With Liquid Types

POPL Lightning Talk/DemoOcaml (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

Page 191: Software Verification With Liquid Types

http://goto.ucsd.edu/liquidsource, papers, demo, etc.

Page 192: Software Verification With Liquid Types

Program Lines DMLAnnot.

LiquidAnnot.

LiquidTime(s)

dotprod 7 3 0 0.3bsearch 24 3 0 0.5queens 30 7 0 0.7

insersort 33 12 0 0.9tower 36 8 1 3.3

matmult 43 10 0 1.8heapsort 84 11 0 0.5

fft 107 13 1 9.1simplex 118 33 0 7.7

gauss 142 22 1 3.1Total 632 125 3 27.9

Evaluation: Array Bounds Checking

Page 193: Software Verification With Liquid Types

Evaluation: Array Bounds Checking

DML @ 20% LOCvs.

Liquid @ 0.5% LOC

Page 194: Software Verification With Liquid Types

The end

Page 195: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u)

else []

Template of “then”-expression{v:int|Xout} list

Check: “head” and “tail” as requiredl≺ u ⊢ “head” <: {v:int|Xout}l≺ u ⊢ “tail” <: {v:int|Xout} list

Page 196: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u)

else []

Check: “head” as requiredl≺ u ⊢ {v:int|v=l} <: {v:int|Xout}

l≺ u Æ v=l ) Xout

Reduces To1

Page 197: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u)

else []

Check: “tail” as required

Template of rangel:int ! u:int ! {v:int|Xout} list

Page 198: Software Verification With Liquid Types

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| Xout [l+1/l]} list

Page 199: Software Verification With Liquid Types

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| Xout [l+1/l][u/u]} list

Page 200: Software Verification With Liquid Types

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| Xout [l+1/l]} list

{Xout [l+1/l]} list <: then-“tail”

Page 201: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u)

else []

Check: “tail” as required{Xout [l+1/l]} list <: then-“tail”

Template of “then”-expression{v:int|Xout} list

Page 202: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u)

else []

Check: “tail” as required{Xout [l+1/l]} list <: {Xout } list

Template of “then”-expression{v:int|Xout} list

Page 203: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u)

else []

Check: “tail” as required{Xout [l+1/l]} list <: {Xout } list

Template of rangel:int ! u:int ! {v:int|Xout} list

Page 204: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u)

else []

Check: “tail” as required{Xout [l+1/l]} list <: {Xout } list

Template of “then”-expression{v:int|Xout} list

Page 205: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u)

else []

Check: “tail” as required{Xout [l+1/l]} list <: {Xout } list

Template of “then”-expression{v:int|Xout} list

Page 206: Software Verification With Liquid Types

let rec range l u = if l < u then l :: (range (l+1) u)

else []

Check: “tail” as required{Xout [l+1/l]} list <: {Xout } list

Template of “then”-expression{v:int|Xout} list