Compositional and Mechanically Verified Program Analyzers
David Darais University of Maryland
Compositional and Mechanically Verified Program Analyzers David - - PowerPoint PPT Presentation
Compositional and Mechanically Verified Program Analyzers David Darais University of Maryland Let's Design an Analysis 2 Let's Design an Analysis Property x/0 2 Let's Design an Analysis Property Program x/0 0: int x y; 1: void
Compositional and Mechanically Verified Program Analyzers
David Darais University of Maryland
2
Property
2
x/0
Property
0: int x y; 1: void safe_fun(int N) { 2: if (N≠0) {x := 0;} 3: else {x := 1;} 4: if (N≠0) {y := 100/N;} 5: else {y := 100/x;}}
Program
3
x/0
Property
0: int x y; 1: void safe_fun(int N) { 2: if (N≠0) {x := 0;} 3: else {x := 1;} 4: if (N≠0) {y := 100/N;} 5: else {y := 100/x;}}
4
Program
Value Abstraction
x/0
Property
0: int x y; 1: void safe_fun(int N) { 2: if (N≠0) {x := 0;} 3: else {x := 1;} 4: if (N≠0) {y := 100/N;} 5: else {y := 100/x;}}
Program
ℤ ⊑ {-,0,+}
Value Abstraction
analyze : exp → results analyze(x := æ) := .. x .. æ .. analyze(IF(æ){e₁}{e₂}) := .. æ .. e₁ .. e₂ ..
Implement
5
x/0
Property
0: int x y; 1: void safe_fun(int N) { 2: if (N≠0) {x := 0;} 3: else {x := 1;} 4: if (N≠0) {y := 100/N;} 5: else {y := 100/x;}}
Program
ℤ ⊑ {-,0,+}
Value Abstraction
analyze : exp → results analyze(x := æ) := .. x .. æ .. analyze(IF(æ){e₁}{e₂}) := .. æ .. e₁ .. e₂ ..
Implement
N ∈ {-,0,+} x ∈ {0,+} y ∈ {-,0,+} UNSAFE: {100/N} UNSAFE: {100/x}
Results
6
x/0
Property
0: int x y; 1: void safe_fun(int N) { 2: if (N≠0) {x := 0;} 3: else {x := 1;} 4: if (N≠0) {y := 100/N;} 5: else {y := 100/x;}}
Program
ℤ ⊑ {-,0,+}
Value Abstraction
analyze : exp → results analyze(x := æ) := .. x .. æ .. analyze(IF(æ){e₁}{e₂}) := .. æ .. e₁ .. e₂ ..
Implement
N ∈ {-,0,+} x ∈ {0,+} y ∈ {-,0,+} UNSAFE: {100/N} UNSAFE: {100/x}
Results
⟦e⟧ ∈ ⟦analyze(e)⟧
Prove Correct
7
x/0
Property
0: int x y; 1: void safe_fun(int N) { 2: if (N≠0) {x := 0;} 3: else {x := 1;} 4: if (N≠0) {y := 100/N;} 5: else {y := 100/x;}}
Program
ℤ ⊑ {-,0,+}
Value Abstraction
analyze : exp → results analyze(x := æ) := .. x .. æ .. analyze(IF(æ){e₁}{e₂}) := .. æ .. e₁ .. e₂ ..
Implement
N ∈ {-,0,+} x ∈ {0,+} y ∈ {-,0,+} UNSAFE: {100/N} UNSAFE: {100/x}
Results
⟦e⟧ ∈ ⟦analyze(e)⟧
Prove Correct
8
0: int x y; 1: void safe_fun(int N) { 2: if (N≠0) {x := 0;} 3: else {x := 1;} 4: if (N≠0) {y := 100/N;} 5: else {y := 100/x;}} N ∈ {-,0,+} x ∈ {0,+} y ∈ {-,0,+} UNSAFE: {100/N} UNSAFE: {100/x}
9
Flow-insensitive
results : var ↦ ℘({-,0,+})
0: int x y; 1: void safe_fun(int N) { 2: if (N≠0) {x := 0;} 3: else {x := 1;} 4: if (N≠0) {y := 100/N;} 5: else {y := 100/x;}}
10
Flow-sensitive
results : loc ↦ (var ↦ ℘({-,0,+}))
4: x ∈ {0,+} 4.T: N ∈ {-,+} 5.F: x ∈ {0,+} N,y ∈ {-,0,+} UNSAFE: {100/x}
0: int x y; 1: void safe_fun(int N) { 2: if (N≠0) {x := 0;} 3: else {x := 1;} 4: if (N≠0) {y := 100/N;} 5: else {y := 100/x;}}
11
Path-sensitive
results : loc ↦ ℘(var ↦ ℘({-,0,+}))
4: N∈{-,+},x∈{0} 4: N∈{0},x∈{+} N∈{-,+},y∈{-,0,+} N∈{0},y∈{0,+} SAFE
x/0
Property
0: int x y; 1: void safe_fun(int N) { 2: if (N≠0) {x := 0;} 3: else {x := 1;} 4: if (N≠0) {y := 100/N;} 5: else {y := 100/x;}}
Program
ℤ ⊑ {-,0,+}
Value Abstraction
analyze : exp → results analyze(x := æ) := .. x .. æ .. analyze(IF(æ){e₁}{e₂}) := .. æ .. e₁ .. e₂ ..
Implement
4: N∈{-,+},x∈{0} 4: N∈{0},x∈{+} N∈{-,+},y∈{-,0,+} N∈{0},y∈{0,+} SAFE
Results
⟦e⟧ ∈ ⟦analyze(e)⟧
Prove Correct
13
safe_fun.js
x/0
Property Program
ℤ ⊑ {-,0,+}
Value Abstraction
analyze : exp → results analyze(x := æ) := .. x .. æ .. analyze(IF(æ){e₁}{e₂}) := .. æ .. e₁ .. e₂ ..
Implement
4: N∈{-,+},x∈{0} 4: N∈{0},x∈{+} N∈{-,+},y∈{-,0,+} N∈{0},y∈{0,+} SAFE
Results
⟦e⟧ ∈ ⟦analyze(e)⟧
Prove Correct
14
Abstracting Definitional Interpreters [draft] Galois Transformers [OOPSLA’15]
Constructive Galois Connections [ICFP’16] Orthogonal Components Systematic Design Mechanized Proofs
15
Abstracting Definitional Interpreters [draft] Galois Transformers [OOPSLA’15]
Constructive Galois Connections [ICFP’16] Orthogonal Components Systematic Design Mechanized Proofs
16
x/0
Property
0: int x y; 1: void safe_fun(int N) { 2: if (N≠0) {x := 0;} 3: else {x := 1;} 4: if (N≠0) {y := 100/N;} 5: else {y := 100/x;}}
Program
ℤ ⊑ {-,0,+}
Value Abstraction
analyze : exp → results analyze(x := æ) := .. x .. æ .. analyze(IF(æ){e₁}{e₂}) := .. æ .. e₁ .. e₂ ..
Implement
4: N∈{-,+},x∈{0} 4: N∈{0},x∈{+} N∈{-,+},y∈{-,0,+} N∈{0},y∈{0,+} SAFE
Results
⟦e⟧ ∈ ⟦analyze(e)⟧
Prove Correct
17
Problem: Isolate path and flow sensitivity in analysis
18
Challenge: Path and flow sensitivity are deeply integrated Problem: Isolate path and flow sensitivity in analysis
18
State-of-the-art: Redesign from scratch Challenge: Path and flow sensitivity are deeply integrated Problem: Isolate path and flow sensitivity in analysis
18
State-of-the-art: Redesign from scratch Challenge: Path and flow sensitivity are deeply integrated Our Insight: Monads capture path and flow sensitivity Problem: Isolate path and flow sensitivity in analysis
18
Monadic small-step interpreter
type !(t)
19
Monadic small-step interpreter
type !(t)
+ Monad Transformers
FlowT[퓈]
19
Monadic small-step interpreter
type !(t)
+ Monad Transformers
FlowT[퓈]
+ Galois Connections α γ
19
✓ Prototype flow insensitive, flow sensitive and path
sensitive CFA—no change to code or proof
20
✓ Prototype flow insensitive, flow sensitive and path
sensitive CFA—no change to code or proof
✓ End-to-end correctness proofs given parameters
20
✓ Prototype flow insensitive, flow sensitive and path
sensitive CFA—no change to code or proof
✓ End-to-end correctness proofs given parameters ✓ Implemented in Haskell and available on Github
20
✓ Prototype flow insensitive, flow sensitive and path
sensitive CFA—no change to code or proof
✓ End-to-end correctness proofs given parameters ✓ Implemented in Haskell and available on Github ✗ Not whole story for path-sensitivity refinement
20
✓ Prototype flow insensitive, flow sensitive and path
sensitive CFA—no change to code or proof
✓ End-to-end correctness proofs given parameters ✓ Implemented in Haskell and available on Github ✗ Not whole story for path-sensitivity refinement ✗ Somewhat naive fixpoint iteration strategies
20
x/0
Property
0: int x y; 1: void safe_fun(int N) { 2: if (N≠0) {x := 0;} 3: else {x := 1;} 4: if (N≠0) {y := 100/N;} 5: else {y := 100/x;}}
Program
ℤ ⊑ {-,0,+}
Value Abstraction
analyze : exp → results analyze(x := æ) := .. x .. æ .. analyze(IF(æ){e₁}{e₂}) := .. æ .. e₁ .. e₂ ..
Implement
4: N∈{-,+},x∈{0} 4: N∈{0},x∈{+} N∈{-,+},y∈{-,0,+} N∈{0},y∈{0,+} SAFE
Results
⟦e⟧ ∈ ⟦analyze(e)⟧
Prove Correct
21
Abstracting Definitional Interpreters [draft] Galois Transformers [OOPSLA’15]
Constructive Galois Connections [ICFP’16] Orthogonal Components Systematic Design Mechanized Proofs
22
Abstracting Definitional Interpreters [draft] Galois Transformers [OOPSLA’15]
Constructive Galois Connections [ICFP’16] Orthogonal Components Systematic Design Mechanized Proofs
23
x/0
Property
ℤ ⊑ {-,0,+}
Value Abstraction
analyze : exp → results analyze(x := æ) := .. x .. æ .. analyze(IF(æ){e₁}{e₂}) := .. æ .. e₁ .. e₂ ..
Implement
4: N∈{-,+},x∈{0} 4: N∈{0},x∈{+} N∈{-,+},y∈{-,0,+} N∈{0},y∈{0,+} SAFE
Results
⟦e⟧ ∈ ⟦analyze(e)⟧
Prove Correct
Program
24
x/0
Property
ℤ ⊑ {-,0,+}
Value Abstraction
analyze : exp → results analyze(x := æ) := .. x .. æ .. analyze(IF(æ){e₁}{e₂}) := .. æ .. e₁ .. e₂ ..
Implement
4: N∈{-,+},x∈{0} 4: N∈{0},x∈{+} N∈{-,+},y∈{-,0,+} N∈{0},y∈{0,+} SAFE
Results
⟦e⟧ ∈ ⟦analyze(e)⟧
Prove Correct
safe_fun.js
Program
24
Problem: Turn interpreters into program analyzers
25
Challenge: Interpreters don’t expose reachable configurations Problem: Turn interpreters into program analyzers
25
State-of-the-art: Small-step machines or constraint systems Challenge: Interpreters don’t expose reachable configurations Problem: Turn interpreters into program analyzers
25
State-of-the-art: Small-step machines or constraint systems Challenge: Interpreters don’t expose reachable configurations Our Insight: Intercept recursion and monad of interpretation Problem: Turn interpreters into program analyzers
25
Definitional Abstract Interpreters
Definitional Interpreters
⟦e⟧ : exp → val
26
Definitional Abstract Interpreters
Definitional Interpreters
⟦e⟧ : exp → val
+ Open Recursion
⟦e⟧ᴼ : (exp → val) → (exp → val)
26
Definitional Abstract Interpreters
Definitional Interpreters
⟦e⟧ : exp → val
+ Open Recursion
⟦e⟧ᴼ : (exp → val) → (exp → val)
+ Monads (again)
⟦e⟧ᴹ : exp → !(val)
26
Definitional Abstract Interpreters
Definitional Interpreters
⟦e⟧ : exp → val
+ Open Recursion
⟦e⟧ᴼ : (exp → val) → (exp → val)
+ Monads (again)
⟦e⟧ᴹ : exp → !(val)
Custom Fixpoints
Y(⟦e⟧ᴼᴹ) vs F(⟦e⟧ᴼᴹ)
+
26
✓ Analyzers instantly from definitional interpreters
Definitional Abstract Interpreters
27
✓ Analyzers instantly from definitional interpreters ✓ Soundness w.r.t. big-step reachability semantics
Definitional Abstract Interpreters
27
✓ Analyzers instantly from definitional interpreters ✓ Soundness w.r.t. big-step reachability semantics ✓ Pushdown analysis inherited from meta-language
Definitional Abstract Interpreters
27
✓ Analyzers instantly from definitional interpreters ✓ Soundness w.r.t. big-step reachability semantics ✓ Pushdown analysis inherited from meta-language ✓ Implemented in Racket and available on Github
Definitional Abstract Interpreters
27
✓ Analyzers instantly from definitional interpreters ✓ Soundness w.r.t. big-step reachability semantics ✓ Pushdown analysis inherited from meta-language ✓ Implemented in Racket and available on Github ✗ More complicated meta-theory
Definitional Abstract Interpreters
27
✓ Analyzers instantly from definitional interpreters ✓ Soundness w.r.t. big-step reachability semantics ✓ Pushdown analysis inherited from meta-language ✓ Implemented in Racket and available on Github ✗ More complicated meta-theory ✗ Monadic, open-recursive interpreters aren’t “simple”
Definitional Abstract Interpreters
27
x/0
Property
ℤ ⊑ {-,0,+}
Value Abstraction
analyze : exp → results analyze(x := æ) := .. x .. æ .. analyze(IF(æ){e₁}{e₂}) := .. æ .. e₁ .. e₂ ..
Implement
4: N∈{-,+},x∈{0} 4: N∈{0},x∈{+} N∈{-,+},y∈{-,0,+} N∈{0},y∈{0,+} SAFE
Results
⟦e⟧ ∈ ⟦analyze(e)⟧
Prove Correct
safe_fun.js
Program
28
Abstracting Definitional Interpreters [draft] Galois Transformers [OOPSLA’15]
Constructive Galois Connections [ICFP’16] Orthogonal Components Systematic Design Mechanized Proofs
29
Abstracting Definitional Interpreters [draft] Galois Transformers [OOPSLA’15]
Constructive Galois Connections [ICFP’16] Orthogonal Components Systematic Design Mechanized Proofs
30
x/0
Property
ℤ ⊑ {-,0,+}
Value Abstraction
analyze : exp → results analyze(x := æ) := .. x .. æ .. analyze(IF(æ){e₁}{e₂}) := .. æ .. e₁ .. e₂ ..
Implement
4: N∈{-,+},x∈{0} 4: N∈{0},x∈{+} N∈{-,+},y∈{-,0,+} N∈{0},y∈{0,+} SAFE
Results
⟦e⟧ ∈ ⟦analyze(e)⟧
Prove Correct
safe_fun.js
Program
31
analyze : exp → results analyze(x := æ) := .. x .. æ .. analyze(IF(æ){e₁}{e₂}) := .. æ .. e₁ .. e₂ ..
Implement
⟦e⟧ ∈ ⟦analyze(e)⟧
Prove Correct
32
analyze : exp → results analyze(x := æ) := .. x .. æ .. analyze(IF(æ){e₁}{e₂}) := .. æ .. e₁ .. e₂ ..
Implement
⟦e⟧ ∈ ⟦analyze(e)⟧
Prove Correct
“Calculational Abstract Interpretation” [Cousot99]
32
Problem: Calculation, abstraction and mechanization don’t mix
33
Challenge: Transition from specifications to algorithms Problem: Calculation, abstraction and mechanization don’t mix
33
State-of-the-art: Avoid Galois connections in mechanizations Challenge: Transition from specifications to algorithms Problem: Calculation, abstraction and mechanization don’t mix
33
State-of-the-art: Avoid Galois connections in mechanizations Challenge: Transition from specifications to algorithms Our Insight: A constructive sub-theory of Galois connections Problem: Calculation, abstraction and mechanization don’t mix
33
Classical Galois Connections
α : ℘(C) → A γ : A → ℘(C)
Calculational Galois Connections
34
Classical Galois Connections
α : ℘(C) → A γ : A → ℘(C)
+ Restricted Form
η : C → A μ : A → ℘(C)
Calculational Galois Connections
34
Classical Galois Connections
α : ℘(C) → A γ : A → ℘(C)
+ Restricted Form
η : C → A μ : A → ℘(C)
+ Monads (again)
calculate : ℘(A) → ℘(A)
Calculational Galois Connections
34
Classical Galois Connections
α : ℘(C) → A γ : A → ℘(C)
+ Restricted Form
η : C → A μ : A → ℘(C)
+ Monads (again)
calculate : ℘(A) → ℘(A)
Calculational Galois Connections
“has effects” “no effects”
34
✓ First theory to support calculation and extraction
Calculational Galois Connections
35
✓ First theory to support calculation and extraction ✓ Soundness and completeness, also mechanized
Calculational Galois Connections
35
✓ First theory to support calculation and extraction ✓ Soundness and completeness, also mechanized ✓ Provably less boilerplate than classical theory
Calculational Galois Connections
35
✓ First theory to support calculation and extraction ✓ Soundness and completeness, also mechanized ✓ Provably less boilerplate than classical theory ✓ Two case studies: calculational AI and gradual typing
Calculational Galois Connections
35
✓ First theory to support calculation and extraction ✓ Soundness and completeness, also mechanized ✓ Provably less boilerplate than classical theory ✓ Two case studies: calculational AI and gradual typing ✗ Still some reasons not to use Galois connections
Calculational Galois Connections
35
✓ First theory to support calculation and extraction ✓ Soundness and completeness, also mechanized ✓ Provably less boilerplate than classical theory ✓ Two case studies: calculational AI and gradual typing ✗ Still some reasons not to use Galois connections ✗ Calculating abstract interpreters is still very difficult
Calculational Galois Connections
35
analyze : exp → results analyze(x := æ) := .. x .. æ .. analyze(IF(æ){e₁}{e₂}) := .. æ .. e₁ .. e₂ ..
Implement
⟦e⟧ ∈ ⟦analyze(e)⟧
Prove Correct
“Calculational Abstract Interpretation” [Cousot99]
36
analyze : exp → results analyze(x := æ) := .. x .. æ .. analyze(IF(æ){e₁}{e₂}) := .. æ .. e₁ .. e₂ ..
Implement
⟦e⟧ ∈ ⟦analyze(e)⟧
Prove Correct
“Calculational Abstract Interpretation” [Cousot99]
AGDA AGDA
36
Abstracting Definitional Interpreters [draft] Galois Transformers [OOPSLA’15]
Constructive Galois Connections [ICFP’16] Orthogonal Components Systematic Design Mechanized Proofs
37
Design Code Proof
38