36
Introduction Generics Delegate clients Capturing delegates Verifying Generics and Delegates Kasper Svendsen Lars Birkedal Matthew Parkinson ECOOP 2010 June 23, 2010

Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Verifying Generics and Delegates

Kasper SvendsenLars Birkedal

Matthew Parkinson

ECOOP 2010

June 23, 2010

Page 2: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Introduction

HO separation logic for C# subset with generics and delegates

• Hoare-style program logic for proving functional correctness

• Separation logic for modular reasoning about state

In HOSL & Hoare Type Theory one can reason about

• polymorphism using universal quantification over predicates

• first-class functions using nested Hoare triples

We extend these techniques to reason about C#

• Main challenge: C# variable capture

Page 3: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

C# variable capture

Example

public delegate Y Func〈Y〉 ();

Func〈int〉 counter() {int x = 0;return delegate () { return ++x; };}

C# semantics

• Inline delegate captures the location of x

• Lifetime of captured x extended to lifetime of delegate

Page 4: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Outline

Introduction

Generics

Delegate clients

Capturing delegates

Page 5: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Setup

C# subset

• Basic imperative features + generics + delegates

Assertion logic

• Logic for reasoning about computational states

• Higher-order separation logic

• Spacial connectives, emp, ∗,−∗, for controlling aliasing

• State assertions, M.f 7→ N, ..., for describing state

Specification logic

• Logic for relating initial and terminal state

Page 6: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Example – Integer list

class Node {Node next;Integer val;}

• Representation predicate

list(x , ε)def= x = null

list(x , a · α)def= ∃n,∃v . x .next 7→ n ∗ x .val 7→ v ∗

Int(v , a) ∗ list(n, α)

• Int(v , a): v is a representation of the integer a

Page 7: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Example – Integer list

class Node {Node next;Integer val;}

• Representation predicate

list(x , ε)def= x = null

list(x , a · α)def= ∃n,∃v . x .next 7→ n ∗ x .val 7→ v ∗

Int(v , a) ∗ list(n, α)

• Int(v , a): v is a representation of the integer a

Page 8: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Example – Generic list

class Node〈X〉 {Node〈X〉 next;X val;}

• Representation predicate

list(x , ε,P)def= x = null

list(x , a · α,P)def= ∃n,∃v . x .next 7→ n ∗ x .val 7→ v ∗

P(v , a) ∗ list(n, α,P)

• P(v , a): v is a representation of a

Page 9: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Example – Fold

void fold〈X〉(Node〈X〉 lst, Action〈Node〈X〉〉 f) {if(lst != null) {

Node〈X〉 next = lst.next;f(lst);fold(next, f);}}

• foreach

• Stateful fold-right – accumulator maintained by delegate

Page 10: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Example – Fold

void fold〈X〉(Node〈X〉 lst, Action〈Node〈X〉〉 f) {if(lst != null) {

Node〈X〉 next = lst.next;f(lst);fold(next, f);}}

• foreach

• Stateful fold-right – accumulator maintained by delegate

Page 11: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Example – Fold

· · ·

Q(ε) ∗ list(lst, a1 · a2 · a3 · α, P )

lst

• Q(α): accumulator predicate; state after having folded over α

Page 12: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Example – Fold

· · ·

Q(a1 · ε) ∗ list(lst, a2 · a3 · α, P )

lst

• Q(α): accumulator predicate; state after having folded over α

Page 13: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Example – Fold

· · ·

list(lst, a3 · α, P )Q(a2 · a1 · ε) ∗

lst

• Q(α): accumulator predicate; state after having folded over α

Page 14: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Example – Fold

Specification

void fold〈X〉(Node〈X〉 lst, Action〈Node〈X〉〉 f) { ... }∀α : Val. ∀P : Val× Val→ Prop. ∀Q : Val→ Prop.

{list(lst, α,P) ∗Q(ε) ∗ ∀a, β, y : Val.

f 7→ 〈(x). {x .next 7→ ∗ x .val 7→ y ∗ P(y , a) ∗Q(β)}{Q(a · β)}〉}

{Q(rev(α))}

• Q(α): accumulator predicate; state after having folded over α

• rev(α): mathematical reverse function

• M 7→ 〈(φ).{P} {Q}〉: M denotes delegate satisfying spec

Page 15: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Example – Fold

Specification

void fold〈X〉(Node〈X〉 lst, Action〈Node〈X〉〉 f) { ... }∀α : Val. ∀P : Val× Val→ Prop. ∀Q : Val→ Prop.

{list(lst, α,P) ∗Q(ε) ∗ ∀a, β, y : Val.

f 7→ 〈(x). {x .next 7→ ∗ x .val 7→ y ∗ P(y , a) ∗Q(β)}{Q(a · β)}〉}

{Q(rev(α))}

• Q(α): accumulator predicate; state after having folded over α

• rev(α): mathematical reverse function

• M 7→ 〈(φ).{P} {Q}〉: M denotes delegate satisfying spec

Page 16: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Variable capture

Increment example

int x = 0;Action f = delegate () {

x++;

};

f();

Page 17: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Variable capture

Increment example

int x = 0;Action f = delegate () {

{ x = n }x++;{ x = n + 1 }

};{ x = 0 ∗ ∀n. f 7→ 〈{ x = n } { x = n + 1 }〉 }

f();

Page 18: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Variable capture

Increment example

int x = 0;Action f = delegate () {

{ x = n }x++;{ x = n + 1 }

};{ x = 0 ∗ ∀n. f 7→ 〈{ x = n } { x = n + 1 }〉 }

f(); ⇒ f 7→〈{ 0 = 0 } { 0 = 1 }〉

Page 19: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Variable capture

Increment example

int x = 0;Action f = delegate () {

{ emp }x++;{ emp }

};{ x = 0 ∗ f 7→ 〈{ emp } { emp }〉 }

f();

Page 20: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Variable capture

Increment example

int x = 0;Action f = delegate () {

{ emp }x++;{ emp }

};{ x = 0 ∗ f 7→ 〈{ emp } { emp }〉 }

f();

Issues

• How to refer to captured variables in nested specs

• How to keep track of potentially modified variables

Page 21: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Variable capture

Variable assertions

• Extend assertion logic with variable assertions Ms7→ N,&x

• Ms7→ N: location M is allocated on the stack and contains N

• &x : denotes location of program variable x

Inline delegate

int x = 0;Action f = delegate () {{ P }

B{ Q }

};{ x = 0 ∗ f 7→ 〈{ ∃y. &x

s7→ y ∗ [y/x]P } { ∃y. &xs7→ y ∗ [y/x]Q }〉 }

Page 22: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Variable capture

Variable assertions

• Extend assertion logic with variable assertions Ms7→ N,&x

• Ms7→ N: location M is allocated on the stack and contains N

• &x : denotes location of program variable x

Inline delegate

int x = 0;Action f = delegate () {{ P }

B{ Q }

};{ x = 0 ∗ f 7→ 〈{ ∃y. &x

s7→ y ∗ [y/x]P } { ∃y. &xs7→ y ∗ [y/x]Q }〉 }

Page 23: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Variable capture

Variable assertions

• Extend assertion logic with variable assertions Ms7→ N,&x

• Ms7→ N: location M is allocated on the stack and contains N

• &x : denotes location of program variable x

Inline delegate

int x = 0;Action f = delegate () {{ x = n }

x++;{ x = n + 1 }

};{ x = 0 ∗ ∀n. f 7→ 〈{ &x

s7→ n } { &xs7→ n + 1 }〉 }

Page 24: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Variable capture

Variable assertions

• Extend assertion logic with variable assertions Ms7→ N,&x

• Ms7→ N: location M is allocated on the stack and contains N

• &x : denotes location of program variable x

Inline delegate

int x = 0;Action f = delegate () {{ emp }

x++;{ emp }

};{ x = 0 ∗ f 7→ 〈{ ∃y. &x

s7→ y } { ∃y. &xs7→ y }〉 }

Page 25: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Variable capture

Aliasing

• Var. assertions introduce aliasing in reasoning about variables:

• Build separation into specification logic:• Can either reason directly or indirectly, but not both• Reason directly about variables in the program var. ctx. φ

• Hoare’s assignment rule thus stil sound

φ;ψ ` P : Prop x , y ∈ φφ;ψ ` {P[y/x ]}x := y{P}

Page 26: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Variable capture

Aliasing

• Var. assertions introduce aliasing in reasoning about variables:

• Build separation into specification logic:• Can either reason directly or indirectly, but not both• Reason directly about variables in the program var. ctx. φ• Hoare’s assignment rule thus stil sound

φ;ψ ` P : Prop x , y ∈ φφ;ψ ` {P[y/x ]}x := y{P}

Page 27: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Variable capture

Capturing delegates

• Verify body using Hoare treatment of variables

• Switch to SL treatment of captured variables in nested spec

• Switch back to Hoare treatment of variables to verify calls

x 6∈ FV (s)

φ;ψ ` {∃x : Val. ls7→ x ∗ P}s{∃x : Val. l

s7→ x ∗Q}φ, x ;ψ ` {&x = l ∧ P}s{Q}

Page 28: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Variable capture

Capturing delegates

• Verify body using Hoare treatment of variables

• Switch to SL treatment of captured variables in nested spec

• Switch back to Hoare treatment of variables to verify calls

x 6∈ FV (s)

φ;ψ ` {∃x : Val. ls7→ x ∗ P}s{∃x : Val. l

s7→ x ∗Q}φ, x ;ψ ` {&x = l ∧ P}s{Q}

Page 29: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Example – In-place reverse

Node〈X〉 reverse〈X〉(Node〈X〉 lst) {Node〈X〉 head = null;fold〈X〉(lst, delegate (Node〈X〉 x) { x.next = head; head = x; });return head;}

Page 30: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Example – In-place reverse

Node〈X〉 reverse〈X〉(Node〈X〉 lst) {Node〈X〉 head = null;fold〈X〉(lst, delegate (Node〈X〉 x) { x.next = head; head = x; });return head;}

· · ·

head lst

Page 31: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Example – In-place reverse

Node〈X〉 reverse〈X〉(Node〈X〉 lst) {Node〈X〉 head = null;fold〈X〉(lst, delegate (Node〈X〉 x) { x.next = head; head = x; });return head;}

null · · ·

head lst

Page 32: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Example – In-place reverse

Node〈X〉 reverse〈X〉(Node〈X〉 lst) {Node〈X〉 head = null;fold〈X〉(lst, delegate (Node〈X〉 x) { x.next = head; head = x; });return head;}

null · · ·

head lst

Page 33: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Example – In-place reverse

Node〈X〉 reverse〈X〉(Node〈X〉 lst) {Node〈X〉 head = null;fold〈X〉(lst, delegate (Node〈X〉 x) { x.next = head; head = x; });return head;}

∀α : Val. ∀P : Val× Val→ Prop.

{list(lst, α,P)}{r .list(r , rev(α),P)}

Page 34: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Example – In-place reverse

Node〈X〉 reverse〈X〉(Node〈X〉 lst) {Node〈X〉 head = null;fold〈X〉(lst, delegate (Node〈X〉 x) { x.next = head; head = x; });return head;}

· · ·· · ·

Q(β) ∗ list(lst, a · α, P )

head

where Q(α) = ∃n : Val. &heads7→ n ∗ list(n, α,P)

Page 35: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Example – In-place reverse

Node〈X〉 reverse〈X〉(Node〈X〉 lst) {Node〈X〉 head = null;fold〈X〉(lst, delegate (Node〈X〉 x) { x.next = head; head = x; });return head;}

· · ·· · ·

Q(a · β) list(lst, α, P )∗

head

where Q(α) = ∃n : Val. &heads7→ n ∗ list(n, α,P)

Page 36: Verifying Generics and Delegates · IntroductionGenericsDelegate clientsCapturing delegates Setup C# subset Basic imperative features + generics + delegates Assertion logic Logic

Introduction Generics Delegate clients Capturing delegates

Conclusion

Generics and non-capturing delegates

• HOL & nested Hoare triples (standard)

Capturing delegates

• Separation logic treatment of variables

• Variable separation build into specification logic

• Unified treatment of local state on the heap and/or stack

• Reasoning standard when there is no capturing