Who Watches the Watchers: Toward Provably-correct Decision Diagram - - PowerPoint PPT Presentation

who watches the watchers toward provably correct decision
SMART_READER_LITE
LIVE PREVIEW

Who Watches the Watchers: Toward Provably-correct Decision Diagram - - PowerPoint PPT Presentation

Who Watches the Watchers: Toward Provably-correct Decision Diagram Code Yousra Lembachar , Ryan Rusich, Iulian Neamtiu, Gianfranco Ciardo University of California, Riverside 1 / 18 Toward a Completely Verified Software Toolchain 2 / 18 Toward


slide-1
SLIDE 1

Who Watches the Watchers: Toward Provably-correct Decision Diagram Code

Yousra Lembachar, Ryan Rusich, Iulian Neamtiu, Gianfranco Ciardo

University of California, Riverside

1 / 18

slide-2
SLIDE 2

Toward a Completely Verified Software Toolchain

2 / 18

slide-3
SLIDE 3

Toward a Completely Verified Software Toolchain

2 / 18

slide-4
SLIDE 4

Toward a Completely Verified Software Toolchain

2 / 18

slide-5
SLIDE 5

Toward a Completely Verified Software Toolchain

2 / 18

slide-6
SLIDE 6

Toward a Completely Verified Software Toolchain

2 / 18

slide-7
SLIDE 7

Toward a Completely Verified Software Toolchain

2 / 18

slide-8
SLIDE 8

Our Contribution

◮ Bddl

◮ A calculus for reasoning about decision diagram library and

client code

◮ Provides a sound type system with operational semantics ◮ Enables compile-time detection of dynamic errors ◮ Enforces correct structural properties and semantics for

decision diagrams

◮ Demonstrate the efficacy of our approach via real world bugs

detected in three mature libraries: CUDD (NuSMV), MDDL (SMART), and JavaBDD

3 / 18

slide-9
SLIDE 9

Runtime Error Example in CUDD

int main () { Cudd mgr(0,2); BDD x = mgr.bddVar(); BDD y = mgr.bddVar(); BDD h = x * y; BDD j = x + y; BDD k = h.Compose(j,2); }

1 1 1 1 h = x.y 1 1 1 j = x+y 1 y x

DdNode* Cudd bddCompose( DdManager * dd, DdNode * f, DdNode * g, int v) { DdNode *proj, *res; /* Sanity check. */ if (v < 0 || v >= dd->size) return(NULL); proj =dd->vars[v]; do { ... } while (dd->reordered == 1); return(res);} BDD BDD::Compose(BDD g, int v) { ... return BDD(..., Cudd bddCompose( mgr.node, g.node, v)); }

4 / 18

slide-10
SLIDE 10

Runtime Error Example in CUDD

int main () { Cudd mgr(0,2); BDD x = mgr.bddVar(); BDD y = mgr.bddVar(); BDD h = x * y; BDD j = x + y; BDD k = h.Compose(j,2); }

1 1 1 1 x y 1 1 1 1 h = x.y j = x+y

DdNode* Cudd bddCompose( DdManager * dd, DdNode * f, DdNode * g, int v) { DdNode *proj, *res; /* Sanity check. */ if (v < 0 || v >= dd->size) return(NULL); proj =dd->vars[v]; do { ... } while (dd->reordered == 1); return(res);} BDD BDD::Compose(BDD g, int v) { ... return BDD(..., Cudd bddCompose( mgr.node, g.node, v)); }

4 / 18

slide-11
SLIDE 11

Runtime Error Example in CUDD

int main () { Cudd mgr(0,2); BDD x = mgr.bddVar(); BDD y = mgr.bddVar(); BDD h = x * y; BDD j = x + y; BDD k = h.Compose(j,2); }

1 1 1 1 x y h = x.y 1 1 1 j = x+y 1 z

DdNode* Cudd bddCompose( DdManager * dd, DdNode * f, DdNode * g, int v) { DdNode *proj, *res; /* Sanity check. */ if (v < 0 || v >= dd->size) return(NULL); proj = dd->vars[v]; do { ... } while (dd->reordered == 1); return(res);} BDD BDD::Compose(BDD g, int v) { ... return BDD(..., Cudd bddCompose( mgr.node, g.node, v)); }

4 / 18

slide-12
SLIDE 12

Binary Decision Diagrams (BDDs)

Binary tree BDD

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 v1 v2 v3 v4 1 1 1 1 1 1 1

f (v1, v2, v3, v4) = (v4 ∨ v2) ∧ (v3 → v1)

5 / 18

slide-13
SLIDE 13

BDD Encodings - Sets and n-ary relations

Set Binary relation

1 1 1 1 1 1 {0011, 0101, 0110, 0111, 1001, 1010, 1011, 1101, 1110, 1111} 1 1 1 v1 v2 v3 v4

{(01,01) (00,11) (01,10) (01,11) (10,01) (11,00) (11,01) (10,11) (11,10) (11,11)}

1 1 1 1 1 1 1 1 1 1 1 1 1 v1 v2 v2 v1 ’ ’

6 / 18

slide-14
SLIDE 14

BDD Encodings - Sets and n-ary relations

Set Binary relation

1 1 1 1 1 1 1 1 1

(0 0 1 1)

1 v1 v2 v3 v4 v1 v2 v3 v4 1 1 1 1 1 1 1 1 1 1 1 1 1

(0 1, 0 1)

v2 v1 ’ ’ v2 v1 v1 v2 v2 v1 ’ ’

6 / 18

slide-15
SLIDE 15

BDD Reduction Rules

Reduction rules for canonicity and compactness...

1 1 1 1 1 1 1 v2 + v1 v1 v2 v3 v4 1 1 1 1 1 1 v2 + v1 1 1 1 1 1 v2 + v1

Fully-reduced (left) vs. quasi-reduced (right) BDDs

7 / 18

slide-16
SLIDE 16

Bddl Calculus

8 / 18

slide-17
SLIDE 17

Bddl Terms - The Bnode term and its attributes

t ::= v | x | succ t | pred t | iszero t | λ:τ.t | t t | letrec x : τ = t in t | if then t else t t | ref t | !t | Bnode (t, i, t, t, t) | t.level | t.index | t.var | t.tchild | t.fchild

1 1 v1 succ(0)

Bnode(succ 0, id2, , ref , ref

v1

1 0 )

9 / 18

slide-18
SLIDE 18

Bddl Terms - The Bnode term and its attributes

t ::= v | x | succ t | pred t | iszero t | λ:τ.t | t t | letrec x : τ = t in t | if then t else t t | ref t | !t | Bnode (t, i, t, t, t) | t.level | t.index | t.var | t.tchild | t.fchild

1 1 v1 succ(0)

Bnode(succ 0, id2, , ref , ref

v1

1 0 )

9 / 18

slide-19
SLIDE 19

Bddl Terms - The Bnode term and its attributes

t ::= v | x | succ t | pred t | iszero t | λ:τ.t | t t | letrec x : τ = t in t | if then t else t t | ref t | !t | Bnode (t, i, t, t, t) | t.level | t.index | t.var | t.tchild | t.fchild

1 1 v1 succ(0)

Bnode(succ 0, id2, , ref , ref

v1

1 0 )

9 / 18

slide-20
SLIDE 20

Bddl Terms - The Bnode term and its attributes

t ::= v | x | succ t | pred t | iszero t | λ:τ.t | t t | letrec x : τ = t in t | if then t else t t | ref t | !t | Bnode (t, i, t, t, t) | t.level | t.index | t.var | t.tchild | t.fchild

1 1 v1 succ(0)

Bnode(succ 0, id2, , ref , ref

v1

1 0 )

9 / 18

slide-21
SLIDE 21

Bddl Terms - The Bnode term and its attributes

t ::= v | x | succ t | pred t | iszero t | λ:τ.t | t t | letrec x : τ = t in t | if then t else t t | ref t | !t | Bnode (t, i, t, t, t) | t.level | t.index | t.var | t.tchild | t.fchild

1 1 v1 succ(0)

Bnode(succ 0, id2, , ref , ref

v1

1 0 )

9 / 18

slide-22
SLIDE 22

Bddl Terms - The Bnode term and its attributes

t ::= v | x | succ t | pred t | iszero t | λ:τ.t | t t | letrec x : τ = t in t | if then t else t t | ref t | !t | Bnode (t, i, t, t, t) | t.level | t.index | t.var | t.tchild | t.fchild

1 1 v1 succ(0)

Bnode(succ 0, id2, , ref , ref

v1

1 0 )

9 / 18

slide-23
SLIDE 23

Bddl Terms - λ-calculus based terms

t ::= v | x | succ t | pred t | iszero t | λ:τ.t | t t | letrec x : τ = t in t | if then t else t t | ref t | !t | Bnode (t, i, t, t, t) | t.level | t.index | t.var | t.tchild | t.fchild letrec v1 = ... in letrec id2 = ... in letrec build = λ n . /* n = succ(0)*/ λ b . /* b = true*/ if iszero n then (if b then 1 else 0 ) else Bnode (succ(0), id2, v1, build 0 true, build 0 false) in build (succ(0) true)

1 1 v1 succ(0)

10 / 18

slide-24
SLIDE 24

Bddl Terms - λ-calculus based terms

t ::= v | x | succ t | pred t | iszero t | λ:τ.t | t t | letrec x : τ = t in t | if then t else t t | ref t | !t | Bnode (t, i, t, t, t) | t.level | t.index | t.var | t.tchild | t.fchild letrec v1 = ... in letrec id2 = ... in letrecbuild = λ n. /* n = succ(0)*/ λ b. /* b = true*/ if iszero n then (if b then 1 else 0 ) else Bnode (succ(0), id2, v1, build 0 true, build 0 false) in build (succ(0) true)

1 1 v1 succ(0)

10 / 18

slide-25
SLIDE 25

Bddl Terms - λ-calculus based terms

t ::= v | x | succ t | pred t | iszero t | λ:τ.t | t t | letrec x : τ = t in t | if then t else t t | ref t | !t | Bnode (t, i, t, t, t) | t.level | t.index | t.var | t.tchild | t.fchild letrec v1 = ... in letrec id2 = ... in letrecbuild = λ n. λ b. if iszero n then (if b then 1 else 0 ) else Bnode (succ(0), id2, v1, build 0 true, build 0 false) in build (succ(0) true)

1 1 v1 succ(0) build(0 true) build(0 false)

10 / 18

slide-26
SLIDE 26

Bddl Types

τ := bool | nat | string | Id | τ → τ | ref τ | bdd[l,r,c] | ν : τ | p(π) l := ⊥, nv r := ⊥, f, q c := ⊥, s, e π := ν | l | r | c letrec v1 : string = ... in letrec id2 : Id = ... in letrec build : {ν : nat | ν = l} → bool → bdd[l, r, c] | l ≤ 1 λ n . λ b . if iszero n then (if b then 1 else 0 ) else Bnode (succ(0), id2, v1, build 0 true, build 0 false) in build (succ(0) true)

1 1 bdd[1,q,s]

11 / 18

slide-27
SLIDE 27

Type checking and type inference for a 3-level BDD

type??

Bnode(3,id7,x2,ref t4,ref t5) Bnode(2,id6,x1 ref t2,ref t3) Bnode(2,id5,x1,ref t2,ref t1) Bnode(1,id4,x3,ref 0 ,ref 0 ) Bnode(1,id3,x3,ref 1 ,ref 0 ) Bnode(1,id2,x3,ref 0 ,ref 1 )

1

T-Bnode

Γ ⊢ id : Id id ∈ dom(Γ) Γ ⊢ vvar : string Γ ⊢ t0 : {ν : nat | ν ≥ 1 ∧ ν = l} Γ ⊢ t1:ref bdd[l′, r, c] bdd[l′, r, c] <:B {ν : bdd[p, r, c] | l = p + 1} Γ ⊢ t2:ref bdd[l′′, r, c] bdd[l′′, r, c] <:B {ν : bdd[p′, r, c] | l = p′ + 1} Γ, id : Id ⊢ Bnode(t0,id,vvar,t1,t2) : bdd[l, r, c]

12 / 18

slide-28
SLIDE 28

Type checking and type inference for a 3-level BDD

Bnode(3,id7,x2,ref t4,ref t5)

3 : {ν : nat | ν ≥ 1 ∧ ν = 3}

Bnode(2,id6,x1 ref t2,ref t3) Bnode(2,id5,x1,ref t2,ref t1) Bnode(1,id4,x3,ref 0 ,ref 0 ) Bnode(1,id3,x3,ref 1 ,ref 0 ) Bnode(1,id2,x3,ref 0 ,ref 1 )

1

T-Bnode

Γ ⊢ id : Id id ∈ dom(Γ) Γ ⊢ vvar : string Γ ⊢t0 : {ν : nat | ν ≥ 1 ∧ ν = l} Γ ⊢ t1:ref bdd[l′, r, c] bdd[l′, r, c] <:B {ν : bdd[p, r, c] | l = p + 1} Γ ⊢ t2:ref bdd[l′′, r, c] bdd[l′′, r, c] <:B {ν : bdd[p′, r, c] | l = p′ + 1} Γ, id : Id ⊢ Bnode (t0 ,id,vvar,t1,t2) : bdd[l, r, c]

12 / 18

slide-29
SLIDE 29

Type checking and type inference for a 3-level BDD

Bnode(3,id7,x2,ref t4,ref t5)

id7 : Id, id7 ∈ Γ

Bnode(2,id6,x1 ref t2,ref t3) Bnode(2,id5,x1,ref t2,ref t1) Bnode(1,id4,x3,ref 0 ,ref 0 ) Bnode(1,id3,x3,ref 1 ,ref 0 ) Bnode(1,id2,x3,ref 0 ,ref 1 )

1

T-Bnode

Γ ⊢ id:Id id ∈ dom(Γ) Γ ⊢ vvar : string Γ ⊢ t0 : {ν : nat | ν ≥ 1 ∧ ν = l} Γ ⊢ t1:ref bdd[l′, r, c] bdd[l′, r, c] <:B {ν : bdd[p, r, c] | l = p + 1} Γ ⊢ t2:ref bdd[l′′, r, c] bdd[l′′, r, c] <:B {ν : bdd[p′, r, c] | l = p′ + 1} Γ, id : Id ⊢ Bnode (t0,id ,vvar,t1,t2) : bdd[l, r, c]

12 / 18

slide-30
SLIDE 30

Type checking and type inference for a 3-level BDD

Bnode(3,id7,x2,ref t4,ref t5)

x2 : string

Bnode(2,id6,x1 ref t2,ref t3) Bnode(2,id5,x1,ref t2,ref t1) Bnode(1,id4,x3,ref 0 ,ref 0 ) Bnode(1,id3,x3,ref 1 ,ref 0 ) Bnode(1,id2,x3,ref 0 ,ref 1 )

1

T-Bnode

Γ ⊢ id : Id id ∈ dom(Γ) Γ ⊢ vvar : string Γ ⊢ t0 : {ν : nat | ν ≥ 1 ∧ ν = l} Γ ⊢ t1:ref bdd[l′, r, c] bdd[l′, r, c] <:B {ν : bdd[p, r, c] | l = p + 1} Γ ⊢ t2:ref bdd[l′′, r, c] bdd[l′′, r, c] <:B {ν : bdd[p′, r, c] | l = p′ + 1} Γ, id : Id ⊢ Bnode (t0,id,vvar ,t1,t2) : bdd[l, r, c]

12 / 18

slide-31
SLIDE 31

Type checking and type inference for a 3-level BDD

Bnode(3,id7,x2,ref t4,ref t5)

ref t4 : type? t4 : type? t2, t1 : type? type?

Bnode(2,id6,x1 ref t2,ref t3) Bnode(2,id5,x1,ref t2,ref t1) Bnode(1,id4,x3,ref 0 ,ref 0 ) Bnode(1,id3,x3,ref 1 ,ref 0 ) Bnode(1,id2,x3,ref 0 ,ref 1 )

1

T-Bnode

Γ ⊢ id : Id id ∈ dom(Γ) Γ ⊢ vvar : string Γ ⊢ t0 : {ν : nat | ν ≥ 1 ∧ ν = l} Γ ⊢ t1:ref bdd[l′, r, c] bdd[l′, r, c] <:B {ν : bdd[p, r, c] | l = p + 1} Γ ⊢ t2:ref bdd[l′′, r, c] bdd[l′′, r, c] <:B {ν : bdd[p′, r, c] | l = p′ + 1} Γ, id : Id ⊢ Bnode (t0,id,vvar,t1 ,t2) : bdd[l, r, c]

12 / 18

slide-32
SLIDE 32

Type checking and type inference for a 3-level BDD

Bnode(3,id7,x2,ref t4,ref t5)

ref t4: ref bdd[2,r,c] t4 : bdd[2,r,c] t2, t1 : bdd[1,r,c] bdd[0,r,c]

Bnode(2,id6,x1 ref t2,ref t3) Bnode(2,id5,x1,ref t2,ref t1) Bnode(1,id4,x3,ref 0 ,ref 0 ) Bnode(1,id3,x3,ref 1 ,ref 0 ) Bnode(1,id2,x3,ref 0 ,ref 1 )

1

T-Bnode

Γ ⊢ id : Id id ∈ dom(Γ) Γ ⊢ vvar : string Γ ⊢ t0 : {ν : nat | ν ≥ 1 ∧ ν = l} Γ ⊢ t1:ref bdd[l′, r, c] bdd[l′, r, c] <:B {ν : bdd[p, r, c] | l = p + 1} Γ ⊢ t2:ref bdd[l′′, r, c] bdd[l′′, r, c] <:B {ν : bdd[p′, r, c] | l = p′ + 1} Γ, id : Id ⊢ Bnode (t0,id,vvar,t1 ,t2) : bdd[l, r, c]

12 / 18

slide-33
SLIDE 33

Type checking and type inference for a 3-level BDD

Bnode(3,id7,x2,ref t4,ref t5)

ref t5: ref bdd[2,r,c]

Bnode(2,id6,x1 ref t2,ref t3) Bnode(2,id5,x1,ref t2,ref t1) Bnode(1,id4,x3,ref 0 ,ref 0 ) Bnode(1,id3,x3,ref 1 ,ref 0 ) Bnode(1,id2,x3,ref 0 ,ref 1 )

1

T-Bnode

Γ ⊢ id : Id id ∈ dom(Γ) Γ ⊢ vvar : string Γ ⊢ t1:ref bdd[l′, r, c] bdd[l′, r, c] <:B {ν : bdd[p, r, c] | l = p + 1} Γ ⊢ t2:ref bdd[l′′, r, c] bdd[l′′, r, c] <:B {ν : bdd[p′, r, c] | l = p′ + 1} Γ, id : Id ⊢ Bnode (t0,id,vvar,t1,t2 ) : bdd[l, r, c]

12 / 18

slide-34
SLIDE 34

Type checking and type inference for a 3-level BDD

Bnode(3,id7,x2,ref t4,ref t5)

bdd[2,r,c] <:B {ν : bdd[2, r, c]}

Bnode(2,id6,x1 ref t2,ref t3) Bnode(2,id5,x1,ref t2,ref t1) Bnode(1,id4,x3,ref 0 ,ref 0 ) Bnode(1,id3,x3,ref 1 ,ref 0 ) Bnode(1,id2,x3,ref 0 ,ref 1 )

1

T-Bnode

Γ ⊢ id : Id id ∈ dom(Γ) Γ ⊢ vvar : string Γ ⊢ t1:ref bdd[l′, r, c] bdd[l’,r,c] <:B {ν : bdd[p, r, c] | l = p + 1} Γ ⊢ t2:ref bdd[l′′, r, c] bdd[l′′, r, c] <:B {ν : bdd[p′, r, c] | l = p′ + 1} Γ, id : Id ⊢ Bnode (t0,id,vvar,t1,t2) : bdd[l, r, c]

12 / 18

slide-35
SLIDE 35

Type checking and type inference for a 3-level BDD

Bnode(3,id7,x2,ref t4,ref t5)

bdd[3,r,c]

Bnode(2,id6,x1 ref t2,ref t3) Bnode(2,id5,x1,ref t2,ref t1) Bnode(1,id4,x3,ref 0 ,ref 0 ) Bnode(1,id3,x3,ref 1 ,ref 0 ) Bnode(1,id2,x3,ref 0 ,ref 1 )

1

T-Bnode

Γ ⊢ id : Id id ∈ dom(Γ) Γ ⊢ vvar : string Γ ⊢ t1:ref bdd[l′, r, c] bdd[l′, r, c] <:B {ν : bdd[p, r, c] | l = p + 1} Γ ⊢ t2:ref bdd[l′′, r, c] bdd[l′′, r, c] <:B {ν : bdd[p′, r, c] | l = p′ + 1} Γ, id : Id ⊢ Bnode (t0,id,vvar,t1,t2) : bdd[l,r,c]

12 / 18

slide-36
SLIDE 36

Bddl in Action: Runtime Error Prevention in CUDD

DdNode* Cudd_bddCompose( ... // bdd composition } int main () { Cudd mgr(0,2); BDD x = mgr.bddVar(); BDD y = mgr.bddVar(); BDD h = x * y; BDD j = x + y; BDD k = h.Compose(j,2); }

= ⇒

letrec two : {ν : nat | ν = 2} = (succ (succ 0)) in letrec bddCompose : bdd[l, r, c] → bdd[l′, r, c]→ {ν : nat | ν ≤ l − 1} → bdd[l”, r, c] = λ f . λ g . λ v . <body> in letrec h = Bnode(two, ...) in letrec j = ... in letrec k = bddCompose h j two ;

13 / 18

slide-37
SLIDE 37

Bddl in Action: Runtime Error Prevention in CUDD

DdNode* Cudd_bddCompose( ... // bdd composition } int main () { Cudd mgr(0,2); BDD x = mgr.bddVar(); BDD y = mgr.bddVar(); BDD h = x * y; BDD j = x + y; BDD k = h.Compose(j,2); }

= ⇒

letrec two : {ν : nat | ν = 2} = (succ (succ 0)) in letrec bddCompose : bdd[l, r, c] → bdd[l′, r, c] → {ν : nat | ν ≤ l − 1} → bdd[l”, r, c] = λ f . λ g . λ v . <body> in letrec h : bdd[2,r,c] = ... in letrec j : bdd[2,r,c] = ... in letrec k = bddCompose h j two {ν : nat | ν = 2} = {ν : nat | ν ≤ 1}

Runtime time error Compile time error

13 / 18

slide-38
SLIDE 38

Bddl in Action: Runtime Error Prevention in MDDL

BddNode* Union_QQ( BddNode *p, BddNode *q){ ASSERT((k = p->GetLevel())) == q->GetLevel()); ... ka = answer→ GetLevel(); ASSERT(ka == k); return answer; } int main () { BddNode *f = new_bdd(1); BddNode *g = new_bdd(2); BddNode *res = Union QQ(f,g); }

= ⇒

letrec union : bbd[l, q, c]-> bbd[l, q, c] -> bbd[l, q, c]) = λ p . λ r . <body> in letrec f : bbd[1, q, s] = ... in letrec g : bbd[2, q, s] = ... in union f g

14 / 18

slide-39
SLIDE 39

Bddl in Action: Runtime Error Prevention in MDDL

BddNode* Union_QQ( BddNode *p, BddNode *q){ ASSERT((k = p->GetLevel())) == q->GetLevel()); ... ka = answer→ GetLevel(); ASSERT(ka == k); return answer; } int main () { BddNode *f = new_bdd(1); BddNode *g = new_bdd(2); BddNode *res = Union QQ(f,g); }

= ⇒

letrec union : bbd[l, q, c] -> bbd[l, q, c] -> bdd[l, q, c]) = λ p . λ r . <body> in letrec f :bbd[1, q, s] = ... in letrec g :bbd[2, q, s] = ... in union f g bdd[1, q, s] = bdd[2, q, s]

Runtime time error Compile time error

14 / 18

slide-40
SLIDE 40

Bddl in Action: Runtime Error Prevention in JavaBDD

public class BasicTests extends BDDTestCase {... public void testCrash() { reset(); Assert.assertTrue(hasNext()); BDDFactory bdd = nextFactory(); BDD a = bdd.one(); bdd.reorder( bdd.getReorderMethod()); }

= ⇒

letrec n : bdd[0,r,c] = 1 in letrec reorder : {ν : bbd[l, r, c] | l ≥ 1} → {ν : bbd[l, r, c] | l ≥ 1} = λ p : bbd[l, r, c]. <body> in reorder n

15 / 18

slide-41
SLIDE 41

Bddl in Action: Runtime Error Prevention in JavaBDD

public class BasicTests extends BDDTestCase {... public void testCrash() { reset(); Assert.assertTrue(hasNext()); BDDFactory bdd = nextFactory(); BDD a = bdd.one(); bdd.reorder( bdd.getReorderMethod()); }

= ⇒

letrec n : bdd[0,r,c] = 1 in letrec reorder : {ν : bbd[l, r, c] | l ≥ 1} → {ν : bbd[l, r, c] | l ≥ 1} = λ p : bbd[l, r, c]. <body> in reorder n bdd[0, r, c] = {bdd[l, r, c]|l ≥ 1}

Runtime time error Compile time error

15 / 18

slide-42
SLIDE 42

Our approach and future directions

BddNode* UnionQQ ( BddNode* p, BddNode* q ){...} ... Original library letrec union: bdd[l,q,c] -> bdd[l,q,c]

  • > {v: bdd[l’,q,c] | l’=l}

... Manually constructed BDDL code @type union: bdd[l,q,c] -> bdd[l,q,c]

  • > {v:bdd[l’,q,c] | l’ = l}

BddNode* UnionQQ ( BddNode* p, BddNode* q){...} ... Annotated code Type checker prototype in O’Caml

16 / 18

slide-43
SLIDE 43

Some Related Work

◮ Static analysis

Lhot´ ak, Ondˇ rej, and Laurie Hendren Jedd: a BDD-based relational extension of Java. PLDI, 2004. ◮ Runtime verification

Rolf Drechsler Verifying integrity of decision diagrams. Integration, the VLSI Journal, 2002. ◮ Liquid types

Ming Kawaguchi, Patrick Rondon, and Ranjit Jhala Type-based data structure verification. PLDI, 2009.

17 / 18

slide-44
SLIDE 44

Conclusion

18 / 18