Galois Transformers and Modular Abstract Interpreters Reusable Metatheory for Program Analysis David Darais Matthew Might David Van Horn University of Maryland University of Utah University of Maryland
Program Analysis 2
Program Analysis • Lots of choices when designing a program analysis 2
Program Analysis • Lots of choices when designing a program analysis • Choices make tradeoffs between precision and performance 2
Program Analysis • Lots of choices when designing a program analysis • Choices make tradeoffs between precision and performance • Implementations are brittle and difficult to change 2
Program Analysis • Lots of choices when designing a program analysis • Choices make tradeoffs between precision and performance • Implementations are brittle and difficult to change • Galois Transformers : Reusable components for building program analyzers 2
Program Analysis • Lots of choices when designing a program analysis • Choices make tradeoffs between precision and performance • Implementations are brittle and difficult to change • Galois Transformers : Reusable components for building program analyzers • Bonus : Variations in path/flow sensitivity of your analyzer for free 2
Let's Design an Analysis (in the paradigm of abstract interpretation) 3
Let's Design an Analysis Program 0: int x y; // global state 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
Let's Design an Analysis Program Analysis Property 0: int x y; // global state 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;}} x/0 5
Let's Design an Analysis Program Analysis Property Abstract Values 0: int x y; // global state 1: void safe_fun(int N) { x/0 2: if (N ≠ 0) {x := 0;} 3: else {x := 1;} 4: if (N ≠ 0) {y := 100/N;} 5: else {y := 100/x;}} ℤ ⊑ {-,0,+} 6
Let's Design an Analysis Program Analysis Property Abstract Values Implement 0: int x y; // global state 1: void safe_fun(int N) { x/0 ℤ ⊑ {-,0,+} 2: if (N ≠ 0) {x := 0;} 3: else {x := 1;} 4: if (N ≠ 0) {y := 100/N;} 5: else {y := 100/x;}} analyze : exp → results analyze(x := æ) := .. x .. æ .. analyze( IF( æ ){ e ₁ }{ e ₂ } ) := .. æ .. e ₁ .. e ₂ .. 7
Let's Design an Analysis Program Analysis Property Abstract Values Get Results 0: int x y; // global state 1: void safe_fun(int N) { x/0 ℤ ⊑ {-,0,+} 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,+} Implement y ∈ {-,0,+} analyze : exp → results analyze(x := æ) := UNSAFE : {100/N} .. x .. æ .. analyze( IF( æ ){ e ₁ }{ e ₂ } ) := UNSAFE : {100/x} .. æ .. e ₁ .. e ₂ .. 8
Let's Design an Analysis Program Analysis Property Abstract Values Prove Correct 0: int x y; // global state 1: void safe_fun(int N) { x/0 ℤ ⊑ {-,0,+} 2: if (N ≠ 0) {x := 0;} 3: else {x := 1;} 4: if (N ≠ 0) {y := 100/N;} 5: else {y := 100/x;}} ⟦ e ⟧ ∈ ⟦ analyze(e) ⟧ Implement Get Results analyze : exp → results N ∈ {-,0,+} analyze(x := æ) := x ∈ {0,+} .. x .. æ .. y ∈ {-,0,+} analyze( IF( æ ){ e ₁ }{ e ₂ } ) := .. æ .. e ₁ .. e ₂ .. UNSAFE : {100/N} UNSAFE : {100/x} 9
Let's Design an Analysis Program Analysis Property Abstract Values 0: int x y; // global state 1: void safe_fun(int N) { x/0 ℤ ⊑ {-,0,+} 2: if (N ≠ 0) {x := 0;} 3: else {x := 1;} 4: if (N ≠ 0) {y := 100/N;} 5: else {y := 100/x;}} Implement Get Results Prove Correct analyze : exp → results N ∈ {-,0,+} analyze(x := æ) := x ∈ {0,+} ⟦ e ⟧ ∈ ⟦ analyze(e) ⟧ .. x .. æ .. y ∈ {-,0,+} analyze( IF( æ ){ e ₁ }{ e ₂ } ) := .. æ .. e ₁ .. e ₂ .. UNSAFE : {100/N} UNSAFE : {100/x} 10
Let's Design an Analysis 0: int x y; // global state 1: void safe_fun(int N) { 2: if (N ≠ 0) {x := 0;} 3: else {x := 1;} 4: if (N ≠ 0) {y := 100/N;} Flow-insensitive 5: else {y := 100/x;}} results : var ↦ ! ({-,0,+}) N ∈ {-,0,+} x ∈ {0,+} y ∈ {-,0,+} UNSAFE : {100/N} UNSAFE : {100/x} 11
Let's Design an Analysis 0: int x y; // global state 1: void safe_fun(int N) { 2: if (N ≠ 0) {x := 0;} 3: else {x := 1;} 4: if (N ≠ 0) {y := 100/N;} Flow-sensitive 5: else {y := 100/x;}} results : loc ↦ (var ↦ ! ({-,0,+})) 12
Let's Design an Analysis 0: int x y; // global state 1: void safe_fun(int N) { 2: if (N ≠ 0) {x := 0;} 3: else {x := 1;} 4: if (N ≠ 0) {y := 100/N;} Flow-sensitive 5: else {y := 100/x;}} results : 4: x ∈ {0,+} loc ↦ (var ↦ ! ({-,0,+})) 4.T: N ∈ {-,+} 5.F: x ∈ {0,+} N,y ∈ {-,0,+} UNSAFE : {100/x} 13
Let's Design an Analysis 0: int x y; // global state 1: void safe_fun(int N) { 2: if (N ≠ 0) {x := 0;} 3: else {x := 1;} 4: if (N ≠ 0) {y := 100/N;} Path-sensitive 5: else {y := 100/x;}} results : loc ↦ ! (var ↦ ! ({-,0,+})) 14
Let's Design an Analysis 0: int x y; // global state 1: void safe_fun(int N) { 2: if (N ≠ 0) {x := 0;} 3: else {x := 1;} 4: if (N ≠ 0) {y := 100/N;} Path-sensitive 5: else {y := 100/x;}} results : 4: N ∈ {-,+},x ∈ {0} loc ↦ ! (var ↦ ! ({-,0,+})) 4: N ∈ {0},x ∈ {+} N ∈ {-,+},y ∈ {-,0,+} N ∈ {0},y ∈ {0,+} SAFE 15
Let's Design an Analysis Program Analysis Property Abstract Values 0: int x y; // global state 1: void safe_fun(int N) { x/0 ℤ ⊑ {-,0,+} 2: if (N ≠ 0) {x := 0;} 3: else {x := 1;} 4: if (N ≠ 0) {y := 100/N;} 5: else {y := 100/x;}} Implement Get Results Prove Correct ? 4: N ∈ {-,+},x ∈ {0} analyze : exp → results 4: N ∈ {0},x ∈ {+} analyze(x := æ) := ⟦ e ⟧ ∈ ⟦ analyze(e) ⟧ .. x .. æ .. N ∈ {-,+},y ∈ {-,0,+} analyze( IF( æ ){ e ₁ }{ e ₂ } ) := N ∈ {0},y ∈ {0,+} .. æ .. e ₁ .. e ₂ .. SAFE 16
Let's Design an Analysis Program Analysis Property Abstract Values ✓ 0: int x y; // global state 1: void safe_fun(int N) { x/0 ℤ ⊑ {-,0,+} 2: if (N ≠ 0) {x := 0;} 3: else {x := 1;} 4: if (N ≠ 0) {y := 100/N;} 5: else {y := 100/x;}} Implement Get Results Prove Correct ? ✗ ✗ 4: N ∈ {-,+},x ∈ {0} analyze : exp → results 4: N ∈ {0},x ∈ {+} analyze(x := æ) := ⟦ e ⟧ ∈ ⟦ analyze(e) ⟧ .. x .. æ .. N ∈ {-,+},y ∈ {-,0,+} analyze( IF( æ ){ e ₁ }{ e ₂ } ) := N ∈ {0},y ∈ {0,+} .. æ .. e ₁ .. e ₂ .. SAFE 16
Let's Design an Analysis Program Analysis Property Abstract Values ? x/0 safe_fun.js ℤ ⊑ {-,0,+} Implement Get Results Prove Correct 4: N ∈ {-,+},x ∈ {0} analyze : exp → results 4: N ∈ {0},x ∈ {+} analyze(x := æ) := ⟦ e ⟧ ∈ ⟦ analyze(e) ⟧ .. x .. æ .. N ∈ {-,+},y ∈ {-,0,+} analyze( IF( æ ){ e ₁ }{ e ₂ } ) := N ∈ {0},y ∈ {0,+} .. æ .. e ₁ .. e ₂ .. SAFE 17
Let's Design an Analysis Program Analysis Property Abstract Values ✓ ? x/0 safe_fun.js ℤ ⊑ {-,0,+} Implement Get Results Prove Correct ✗ ✗ 4: N ∈ {-,+},x ∈ {0} analyze : exp → results 4: N ∈ {0},x ∈ {+} analyze(x := æ) := ⟦ e ⟧ ∈ ⟦ analyze(e) ⟧ .. x .. æ .. N ∈ {-,+},y ∈ {-,0,+} analyze( IF( æ ){ e ₁ }{ e ₂ } ) := N ∈ {0},y ∈ {0,+} .. æ .. e ₁ .. e ₂ .. SAFE 17
Problems Worth Solving • How to change path/flow sensitivity without redesigning from scratch? • How to reuse machinery between analyzers for different languages? • How to translate proofs between different analysis designs? 18
Solution Monad Galoi ѕ Galois + = Transformers Transformer ѕ Connections Compositional Compositional Compositional abstract interpreters abstractions interpreters 19
Galoi ѕ Transformer ѕ • What's a Monad? • What are Transformers? • What are Galois Connections? 20
Galoi ѕ Transformer ѕ • What's a Monad? • What are Transformers? • What are Galois Connections? 21
A Monad • A module with: type " (t) • a type operator " op x ← e ₁ ; e ₂ • a semicolon operator op return(e) (bind) • effect operation op get op put(e) • " (t) : op fail • "A computation that performs op ... some effects, then returns t " 22
A Monadic Interpreter Program Analysis Property Abstract Domain 0: int x y; // global state 1: void safe_fun(int N) { x/0 ℤ ⊑ {-,0,+} 2: if (N ≠ 0) {x := 0;} 3: else {x := 1;} 4: if (N ≠ 0) {y := 100/N;} 5: else {y := 100/x;}} Implement Get Results Prove Correct analyze : exp → results N ∈ {-,0,+} analyze(x := æ) := x ∈ {0,+} ⟦ e ⟧ ∈ ⟦ analyze(e) ⟧ .. x .. æ .. y ∈ {-,0,+} analyze( IF( æ ){ e ₁ }{ e ₂ } ) := .. æ .. e ₁ .. e ₂ .. UNSAFE : {100/N} UNSAFE : {100/x} 23
A Monadic Interpreter 0: int x y; // global state 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;}} 24
Recommend
More recommend