A MuDDy Experience - ML Bindings to a BDD Library
Upcoming SlideShare
Loading in...5
×
 

A MuDDy Experience - ML Bindings to a BDD Library

on

  • 716 views

Slides for WCDSL09

Slides for WCDSL09

Statistics

Views

Total Views
716
Views on SlideShare
714
Embed Views
2

Actions

Likes
0
Downloads
1
Comments
0

1 Embed 2

http://www.linkedin.com 2

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

A MuDDy Experience - ML Bindings to a BDD Library A MuDDy Experience - ML Bindings to a BDD Library Presentation Transcript

  • 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
  • The Message ML and BDDs hits a sweet spot 2 / 20
  • 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 flavours Been used in many different projects over the years Domain Specific Embedded Language (DSEL) You embed a DSL in a general-purpose language 3 / 20
  • 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 verification and hardware synthesis Excellent for representing large relations, for instance. 4 / 20
  • 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 verification and hardware synthesis Excellent for representing large relations, for instance. Did I mention it is a canonical representation? 4 / 20
  • An Example BDD A BDD representing (x ⇔ y) ∧ ¬z x y y z 0 1 With variable ordering x < y < z 5 / 20
  • MuDDy MuDDy supports most features from BuDDy Structure bdd contains functions for manipulating BDDs Structure fdd contains functions for manipulating finite 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
  • 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
  • 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
  • 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 defining a (huge) transition predicate 5. Use BDDs to find the set of reachable states and analyse all reachable states in one go. 8 / 20
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • Putting It All Together To find all the reachable states of a SGCL program first 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
  • 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
  • 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
  • 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 finite state machines 20 / 20