Compositional and Mechanically Verified Program Analyzers David - - PowerPoint PPT Presentation

compositional and mechanically verified program analyzers
SMART_READER_LITE
LIVE PREVIEW

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


slide-1
SLIDE 1

Compositional and Mechanically Verified Program Analyzers

David Darais University of Maryland

slide-2
SLIDE 2

Let's Design an Analysis

2

slide-3
SLIDE 3

Property

x/0

Let's Design an Analysis

2

slide-4
SLIDE 4

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

Let's Design an Analysis

3

slide-5
SLIDE 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;}}

Let's Design an Analysis

4

Program

ℤ ⊑ {-,0,+}

Value Abstraction

slide-6
SLIDE 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

Let's Design an Analysis

5

slide-7
SLIDE 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

Let's Design an Analysis

6

slide-8
SLIDE 8

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

Let's Design an Analysis

7

slide-9
SLIDE 9

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

Let's Design an Analysis

8

slide-10
SLIDE 10

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}

Let's Design an Analysis

9

Flow-insensitive

results : var ↦ ℘({-,0,+})

slide-11
SLIDE 11

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

Let's Design an Analysis

10

Flow-sensitive

results : loc ↦ (var ↦ ℘({-,0,+}))

4: x ∈ {0,+} 4.T: N ∈ {-,+} 5.F: x ∈ {0,+} N,y ∈ {-,0,+} UNSAFE: {100/x}

slide-12
SLIDE 12

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

Let's Design an Analysis

11

Path-sensitive

results : loc ↦ ℘(var ↦ ℘({-,0,+}))

4: N∈{-,+},x∈{0} 4: N∈{0},x∈{+} N∈{-,+},y∈{-,0,+} N∈{0},y∈{0,+} SAFE

slide-13
SLIDE 13

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

Let's Design an Analysis

13

? ✓ ✗ ✗

slide-14
SLIDE 14

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

Let's Design an Analysis

14

✓ ✗ ✗

slide-15
SLIDE 15

Abstracting Definitional Interpreters
 [draft] Galois Transformers
 [OOPSLA’15]

Contributions

Constructive Galois Connections
 [ICFP’16] Orthogonal Components Systematic Design Mechanized Proofs

15

slide-16
SLIDE 16

Abstracting Definitional Interpreters
 [draft] Galois Transformers
 [OOPSLA’15]

Contributions

Constructive Galois Connections
 [ICFP’16] Orthogonal Components Systematic Design Mechanized Proofs

16

slide-17
SLIDE 17

Orthogonal Components

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

slide-18
SLIDE 18

Orthogonal Components

Problem: Isolate path and flow sensitivity in analysis

18

slide-19
SLIDE 19

Orthogonal Components

Challenge: Path and flow sensitivity are deeply integrated Problem: Isolate path and flow sensitivity in analysis

18

slide-20
SLIDE 20

Orthogonal Components

State-of-the-art: Redesign from scratch Challenge: Path and flow sensitivity are deeply integrated Problem: Isolate path and flow sensitivity in analysis

18

slide-21
SLIDE 21

Orthogonal Components

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

slide-22
SLIDE 22

Galois Transformers

Monadic small-step interpreter

type !(t)

  • p x ← e₁ ; e₂
  • p return(e)

19

slide-23
SLIDE 23

Galois Transformers

Monadic small-step interpreter

type !(t)

  • p x ← e₁ ; e₂
  • p return(e)

+ Monad Transformers

FlowT[퓈]

19

slide-24
SLIDE 24

Galois Transformers

Monadic small-step interpreter

type !(t)

  • p x ← e₁ ; e₂
  • p return(e)

+ Monad Transformers

FlowT[퓈]

+ Galois Connections α γ

19

slide-25
SLIDE 25

Galois Transformers

✓ Prototype flow insensitive, flow sensitive and path

sensitive CFA—no change to code or proof

20

slide-26
SLIDE 26

Galois Transformers

✓ Prototype flow insensitive, flow sensitive and path

sensitive CFA—no change to code or proof

✓ End-to-end correctness proofs given parameters

20

slide-27
SLIDE 27

Galois Transformers

✓ 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

slide-28
SLIDE 28

Galois Transformers

✓ 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

slide-29
SLIDE 29

Galois Transformers

✓ 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

slide-30
SLIDE 30

Orthogonal Components

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

slide-31
SLIDE 31

Abstracting Definitional Interpreters
 [draft] Galois Transformers
 [OOPSLA’15]

Contributions

Constructive Galois Connections
 [ICFP’16] Orthogonal Components Systematic Design Mechanized Proofs

22

slide-32
SLIDE 32

Abstracting Definitional Interpreters
 [draft] Galois Transformers
 [OOPSLA’15]

Contributions

Constructive Galois Connections
 [ICFP’16] Orthogonal Components Systematic Design Mechanized Proofs

23

slide-33
SLIDE 33

Systematic Design

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

slide-34
SLIDE 34

Systematic Design

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

slide-35
SLIDE 35

Systematic Design

Problem: Turn interpreters into program analyzers

25

slide-36
SLIDE 36

Systematic Design

Challenge: Interpreters don’t expose reachable configurations Problem: Turn interpreters into program analyzers

25

slide-37
SLIDE 37

Systematic Design

State-of-the-art: Small-step machines or constraint systems Challenge: Interpreters don’t expose reachable configurations Problem: Turn interpreters into program analyzers

25

slide-38
SLIDE 38

Systematic Design

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

slide-39
SLIDE 39

Definitional Abstract Interpreters

Definitional Interpreters

⟦e⟧ : exp → val

26

slide-40
SLIDE 40

Definitional Abstract Interpreters

Definitional Interpreters

⟦e⟧ : exp → val

+ Open Recursion

⟦e⟧ᴼ : (exp → val) → (exp → val)

26

slide-41
SLIDE 41

Definitional Abstract Interpreters

Definitional Interpreters

⟦e⟧ : exp → val

+ Open Recursion

⟦e⟧ᴼ : (exp → val) → (exp → val)

+ Monads (again)

⟦e⟧ᴹ : exp → !(val)

26

slide-42
SLIDE 42

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

slide-43
SLIDE 43

✓ Analyzers instantly from definitional interpreters

Definitional Abstract Interpreters

27

slide-44
SLIDE 44

✓ Analyzers instantly from definitional interpreters ✓ Soundness w.r.t. big-step reachability semantics

Definitional Abstract Interpreters

27

slide-45
SLIDE 45

✓ Analyzers instantly from definitional interpreters ✓ Soundness w.r.t. big-step reachability semantics ✓ Pushdown analysis inherited from meta-language

Definitional Abstract Interpreters

27

slide-46
SLIDE 46

✓ 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

slide-47
SLIDE 47

✓ 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

slide-48
SLIDE 48

✓ 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

slide-49
SLIDE 49

Systematic Design

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

slide-50
SLIDE 50

Abstracting Definitional Interpreters
 [draft] Galois Transformers
 [OOPSLA’15]

Contributions

Constructive Galois Connections
 [ICFP’16] Orthogonal Components Systematic Design Mechanized Proofs

29

slide-51
SLIDE 51

Abstracting Definitional Interpreters
 [draft] Galois Transformers
 [OOPSLA’15]

Contributions

Constructive Galois Connections
 [ICFP’16] Orthogonal Components Systematic Design Mechanized Proofs

30

slide-52
SLIDE 52

Mechanized Proofs

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

slide-53
SLIDE 53

Mechanized Proofs

analyze : exp → results analyze(x := æ) := .. x .. æ .. analyze(IF(æ){e₁}{e₂}) := .. æ .. e₁ .. e₂ ..

Implement

⟦e⟧ ∈ ⟦analyze(e)⟧

Prove Correct

32

slide-54
SLIDE 54

Mechanized Proofs

analyze : exp → results analyze(x := æ) := .. x .. æ .. analyze(IF(æ){e₁}{e₂}) := .. æ .. e₁ .. e₂ ..

Implement

⟦e⟧ ∈ ⟦analyze(e)⟧

Prove Correct

“Calculational Abstract Interpretation” [Cousot99]

32

slide-55
SLIDE 55

Mechanized Proofs

Problem: Calculation, abstraction and mechanization don’t mix

33

slide-56
SLIDE 56

Mechanized Proofs

Challenge: Transition from specifications to algorithms Problem: Calculation, abstraction and mechanization don’t mix

33

slide-57
SLIDE 57

Mechanized Proofs

State-of-the-art: Avoid Galois connections in mechanizations Challenge: Transition from specifications to algorithms Problem: Calculation, abstraction and mechanization don’t mix

33

slide-58
SLIDE 58

Mechanized Proofs

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

slide-59
SLIDE 59

Classical Galois Connections

α : ℘(C) → A γ : A → ℘(C)

Calculational Galois Connections

34

slide-60
SLIDE 60

Classical Galois Connections

α : ℘(C) → A γ : A → ℘(C)

+ Restricted Form

η : C → A μ : A → ℘(C)

Calculational Galois Connections

34

slide-61
SLIDE 61

Classical Galois Connections

α : ℘(C) → A γ : A → ℘(C)

+ Restricted Form

η : C → A μ : A → ℘(C)

+ Monads (again)

calculate : ℘(A) → ℘(A)

Calculational Galois Connections

34

slide-62
SLIDE 62

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

slide-63
SLIDE 63

✓ First theory to support calculation and extraction

Calculational Galois Connections

35

slide-64
SLIDE 64

✓ First theory to support calculation and extraction ✓ Soundness and completeness, also mechanized

Calculational Galois Connections

35

slide-65
SLIDE 65

✓ First theory to support calculation and extraction ✓ Soundness and completeness, also mechanized ✓ Provably less boilerplate than classical theory

Calculational Galois Connections

35

slide-66
SLIDE 66

✓ 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

slide-67
SLIDE 67

✓ 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

slide-68
SLIDE 68

✓ 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

slide-69
SLIDE 69

Mechanized Proofs

analyze : exp → results analyze(x := æ) := .. x .. æ .. analyze(IF(æ){e₁}{e₂}) := .. æ .. e₁ .. e₂ ..

Implement

⟦e⟧ ∈ ⟦analyze(e)⟧

Prove Correct

“Calculational Abstract Interpretation” [Cousot99]

36

slide-70
SLIDE 70

Mechanized Proofs

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

slide-71
SLIDE 71

Abstracting Definitional Interpreters
 [draft] Galois Transformers
 [OOPSLA’15]

Contributions

Constructive Galois Connections
 [ICFP’16] Orthogonal Components Systematic Design Mechanized Proofs

37

slide-72
SLIDE 72

Program Analysis Design

Design Code Proof

38