Upcoming SlideShare
×

# A MuDDy Experience - ML Bindings to a BDD Library

546 views

Published on

Slides for WCDSL09

Published in: Technology, Health & Medicine
0 Likes
Statistics
Notes
• Full Name
Comment goes here.

Are you sure you want to Yes No
Your message goes here
• Be the first to comment

• Be the first to like this

Views
Total views
546
On SlideShare
0
From Embeds
0
Number of Embeds
12
Actions
Shares
0
2
0
Likes
0
Embeds 0
No embeds

No notes for slide

### A MuDDy Experience - ML Bindings to a BDD Library

1. 1. A MuDDy Experience ML Bindings to a BDD Library Ken Friis Larsen kflarsen@diku.dk Department of Computer Science University of Copenhagen July 15, 2009 1 / 20
2. 2. The Message ML and BDDs hits a sweet spot 2 / 20
3. 3. Background BuDDy C library for Binary Decision Diagrams by Jørn Lind-Nielsen State-of-art performance . . . 10 years ago MuDDy An ML interface to BuDDy Comes in Moscow ML, MLton, and O’Caml ﬂavours Been used in many different projects over the years Domain Speciﬁc Embedded Language (DSEL) You embed a DSL in a general-purpose language 3 / 20
4. 4. Binary Decision Diagrams A BDD is: A canonical explicit directed acyclic graph representation of a boolean function A boolean expression on if-then-else normal form BDDs are mainly used for formal veriﬁcation and hardware synthesis Excellent for representing large relations, for instance. 4 / 20
5. 5. Binary Decision Diagrams A BDD is: A canonical explicit directed acyclic graph representation of a boolean function A boolean expression on if-then-else normal form BDDs are mainly used for formal veriﬁcation and hardware synthesis Excellent for representing large relations, for instance. Did I mention it is a canonical representation? 4 / 20
6. 6. An Example BDD A BDD representing (x ⇔ y) ∧ ¬z x y y z 0 1 With variable ordering x < y < z 5 / 20
7. 7. MuDDy MuDDy supports most features from BuDDy Structure bdd contains functions for manipulating BDDs Structure fdd contains functions for manipulating ﬁnite domain values, represented by a set of BDDs Structure bvec contains functions for representing and manipulating machine words represented by a set of BDDs. 6 / 20
8. 8. Building BDDs from SML Building a BDD representing the expression (x ⇒ y ∧ x) ⇒ y val (x, y) = (bdd.ithvar 0, bdd.ithvar 1) val b = (x ==> y / x) ==> y 7 / 20
9. 9. Building BDDs from SML Building a BDD representing the expression (x ⇒ y ∧ x) ⇒ y val (x, y) = (bdd.ithvar 0, bdd.ithvar 1) val b = (x ==> y / x) ==> y Given the syntactic sugar: infix ==> / val(op /, op ==>) = (bdd.AND, bdd.IMP) 7 / 20
10. 10. Using BDDs to Analyse a DS(E)L 1. Design your language 2. Declare types for representing abstract syntax trees 3. Design a concrete syntax 4. Use BDDs to model the semantics of your language Usually that means deﬁning a (huge) transition predicate 5. Use BDDs to ﬁnd the set of reachable states and analyse all reachable states in one go. 8 / 20
11. 11. Simple Guarded Command Language e ::= true | false | x | e1 op e2 | ¬e assignment ::= x1 , . . . , xn := e1 , . . . , en command ::= e ? assignment program ::= assignment command1 || . . . || commandn 9 / 20
12. 12. Milner’s Scheduler h1 c1 c2 start h0 h2 c0 c3 h3 cycler i = ci ∧ ¬ti ? ti , ci , hi := true, ¬ci , true || hi ? ci+1 mod N , hi := true, false 10 / 20
13. 13. SGCL Embedded in SML, Abstract syntax type var = string datatype boolop = AND | OR | IMP | BIIMP datatype bexp = BVar of var | BBin of bexp * boolop * bexp | NOT of bexp | TRUE | FALSE datatype command = CMD of bexp * (var * bexp) list datatype program = PRG of (var * bexp) list * command list 11 / 20
14. 14. SGCL Embedded in SML, Syntactic Sugar fun mkBBin opr (x, y) = BBin(x, opr, y) infix / / ==> <==> val (op /, op /, op ==>, op <==>) = (mkBBin AND, mkBBin OR, mkBBin IMP, mkBBin BIIMP) infix ::= val op ::= = ListPair.zip infix ? fun g ? ass = [CMD(g, ass)] infix || val op|| = op@ val \$ = BVar 12 / 20
15. 15. Milner’s Scheduler in SML/SGCL val (c0, t0,...,t3, h3) = ("c0", "t0",...,"t3", "h3") fun cycler c t h c’ = (\$c <==> TRUE / \$t <==> FALSE) ? ([t, c, h] ::= [TRUE, NOT(\$c), TRUE]) || ((\$h <==> TRUE) ? ([c’, h] ::= [TRUE, FALSE])) fun task t = \$t ? ([t] ::= [FALSE]) val milner4 = PRG( [(c0, TRUE), (t0, FALSE), (h0, FALSE), ... ] cycler c0 t0 h0 c1 || cycler c1 t1 h1 c2 || cycler c2 t2 h2 c3 || cycler c3 t3 h3 c0 || task t0 || task t1 || task t2 || task t3) 13 / 20
16. 16. Semantics of SGCL The semantics of a command is a predicate describing a state change by using a ordinary variables to describe the current state and primed variables to describe the next state. The semantics of a program is a predicate describing the initial state, and conjunction of the semantics of the commands. type bdd_vars = { var: int, primed: int} type var_map = string * bdd_vars val commandToBDD: var_map -> command -> bdd.bdd val programToBDD: var_map -> program -> bdd.bdd * bdd.bdd 14 / 20
17. 17. Semantics of SGCL fun commandToBDD allVars (CMD(guard, assignments)) = let val changed = List.map #1 assignments val unchanged = List.foldl (fn ((v, {var, primed}), res) => if mem v changed then res else bdd.AND(bdd.BIIMP(bdd.ithvar primed, bdd.ithvar var), res)) bdd.TRUE allVars val assigns = conj (map (fn (v,be) => bdd.BIIMP(primed v, bexp be)) assignments) in bdd.IMP(bexp guard, assigns) end 15 / 20
18. 18. Finding All Reachable States fun reachable allVars I T = let val renames = List.map (fn(_,{var,primed}) => (var, primed)) allVars val pairset = bdd.makepairSet renames val unprimed = bdd.makeset(List.map #var allVars) open bdd infix OR fun loop R = let val post = appex T R And unprimed val next = R OR replace next pairset in if equal R next then R else loop next end in loop I end 16 / 20
19. 19. Putting It All Together To ﬁnd all the reachable states of a SGCL program ﬁrst call programToBDD and then reachable: val milner4 = ... val allVars = ... val (I, T) = programToBDD allVars milner4 val states = reachable allVars I T We can now easily check some invariants. For example, that if cycler 2 holds a token, no other cycler has a token: val c2inv = \$c2 ==> NOT(\$c0) / NOT(\$c1) / NOT(\$c3) val check_c2inv = bdd.IMP (states, bexp allVars c2inv) 17 / 20
20. 20. Keeping It Honest The construction of the mapping between DSL variables and BDDs variables is usually where things go sour. That is, it is hard to choose a good BDD variable ordering. No general algorithm, but the following heuristics gives good results: a variable and its primed version should be next to each other in the ordering if two variables are “close” to each other in the syntax tree, they should be close to each other in the ordering if a variable occurs with high frequency in the syntax tree, it should be in the beginning of the ordering 18 / 20
21. 21. What About Performance? No. of Schedulers: 50 100 150 200 C 1.63 4.69 13.66 31.20 C++ 1.66 4.82 13.89 31.51 O’Caml (native) 1.71 5.04 14.47 32.05 O’Caml (bytecode) 1.74 5.15 14.58 32.91 Moscow ML 1.76 5.15 15.12 33.42 Fresh runs on current laptop: No. of Schedulers: 50 100 150 200 C 0.38 1.07 3.18 7.25 O’Caml (native) 0.35 1.21 3.42 7.64 O’Caml (bytecode) 0.38 1.24 3.52 7.82 Moscow ML 0.37 1.21 3.45 7.73 MLton 0.38 1.29 3.68 8.14 19 / 20
22. 22. Summary ML and BDDs hits a sweet spot reasonably easy to embed DSLs in ML languages MLs gives few surprises with respect to space usage and execution BDDs can be used to represent many nice abstractions symbolically SGCL is a nice way to specify ﬁnite state machines 20 / 20