a modern C++ library for the manipulation of Boolean functions
a modern C++ library for the manipulation of Boolean functions
a modern C++ library for the manipulation of Boolean functions
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
algorithm and write that a node is created, we will leave <strong>the</strong> fact that we are calling<br />
make_node (thus applying <strong>the</strong> third reduction rule) implicit.<br />
3.1.4 Caches<br />
CORAL keeps associative caches <strong>for</strong> most <strong>of</strong> its ROBDD operations. We will not give a<br />
list here as <strong>the</strong>ir names are easily identifiable by <strong>the</strong> Cache suffix in <strong>the</strong> source code. For<br />
simplicity we will not mention <strong>the</strong>m in <strong>the</strong> pseudo-codes.<br />
3.2 ROBDD algorithms<br />
3.2.1 Memory management<br />
CORAL’s class ROBDD does not distinguish a ROBDD from its root node and uses its own<br />
customized mechanisms <strong>for</strong> <strong>the</strong> allocation <strong>of</strong> ROBDD nodes. ROBDD is derived from <strong>the</strong><br />
Reference_Counted_Object class in order <strong>for</strong> ROBDDs to be reference counted, which<br />
means that each ROBDD is normally deallocated (by a garbage collection algorithm)<br />
only after <strong>the</strong>re are no more references to it. The end user, in fact, does not use ROBDD<br />
directly: instead he utilizes <strong>the</strong> ROBDD_Ptr class, which is nothing more than a wrapper<br />
<strong>for</strong> a ROBDD pointer that also automatically adjusts reference counters <strong>of</strong> ROBDDs<br />
whenever <strong>the</strong> underlying pointer is changed.<br />
All ROBDD nodes allocated by CORAL are kept inside an array with variable length,<br />
which is <strong>for</strong>med by a certain number <strong>of</strong> memory chunks. CORAL counts <strong>the</strong> number<br />
<strong>of</strong> allocated chunks and will throw an exception <strong>of</strong> type Too_Many_BDD_Nodes<br />
if it exceeds MAX_CHUNKS_BEFORE_EXCEPTION and <strong>the</strong> public <strong>Boolean</strong> static member<br />
ROBDD::dont_throw is set to false, which means that setting this latter value to false allows<br />
<strong>the</strong> end user to be notified when <strong>the</strong> memory occupation <strong>of</strong> ROBDDs is becoming too<br />
large. In this case, <strong>the</strong> normal behavior consists <strong>of</strong> calling ROBDD::emergency_cleanup()<br />
after catching <strong>the</strong> expression in order to regain some memory.<br />
3.2.2 Algorithms with upward approximation<br />
Algorithms with upward approximation, characterized by <strong>the</strong> substring up in <strong>the</strong>ir names,<br />
can be used on large ROBDDs in order to obtain more efficiency at <strong>the</strong> expense <strong>of</strong><br />
some precision in <strong>the</strong> result. Each <strong>Boolean</strong> function g such that f =⇒ g is an upward<br />
approximation <strong>of</strong> function f. These algorithms return an upward approximation <strong>of</strong> <strong>the</strong><br />
result by trying to per<strong>for</strong>m <strong>the</strong>ir corresponding non-approximated algorithm and checking<br />
if it throws Too_Many_BDD_Nodes: if <strong>the</strong> exception is not thrown <strong>the</strong>n <strong>the</strong> exact result is<br />
returned, o<strong>the</strong>rwise we return an upward approximation <strong>for</strong> it. For example <strong>the</strong> and_up<br />
operator, which is <strong>the</strong> upward approximation version <strong>of</strong> <strong>the</strong> conjunction operator and_ite,<br />
approximates f ∧ g with f when Too_Many_BDD_Nodes is thrown; its implementation is<br />
shown in Listing 3.1.<br />
3.2 ROBDD algorithms 12