You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1165 lines
42 KiB

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
  2. <!--Converted with LaTeX2HTML 2008 (1.71)
  3. original version by: Nikos Drakos, CBLU, University of Leeds
  4. * revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan
  5. * with significant contributions from:
  6. Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
  7. <HTML>
  8. <HEAD>
  9. <TITLE>Programmer's Manual</TITLE>
  10. <META NAME="description" CONTENT="Programmer's Manual">
  11. <META NAME="keywords" CONTENT="cuddIntro">
  12. <META NAME="resource-type" CONTENT="document">
  13. <META NAME="distribution" CONTENT="global">
  14. <META NAME="Generator" CONTENT="LaTeX2HTML v2008">
  15. <META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
  16. <LINK REL="STYLESHEET" HREF="cuddIntro.css">
  17. <LINK REL="next" HREF="node5.html">
  18. <LINK REL="previous" HREF="node3.html">
  19. <LINK REL="up" HREF="cuddIntro.html">
  20. <LINK REL="next" HREF="node5.html">
  21. </HEAD>
  22. <BODY >
  23. <!--Navigation Panel-->
  24. <A NAME="tex2html154"
  25. HREF="node5.html">
  26. <IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
  27. SRC="icons/next.png"></A>
  28. <A NAME="tex2html150"
  29. HREF="cuddIntro.html">
  30. <IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
  31. SRC="icons/up.png"></A>
  32. <A NAME="tex2html144"
  33. HREF="node3.html">
  34. <IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
  35. SRC="icons/prev.png"></A>
  36. <A NAME="tex2html152"
  37. HREF="node8.html">
  38. <IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index"
  39. SRC="icons/index.png"></A>
  40. <BR>
  41. <B> Next:</B> <A NAME="tex2html155"
  42. HREF="node5.html">The C++ Interface</A>
  43. <B> Up:</B> <A NAME="tex2html151"
  44. HREF="cuddIntro.html">CUDD: CU Decision Diagram</A>
  45. <B> Previous:</B> <A NAME="tex2html145"
  46. HREF="node3.html">User's Manual</A>
  47. &nbsp; <B> <A NAME="tex2html153"
  48. HREF="node8.html">Index</A></B>
  49. <BR>
  50. <BR>
  51. <!--End of Navigation Panel-->
  52. <!--Table of Child-Links-->
  53. <A NAME="CHILD_LINKS"><STRONG>Subsections</STRONG></A>
  54. <UL>
  55. <LI><A NAME="tex2html156"
  56. HREF="node4.html#SECTION00041000000000000000">Compiling and Linking</A>
  57. <LI><A NAME="tex2html157"
  58. HREF="node4.html#SECTION00042000000000000000">Reference Counts</A>
  59. <UL>
  60. <LI><A NAME="tex2html158"
  61. HREF="node4.html#SECTION00042100000000000000">NULL Return Values</A>
  62. <LI><A NAME="tex2html159"
  63. HREF="node4.html#SECTION00042200000000000000"><I>Cudd_RecursiveDeref</I> vs. <I>Cudd_Deref</I></A>
  64. <LI><A NAME="tex2html160"
  65. HREF="node4.html#SECTION00042300000000000000">When Increasing the Reference Count is Unnecessary</A>
  66. <LI><A NAME="tex2html161"
  67. HREF="node4.html#SECTION00042400000000000000">Saturating Increments and Decrements</A>
  68. </UL>
  69. <BR>
  70. <LI><A NAME="tex2html162"
  71. HREF="node4.html#SECTION00043000000000000000">Complement Arcs</A>
  72. <LI><A NAME="tex2html163"
  73. HREF="node4.html#SECTION00044000000000000000">The Cache</A>
  74. <UL>
  75. <LI><A NAME="tex2html164"
  76. HREF="node4.html#SECTION00044100000000000000">Cache Sizing</A>
  77. <LI><A NAME="tex2html165"
  78. HREF="node4.html#SECTION00044200000000000000">Local Caches</A>
  79. </UL>
  80. <BR>
  81. <LI><A NAME="tex2html166"
  82. HREF="node4.html#SECTION00045000000000000000">The Unique Table</A>
  83. <LI><A NAME="tex2html167"
  84. HREF="node4.html#SECTION00046000000000000000">Allowing Asynchronous Reordering</A>
  85. <LI><A NAME="tex2html168"
  86. HREF="node4.html#SECTION00047000000000000000">Debugging</A>
  87. <LI><A NAME="tex2html169"
  88. HREF="node4.html#SECTION00048000000000000000">Gathering and Interpreting Statistics</A>
  89. <UL>
  90. <LI><A NAME="tex2html170"
  91. HREF="node4.html#SECTION00048100000000000000">Non Modifiable Parameters</A>
  92. <LI><A NAME="tex2html171"
  93. HREF="node4.html#SECTION00048200000000000000">Modifiable Parameters</A>
  94. <LI><A NAME="tex2html172"
  95. HREF="node4.html#SECTION00048300000000000000">Extended Statistics and Reporting</A>
  96. </UL>
  97. <BR>
  98. <LI><A NAME="tex2html173"
  99. HREF="node4.html#SECTION00049000000000000000">Guidelines for Documentation</A>
  100. </UL>
  101. <!--End of Table of Child-Links-->
  102. <HR>
  103. <H1><A NAME="SECTION00040000000000000000"></A>
  104. <A NAME="sec:prog"></A>
  105. <BR>
  106. Programmer's Manual
  107. </H1>
  108. <P>
  109. This section provides additional detail on the working of the CUDD
  110. package and on the programming conventions followed in its writing.
  111. The additional detail should help those who want to write procedures
  112. that directly manipulate the CUDD data structures.
  113. <P>
  114. <H2><A NAME="SECTION00041000000000000000"></A>
  115. <A NAME="702"></A><A NAME="sec:compileInt"></A>
  116. <BR>
  117. Compiling and Linking
  118. </H2>
  119. <P>
  120. If you plan to use the CUDD package as a clear box<A NAME="704"></A>
  121. (for instance, you want to write a procedure that traverses a decision
  122. diagram) you need to add
  123. <PRE>
  124. #include "cuddInt.h"
  125. </PRE>
  126. to your source files. In addition, you should link <code>libcudd.a</code> to
  127. your executable. Some platforms require specific compiler and linker
  128. flags. Refer to the <TT>Makefile</TT> in the top level directory of
  129. the distribution.
  130. <P>
  131. <H2><A NAME="SECTION00042000000000000000"></A>
  132. <A NAME="709"></A><A NAME="sec:ref"></A>
  133. <BR>
  134. Reference Counts
  135. </H2>
  136. <P>
  137. Garbage<A NAME="711"></A> collection in the CUDD package is
  138. based on reference counts. Each node stores the sum of the external
  139. references and internal references. An internal BDD or ADD node is
  140. created by a call to <I>cuddUniqueInter</I><A NAME="1294"></A>, an
  141. internal ZDD node is created by a call to
  142. <I>cuddUniqueInterZdd</I><A NAME="1296"></A>, and a
  143. terminal<A NAME="716"></A> node is created by a call to
  144. <I>cuddUniqueConst</I><A NAME="1298"></A>. If the node returned by
  145. these functions is new, its reference count is zero. The function
  146. that calls <I>cuddUniqueInter</I><A NAME="1300"></A>,
  147. <I>cuddUniqueInterZdd</I><A NAME="1302"></A>, or
  148. <I>cuddUniqueConst</I><A NAME="1304"></A> is responsible for
  149. increasing the reference count of the node. This is accomplished by
  150. calling <I>Cudd_Ref</I><A NAME="1306"></A>.
  151. <P>
  152. When a function is no longer needed by an application, the memory used
  153. by its diagram can be recycled by calling
  154. <I>Cudd_RecursiveDeref</I><A NAME="1308"></A> (BDDs and ADDs)
  155. or <I>Cudd_RecursiveDerefZdd</I><A NAME="1310"></A>
  156. (ZDDs). These functions decrease the reference <A NAME="731"></A> count of the node passed to them. If the reference count
  157. becomes 0, then two things happen:
  158. <OL>
  159. <LI>The node is declared ``dead<A NAME="733"></A>;'' this entails
  160. increasing the counters<A NAME="734"></A> of the dead
  161. nodes. (One counter for the subtable<A NAME="735"></A> to which the
  162. node belongs, and one global counter for the
  163. unique<A NAME="736"></A> table to which the node belongs.) The
  164. node itself is not affected.
  165. </LI>
  166. <LI>The function is recursively called on the two children of the
  167. node.
  168. </LI>
  169. </OL>
  170. For instance, if the diagram of a function does not share any nodes
  171. with other diagrams, then calling
  172. <I>Cudd_RecursiveDeref</I><A NAME="1312"></A> or
  173. <I>Cudd_RecursiveDerefZdd</I><A NAME="1314"></A> on its
  174. root will cause all the nodes of the diagram to become dead.
  175. <P>
  176. When the number of dead nodes reaches a given level (dynamically
  177. determined by the package) garbage collection takes place. During
  178. garbage<A NAME="742"></A> collection dead nodes are returned
  179. to the node free list<A NAME="743"></A>.
  180. <P>
  181. When a new node is created, it is important to increase its
  182. reference<A NAME="744"></A> count before one of the two
  183. following events occurs:
  184. <OL>
  185. <LI>A call to <I>cuddUniqueInter</I><A NAME="1316"></A>,
  186. to <I>cuddUniqueInterZdd</I><A NAME="1318"></A>, to
  187. <I>cuddUniqueConst</I><A NAME="1320"></A>, or to a
  188. function that may eventually cause a call to them.
  189. </LI>
  190. <LI>A call to
  191. <I>Cudd_RecursiveDeref</I><A NAME="1322"></A>, to
  192. <I>Cudd_RecursiveDerefZdd</I><A NAME="1324"></A>, or to
  193. a function that may eventually cause a call to them.
  194. </LI>
  195. </OL>
  196. In practice, it is recommended to increase the reference count as soon
  197. as the returned pointer has been tested for not being NULL.
  198. <P>
  199. <H3><A NAME="SECTION00042100000000000000"></A>
  200. <A NAME="sec:null"></A>
  201. <BR>
  202. NULL Return Values
  203. </H3>
  204. <P>
  205. The interface to the memory management functions (e.g., malloc) used
  206. by CUDD intercepts NULL return values and calls a handler. The
  207. default handler exits with an error message. If the application does
  208. not install another handler, therefore, a NULL return value from an
  209. exported function of CUDD signals an internal error.
  210. <P>
  211. If the aplication, however, installs another handler that lets
  212. execution continue, a NULL pointer returned by an exported function
  213. typically indicates that the process has run out of memory.
  214. <I>Cudd_ReadErrorCode</I><A NAME="1326"></A> can be used to
  215. ascertain the nature of the problem.
  216. <P>
  217. An application that tests for the result being NULL can try some
  218. remedial action, if it runs out of memory. For instance, it may free
  219. some memory that is not strictly necessary, or try a slower algorithm
  220. that takes less space. As an example, CUDD overrides the default
  221. handler when trying to enlarge the cache or increase the number of
  222. slots of the unique table. If the allocation fails, the package prints
  223. out a message and continues without resizing the cache.
  224. <P>
  225. <H3><A NAME="SECTION00042200000000000000"></A>
  226. <A NAME="sec:deref"></A>
  227. <BR>
  228. <I>Cudd_RecursiveDeref</I> vs. <I>Cudd_Deref</I>
  229. </H3>
  230. <P>
  231. It is often the case that a recursive procedure has to protect the
  232. result it is going to return, while it disposes of intermediate
  233. results. (See the previous discussion on when to increase reference
  234. counts.) Once the intermediate results have been properly disposed
  235. of, the final result must be returned to its pristine state, in which
  236. the root node may have a reference count of 0. One cannot use
  237. <I>Cudd_RecursiveDeref</I><A NAME="1328"></A> (or
  238. <I>Cudd_RecursiveDerefZdd</I>) for this purpose, because it may
  239. erroneously make some nodes dead. Therefore, the package provides a
  240. different function: <I>Cudd_Deref</I><A NAME="1330"></A>. This
  241. function is not recursive, and does not change the dead node counts.
  242. Its use is almost exclusively the one just described: Decreasing the
  243. reference count of the root of the final result before returning from
  244. a recursive procedure.
  245. <P>
  246. <H3><A NAME="SECTION00042300000000000000"></A>
  247. <A NAME="770"></A><A NAME="sec:noref"></A>
  248. <BR>
  249. When Increasing the Reference Count is Unnecessary
  250. </H3>
  251. <P>
  252. When a copy of a predefined constant<A NAME="772"></A> or of a
  253. simple BDD variable is needed for comparison purposes, then calling
  254. <I>Cudd_Ref</I><A NAME="1332"></A> is not necessary, because these
  255. simple functions are guaranteed to have reference counts greater than
  256. 0 at all times. If no call to <I>Cudd_Ref</I> is made, then no
  257. attempt to free the diagram by calling
  258. <I>Cudd_RecursiveDeref</I><A NAME="1334"></A> or
  259. <I>Cudd_RecursiveDerefZdd</I><A NAME="1336"></A> should be
  260. made.
  261. <P>
  262. <H3><A NAME="SECTION00042400000000000000"></A>
  263. <A NAME="781"></A><A NAME="782"></A><A NAME="sec:satur"></A>
  264. <BR>
  265. Saturating Increments and Decrements
  266. </H3>
  267. <P>
  268. On 32-bit machines, the CUDD package stores the
  269. reference<A NAME="784"></A> counts in unsigned short int's.
  270. For large diagrams, it is possible for some reference counts to exceed
  271. the capacity of an unsigned short int. Therefore, increments and
  272. decrements of reference counts are <I>saturating</I>. This means that
  273. once a reference count has reached the maximum possible value, it is
  274. no longer changed by calls to <I>Cudd_Ref</I>,
  275. <I>Cudd_RecursiveDeref</I><A NAME="1338"></A>,
  276. <I>Cudd_RecursiveDerefZdd</I><A NAME="1340"></A>, or
  277. <I>Cudd_Deref</I><A NAME="1342"></A>. As a consequence, some nodes
  278. that have no references may not be declared dead. This may result in a
  279. small waste of memory, which is normally more than offset by the
  280. reduction in size of the node structure.
  281. <P>
  282. When using 64-bit pointers, there is normally no memory advantage from
  283. using short int's instead of int's in a DdNode. Therefore, increments
  284. and decrements are not saturating in that case. What option is in
  285. effect depends on two macros, SIZEOF_VOID_P<A NAME="793"></A>
  286. and SIZEOF_INT<A NAME="794"></A>, defined in the external
  287. header<A NAME="795"></A> file (<I>cudd.h</I><A NAME="797"></A>). The
  288. increments and decrements of the reference counts are performed using
  289. two macros: <I>cuddSatInc</I><A NAME="1344"></A> and
  290. <I>cuddSatDec</I><A NAME="1346"></A>, whose definitions depend on
  291. SIZEOF_VOID_P<A NAME="802"></A> and
  292. SIZEOF_INT<A NAME="803"></A>.
  293. <P>
  294. <H2><A NAME="SECTION00043000000000000000"></A>
  295. <A NAME="805"></A><A NAME="sec:compl"></A>
  296. <BR>
  297. Complement Arcs
  298. </H2>
  299. <P>
  300. If ADDs are restricted to use only the constants 0 and 1, they behave
  301. like BDDs without complement arcs. It is normally easier to write code
  302. that manipulates 0-1 ADDs, than to write code for BDDs. However,
  303. complementation is trivial with complement arcs, and is not trivial
  304. without. As a consequence, with complement arcs it is possible to
  305. check for more terminal cases and it is possible to apply De Morgan's
  306. laws to reduce problems that are essentially identical to a standard
  307. form. This in turn increases the utilization of the cache<A NAME="807"></A>.
  308. <P>
  309. The complement attribute is stored in the least significant bit of the
  310. ``else'' pointer of each node. An external pointer to a function can
  311. also be complemented. The ``then'' pointer to a node, on the other
  312. hand, is always <I>regular<A NAME="808"></A></I>. It is a mistake to
  313. use a complement<A NAME="809"></A> pointer as it is to address
  314. memory. Instead, it is always necessary to obtain a regular version
  315. of it. This is normally done by calling
  316. <I>Cudd_Regular</I><A NAME="1348"></A>. It is also a mistake to
  317. call <I>cuddUniqueInter</I><A NAME="1350"></A> with a complemented
  318. ``then'' child as argument. The calling procedure must apply De
  319. Morgan's laws by complementing both pointers passed to
  320. <I>cuddUniqueInter</I><A NAME="1352"></A> and then taking the
  321. complement of the result.
  322. <P>
  323. <H2><A NAME="SECTION00044000000000000000"></A>
  324. <A NAME="817"></A><A NAME="sec:cache"></A>
  325. <BR>
  326. The Cache
  327. </H2>
  328. <P>
  329. Each entry of the cache consists of five fields: The operator, three
  330. pointers to operands and a pointer to the result. The operator and the
  331. three pointers to the operands are combined to form three words. The
  332. combination relies on two facts:
  333. <UL>
  334. <LI>Most operations have one or two operands. A few bits are
  335. sufficient to discriminate all three-operands operations.
  336. </LI>
  337. <LI>All nodes are aligned to 16-byte boundaries. (32-byte boundaries
  338. if 64-bit pointers are used.) Hence, there are a few bits available
  339. to distinguish the three-operand operations from te others and to
  340. assign unique codes to them.
  341. </LI>
  342. </UL>
  343. <P>
  344. The cache does not contribute to the reference
  345. <A NAME="821"></A>
  346. counts of the nodes. The fact that the cache contains a
  347. pointer to a node does not imply that the node is alive. Instead, when
  348. garbage<A NAME="822"></A> collection takes place, all entries
  349. of the cache pointing to dead<A NAME="823"></A> nodes are cleared.
  350. <P>
  351. The cache is also cleared (of all entries) when dynamic
  352. reordering<A NAME="824"></A> takes place. In both cases, the entries
  353. removed from the cache are about to become invalid.
  354. <P>
  355. All operands and results in a cache entry must be pointers to
  356. DdNodes<A NAME="825"></A>. If a function produces more than one result,
  357. or uses more than three arguments, there are currently two solutions:
  358. <UL>
  359. <LI>Build a separate, local, cache<A NAME="827"></A>. (Using, for
  360. instance, the <I>st</I> library<A NAME="829"></A>.)
  361. </LI>
  362. <LI>Combine multiple results, or multiple operands, into a single
  363. diagram, by building a ``multiplexing structure'' with reserved
  364. variables.
  365. </LI>
  366. </UL>
  367. Support of the former solution is under development. (See
  368. <TT>cuddLCache.c</TT>..) Support for the latter solution may be
  369. provided in future versions of the package.
  370. <P>
  371. There are three sets of interface<A NAME="832"></A> functions to
  372. the cache. The first set is for functions with three operands:
  373. <I>cuddCacheInsert</I><A NAME="1354"></A> and
  374. <I>cuddCacheLookup</I><A NAME="1356"></A>. The second set is for
  375. functions with two operands:
  376. <I>cuddCacheInsert2</I><A NAME="1358"></A> and
  377. <I>cuddCacheLookup2</I><A NAME="1360"></A>. The second set is for
  378. functions with one operand:
  379. <I>cuddCacheInsert1</I><A NAME="1362"></A> and
  380. <I>cuddCacheLookup1</I><A NAME="1364"></A>. The second set is
  381. slightly faster than the first, and the third set is slightly faster
  382. than the second.
  383. <P>
  384. <H3><A NAME="SECTION00044100000000000000"></A>
  385. <A NAME="846"></A><A NAME="sec:cache-sizing"></A>
  386. <BR>
  387. Cache Sizing
  388. </H3>
  389. <P>
  390. The size of the cache can increase during the execution of an
  391. application. (There is currently no way to decrease the size of the
  392. cache, though it would not be difficult to do it.) When a cache miss
  393. occurs, the package uses the following criteria to decide whether to
  394. resize the cache:
  395. <OL>
  396. <LI>If the cache already exceeds the limit given by the
  397. <TT>maxCache<A NAME="849"></A></TT> field of the manager, no resizing
  398. takes place. The limit is the minimum of two values: a value set at
  399. initialization time and possibly modified by the application, which
  400. constitutes the hard limit beyond which the cache will never grow;
  401. and a number that depends on the current total number of slots in
  402. the unique<A NAME="850"></A> table.
  403. </LI>
  404. <LI>If the cache is not too large already, resizing is decided based
  405. on the hit rate. The policy adopted by the CUDD package is
  406. ``reward-based<A NAME="851"></A>.'' If the cache hit
  407. rate is high, then it is worthwhile to increase the size of the
  408. cache.
  409. </LI>
  410. </OL>
  411. When resizing takes place, the statistical counters <A NAME="853"></A> used to compute the hit rate are reinitialized so as to
  412. prevent immediate resizing. The number of entries is doubled.
  413. <P>
  414. The rationale for the ``reward-based<A NAME="854"></A>''
  415. policy is as follows. In many BDD/ADD applications the hit rate is
  416. not very sensitive to the size of the cache: It is primarily a
  417. function of the problem instance at hand. If a large hit rate is
  418. observed, chances are that by using a large cache, the results of
  419. large problems (those that would take longer to solve) will survive in
  420. the cache without being overwritten long enough to cause a valuable
  421. cache hit. Notice that when a large problem is solved more than once,
  422. so are its recursively generated subproblems. If the hit rate is
  423. low, the probability of large problems being solved more than once is
  424. low.
  425. <P>
  426. The other observation about the cache sizing policy is that there is
  427. little point in keeping a cache which is much larger than the unique
  428. table. Every time the unique table ``fills up,'' garbage collection is
  429. invoked and the cache is cleared of all dead entries. A cache that is
  430. much larger than the unique<A NAME="855"></A> table is therefore
  431. less than fully utilized.
  432. <P>
  433. <H3><A NAME="SECTION00044200000000000000"></A>
  434. <A NAME="857"></A><A NAME="sec:local-caches"></A>
  435. <BR>
  436. Local Caches
  437. </H3>
  438. <P>
  439. Sometimes it may be necessary or convenient to use a local cache. A
  440. local cache can be lossless<A NAME="859"></A> (no results are ever
  441. overwritten), or it may store objects for which
  442. canonical<A NAME="860"></A> representations are not available. One
  443. important fact to keep in mind when using a local cache is that local
  444. caches are not cleared during garbage<A NAME="861"></A>
  445. collection or before reordering. Therefore, it is necessary to
  446. increment the reference<A NAME="862"></A> count of all nodes
  447. pointed by a local cache. (Unless their reference counts are
  448. guaranteed positive in some other way. One such way is by including
  449. all partial results in the global result.) Before disposing of the
  450. local cache, all elements stored in it must be passed to
  451. <I>Cudd_RecursiveDeref</I><A NAME="1366"></A>. As consequence
  452. of the fact that all results in a local cache are referenced, it is
  453. generally convenient to store in the local cache also the result of
  454. trivial problems, which are not usually stored in the global cache.
  455. Otherwise, after a recursive call, it is difficult to tell whether the
  456. result is in the cache, and therefore referenced, or not in the cache,
  457. and therefore not referenced.
  458. <P>
  459. An alternative approach to referencing the results in the local caches
  460. is to install hook functions (see Section&nbsp;<A HREF="node3.html#sec:hooks">3.16</A>) to be
  461. executed before garbage collection.
  462. <P>
  463. <H2><A NAME="SECTION00045000000000000000"></A>
  464. <A NAME="867"></A><A NAME="sec:unique"></A>
  465. <BR>
  466. The Unique Table
  467. </H2>
  468. <P>
  469. A recursive procedure typically splits the operands by expanding with
  470. respect to the topmost variable. Topmost in this context refers to the
  471. variable that is closest to the roots in the current variable order.
  472. The nodes, on the other hand, hold the index, which is invariant with
  473. reordering. Therefore, when splitting, one must use the
  474. permutation<A NAME="869"></A> array maintained by the
  475. package to get the right level. Access to the permutation array is
  476. provided by the macro <I>cuddI</I><A NAME="1368"></A> for BDDs and ADDs,
  477. and by the macro <I>cuddIZ</I><A NAME="1370"></A> for ZDDs.
  478. <P>
  479. The unique table consists of as many hash<A NAME="874"></A> tables as
  480. there are variables in use. These has tables are called <I>unique
  481. subtables</I>. The sizes of the unique subtables are determined by two
  482. criteria:
  483. <OL>
  484. <LI>The collision<A NAME="877"></A> lists should be short
  485. to keep access time down.
  486. </LI>
  487. <LI>There should be enough room for dead<A NAME="878"></A> nodes, to
  488. prevent too frequent garbage<A NAME="879"></A> collections.
  489. </LI>
  490. </OL>
  491. While the first criterion is fairly straightforward to implement, the
  492. second leaves more room to creativity. The CUDD package tries to
  493. figure out whether more dead node should be allowed to increase
  494. performance. (See also Section&nbsp;<A HREF="node3.html#sec:params">3.4</A>.) There are two
  495. reasons for not doing garbage collection too often. The obvious one is
  496. that it is expensive. The second is that dead nodes may be
  497. reclaimed<A NAME="882"></A>, if they are the result of a
  498. successful cache lookup. Hence dead nodes may provide a substantial
  499. speed-up if they are kept around long enough. The usefulness of
  500. keeping many dead nodes around varies from application to application,
  501. and from problem instance to problem instance. As in the sizing of the
  502. cache, the CUDD package adopts a
  503. ``reward-based<A NAME="883"></A>'' policy to
  504. decide how much room should be used for the unique table. If the
  505. number of dead nodes reclaimed is large compared to the number of
  506. nodes directly requested from the memory manager, then the CUDD
  507. package assumes that it will be beneficial to allow more room for the
  508. subtables, thereby reducing the frequency of garbage collection. The
  509. package does so by switching between two modes of operation:
  510. <OL>
  511. <LI>Fast growth<A NAME="885"></A>: In this mode, the
  512. ratio of dead nodes to total nodes required for garbage collection
  513. is higher than in the slow growth mode to favor resizing
  514. of the subtables.
  515. </LI>
  516. <LI>Slow growth<A NAME="886"></A>: In this
  517. mode keeping many dead nodes around is not as important as
  518. keeping memory requirements low.
  519. </LI>
  520. </OL>
  521. Switching from one mode to the other is based on the following
  522. criteria:
  523. <OL>
  524. <LI>If the unique table is already large, only slow growth is
  525. possible.
  526. </LI>
  527. <LI>If the table is small and many dead nodes are being reclaimed,
  528. then fast growth is selected.
  529. </LI>
  530. </OL>
  531. This policy is especially effective when the diagrams being
  532. manipulated have lots of recombination. Notice the interplay of the
  533. cache sizing and unique sizing: Fast growth normally occurs when the
  534. cache hit rate is large. The cache and the unique table then grow in
  535. concert, preserving a healthy balance between their sizes.
  536. <P>
  537. <H2><A NAME="SECTION00046000000000000000"></A>
  538. <A NAME="891"></A><A NAME="sec:async"></A>
  539. <BR>
  540. Allowing Asynchronous Reordering
  541. </H2>
  542. <P>
  543. Asynchronous reordering is the reordering that is triggered
  544. automatically by the increase of the number of nodes. Asynchronous
  545. reordering takes place when a new internal node must be created, and
  546. the number of nodes has reached a given
  547. threshold<A NAME="893"></A>. (The threshold is adjusted by
  548. the package every time reordering takes place.)
  549. <P>
  550. Those procedures that do not create new nodes (e.g., procedures that
  551. count the number of nodes or minterms<A NAME="894"></A>) need
  552. not worry about asynchronous reordering: No special precaution is
  553. necessary in writing them.
  554. <P>
  555. Procedures that only manipulate decision diagrams through the exported
  556. functions of the CUDD package also need not concern themselves with
  557. asynchronous reordering. (See Section&nbsp;<A HREF="node3.html#sec:nodes">3.2.1</A> for the
  558. exceptions.)
  559. <P>
  560. The remaining class of procedures is composed of functions that visit
  561. the diagrams and may create new nodes. All such procedures in the CUDD
  562. package are written so that they can be interrupted by dynamic
  563. reordering. The general approach followed goes under the name of
  564. ``abort and retry<A NAME="896"></A>.'' As the name
  565. implies, a computation that is interrupted by dynamic reordering is
  566. aborted and tried again.
  567. <P>
  568. A recursive procedure that can be interrupted by dynamic reordering
  569. (an interruptible<A NAME="897"></A> procedure
  570. from now on) is composed of two functions. One is responsible for the
  571. real computation. The other is a simple
  572. wrapper<A NAME="898"></A>, which tests whether
  573. reordering occurred and restarts the computation if it did.
  574. <P>
  575. Asynchronous reordering of BDDs and ADDs can only be triggered inside
  576. <I>cuddUniqueInter</I><A NAME="1372"></A>, when a new node is about
  577. to be created. Likewise, asynchronous reordering of ZDDs can only be
  578. triggered inside <I>cuddUniqueInterZdd</I><A NAME="1374"></A>.
  579. When reordering is triggered, three things happen:
  580. <OL>
  581. <LI><I>cuddUniqueInter</I><A NAME="1376"></A> returns a NULL
  582. value;
  583. </LI>
  584. <LI>The flag <I>reordered</I> of the manager is set to 1. (0 means
  585. no reordering, while 2 indicates an error occurred during
  586. reordering.)
  587. </LI>
  588. <LI>The counter <I>reorderings</I> of the manager is incremented.
  589. The counter is initialized to 0 when the manager is started and can
  590. be accessed by calling
  591. <I>Cudd_ReadReorderings</I><A NAME="1378"></A>. By taking
  592. two readings of the counter, an application can determine if
  593. variable reordering has taken place between the first and the second
  594. reading. The package itself, however, does not make use of the
  595. counter: It is mentioned here for completeness.
  596. </LI>
  597. </OL>
  598. <P>
  599. The recursive procedure that receives a NULL value from
  600. <I>cuddUniqueInter</I><A NAME="1380"></A> must free all
  601. intermediate results that it may have computed before, and return NULL
  602. in its turn.
  603. <P>
  604. The wrapper<A NAME="913"></A> function does not
  605. decide whether reordering occurred based on the NULL return value,
  606. because the NULL value may be the result of lack of memory. Instead,
  607. it checks the <I>reordered</I> flag.
  608. <P>
  609. When a recursive procedure calls another recursive procedure that may
  610. cause reordering, it should bypass the wrapper and call the recursive
  611. procedure directly. Otherwise, the calling procedure will not know
  612. whether reordering occurred, and will not be able to restart. This is
  613. the main reason why most recursive procedures are internal, rather
  614. than static. (The wrappers, on the other hand, are mostly exported.)
  615. <P>
  616. <H2><A NAME="SECTION00047000000000000000"></A>
  617. <A NAME="916"></A><A NAME="sec:debug"></A>
  618. <BR>
  619. Debugging
  620. </H2>
  621. <P>
  622. By defining the symbol DD_DEBUG<A NAME="918"></A> during compilation,
  623. numerous checks are added to the code. In addition, the procedures
  624. <I>Cudd_DebugCheck</I><A NAME="1382"></A>,
  625. <I>Cudd_CheckKeys</I><A NAME="1384"></A>, and
  626. <I>cuddHeapProfile</I><A NAME="1386"></A> can be called at any
  627. point to verify the consistency of the data structure.
  628. (<I>cuddHeapProfile</I> is an internal procedure. It is declared in
  629. <I>cuddInt.h</I><A NAME="927"></A>.) Procedures
  630. <I>Cudd_DebugCheck</I> and <I>Cudd_CheckKeys</I> are especially
  631. useful when CUDD reports that during garbage collection the number of
  632. nodes actually deleted from the unique table is different from the
  633. count of dead nodes kept by the manager. The error causing the
  634. discrepancy may have occurred much earlier than it is discovered. A
  635. few strategicaly placed calls to the debugging procedures can
  636. considerably narrow down the search for the source of the problem.
  637. (For instance, a call to <I>Cudd_RecursiveDeref</I> where one to
  638. <I>Cudd_Deref</I> was required may be identified in this way.)
  639. <P>
  640. One of the most common problems encountered in debugging code based on
  641. the CUDD package is a missing call to
  642. <I>Cudd_RecursiveDeref</I><A NAME="1388"></A>. To help
  643. identify this type of problems, the package provides a function called
  644. <I>Cudd_CheckZeroRef</I><A NAME="1390"></A>. This function
  645. should be called immediately before shutting down the manager.
  646. <I>Cudd_CheckZeroRef</I> checks that the only nodes left with
  647. non-zero reference<A NAME="937"></A> counts are the
  648. predefined constants, the BDD projection<A NAME="938"></A>
  649. functions, and nodes whose reference counts are
  650. saturated<A NAME="939"></A>.
  651. <P>
  652. For this function to be effective the application must explicitly
  653. dispose of all diagrams to which it has pointers before calling it.
  654. <P>
  655. <H2><A NAME="SECTION00048000000000000000"></A>
  656. <A NAME="941"></A><A NAME="sec:stats"></A>
  657. <BR>
  658. Gathering and Interpreting Statistics
  659. </H2>
  660. <P>
  661. Function <I>Cudd_PrintInfo</I><A NAME="1392"></A> can be called to
  662. print out the values of parameters and statistics for a manager. The
  663. output of <I>Cudd_PrintInfo</I> is divided in two sections. The
  664. first reports the values of parameters that are under the application
  665. control. The second reports the values of statistical counters and
  666. other non-modifiable parameters. A quick guide to the interpretation
  667. of all these quantities follows. For ease of exposition, we reverse
  668. the order and describe the non-modifiable parameters first. We'll use
  669. a sample run as example. There is nothing special about this run.
  670. <P>
  671. <H3><A NAME="SECTION00048100000000000000"></A>
  672. <A NAME="sec:nonModPar"></A>
  673. <BR>
  674. Non Modifiable Parameters
  675. </H3>
  676. <P>
  677. The list of non-modifiable parameters starts with:
  678. <PRE>
  679. **** CUDD non-modifiable parameters ****
  680. Memory in use: 32544220
  681. </PRE>
  682. This is the memory used by CUDD for three things mainly: Unique table
  683. (including all DD nodes in use), node free list, and computed table.
  684. This number almost never decreases in the lifetime of a CUDD manager,
  685. because CUDD does not release memory when it frees nodes. Rather, it
  686. puts the nodes on its own free list. This number is in bytes. It does
  687. not represent the peak memory occupation, because it does not include
  688. the size of data structures created temporarily by some functions (e.g.,
  689. local look-up tables).
  690. <P>
  691. <PRE>
  692. Peak number of nodes: 837018
  693. </PRE>
  694. This number is the number of nodes that the manager has allocated.
  695. This is not the largest size of the BDDs, because the manager will
  696. normally have some dead nodes and some nodes on the free list.
  697. <P>
  698. <PRE>
  699. Peak number of live nodes: 836894
  700. </PRE>
  701. This is the largest number of live nodes that the manager has held
  702. since its creation.
  703. <P>
  704. <PRE>
  705. Number of BDD variables: 198
  706. Number of ZDD variables: 0
  707. </PRE>
  708. These numbers tell us this run was not using ZDDs.
  709. <P>
  710. <PRE>
  711. Number of cache entries: 1048576
  712. </PRE>
  713. Current number of slots of the computed table. If one has a
  714. performance problem, this is one of the numbers to look at. The cache
  715. size is always a power of 2.
  716. <P>
  717. <PRE>
  718. Number of cache look-ups: 2996536
  719. Number of cache hits: 1187087
  720. </PRE>
  721. These numbers give an indication of the hit rate in the computed
  722. table. It is not unlikely for model checking runs to get
  723. hit rates even higher than this one (39.62%).
  724. <P>
  725. <PRE>
  726. Number of cache insertions: 1809473
  727. Number of cache collisions: 961208
  728. Number of cache deletions: 0
  729. </PRE>
  730. A collision<A NAME="962"></A> occurs when a cache entry is
  731. overwritten. A deletion<A NAME="963"></A>
  732. occurs when a cache entry is invalidated (e.g., during garbage
  733. collection). If the number of deletions is high compared to the
  734. number of collisions, it means that garbage collection occurs too
  735. often. In this case there were no garbage collections; hence, no
  736. deletions.
  737. <P>
  738. <PRE>
  739. Cache used slots = 80.90% (expected 82.19%)
  740. </PRE>
  741. Percentage of cache slots that contain a valid entry. If this
  742. number is small, it may signal one of three conditions:
  743. <OL>
  744. <LI>The cache may have been recently resized and it is still filling
  745. up.
  746. </LI>
  747. <LI>The cache is too large for the BDDs. This should not happen if
  748. the size of the cache is determined by CUDD.
  749. </LI>
  750. <LI>The hash function is not working properly. This is accompanied
  751. by a degradation in performance. Conversely, a degradation in
  752. performance may be due to bad hash function behavior.
  753. </LI>
  754. </OL>
  755. The expected value is computed assuming a uniformly random
  756. distribution of the accesses. If the difference between the measured
  757. value and the expected value is large (unlike this case), the cache is
  758. not working properly.
  759. <P>
  760. <PRE>
  761. Soft limit for cache size: 1318912
  762. </PRE>
  763. This number says how large the cache can grow. This limit is based on
  764. the size of the unique table. CUDD uses a reward-based policy for
  765. growing the cache. (See Section&nbsp;<A HREF="#sec:cache-sizing">4.4.1</A>.) The default
  766. hit rate for resizing is 30% and the value in effect is reported
  767. among the modifiable parameters.
  768. <P>
  769. <PRE>
  770. Number of buckets in unique table: 329728
  771. </PRE>
  772. This number is exactly one quarter of the one above. This is indeed
  773. how the soft limit is determined currently, unless the computed table
  774. hits the specified hard limit. (See below.)
  775. <P>
  776. <PRE>
  777. Used buckets in unique table: 87.96% (expected 87.93%)
  778. </PRE>
  779. Percentage of unique table buckets that contain at least one
  780. node. Remarks analogous to those made about the used cache slots apply.
  781. <P>
  782. <PRE>
  783. Number of BDD and ADD nodes: 836894
  784. Number of ZDD nodes: 0
  785. </PRE>
  786. How many nodes are currently in the unique table, either alive or dead.
  787. <P>
  788. <PRE>
  789. Number of dead BDD and ADD nodes: 0
  790. Number of dead ZDD nodes: 0
  791. </PRE>
  792. Subtract these numbers from those above to get the number of live
  793. nodes. In this case there are no dead nodes because the application
  794. uses delayed dereferencing
  795. <I>Cudd_DelayedDerefBdd</I><A NAME="1394"></A>.
  796. <P>
  797. <PRE>
  798. Total number of nodes allocated: 836894
  799. </PRE>
  800. This is the total number of nodes that were requested and obtained
  801. from the free list. It never decreases, and is not an indication of
  802. memory occupation after the first garbage collection. Rather, it is a
  803. measure of the package activity.
  804. <P>
  805. <PRE>
  806. Total number of nodes reclaimed: 0
  807. </PRE>
  808. These are the nodes that were resuscitated from the dead. If they are
  809. many more than the allocated nodes, and the total
  810. number of slots is low relative to the number of nodes, then one may
  811. want to increase the limit for fast unique table growth. In this case,
  812. the number is 0 because of delayed dereferencing.
  813. <P>
  814. <PRE>
  815. Garbage collections so far: 0
  816. Time for garbage collections: 0.00 sec
  817. Reorderings so far: 0
  818. Time for reordering: 0.00 sec
  819. </PRE>
  820. There is a GC for each reordering. Hence the first count will always be
  821. at least as large as the second.
  822. <P>
  823. <PRE>
  824. Node swaps in reordering: 0
  825. </PRE>
  826. This is the number of elementary reordering steps. Each step consists
  827. of the re-expression of one node while swapping two adjacent
  828. variables. This number is a good measure of the amount of work done in
  829. reordering.
  830. <P>
  831. <H3><A NAME="SECTION00048200000000000000"></A>
  832. <A NAME="sec:modPar"></A>
  833. <BR>
  834. Modifiable Parameters
  835. </H3>
  836. <P>
  837. Let us now consider the modifiable parameters, that is, those settings on
  838. which the application or the user has control.
  839. <P>
  840. <PRE>
  841. **** CUDD modifiable parameters ****
  842. Hard limit for cache size: 8388608
  843. </PRE>
  844. This number counts entries. Each entry is 16 bytes if CUDD is compiled
  845. to use 32-bit pointers. Two important observations are in order:
  846. <OL>
  847. <LI>If the datasize limit is set, CUDD will use it to determine this
  848. number automatically. On a Unix system, one can type ``limit'' or
  849. ``ulimit'' to verify if this value is set. If the datasize limit is
  850. not set, CUDD uses a default which is rather small. If you have
  851. enough memory (say 64MB or more) you should seriously consider
  852. <I>not</I> using the default. So, either set the datasize limit, or
  853. override the default with
  854. <I>Cudd_SetMaxCacheHard</I><A NAME="1396"></A>.
  855. </LI>
  856. <LI>If a process seems to be going nowhere, a small value for
  857. this parameter may be the culprit. One cannot overemphasize the
  858. importance of the computed table in BDD algorithms.
  859. </LI>
  860. </OL>
  861. In this case the limit was automatically set for a target maximum
  862. memory occupation of 104 MB.
  863. <P>
  864. <PRE>
  865. Cache hit threshold for resizing: 15%
  866. </PRE>
  867. This number can be changed if one suspects performance is hindered by
  868. the small size of the cache, and the cache is not growing towards the
  869. soft limit sufficiently fast. In such a case one can change the
  870. default 30% to 15% (as in this case) or even 1%.
  871. <P>
  872. <PRE>
  873. Garbage collection enabled: yes
  874. </PRE>
  875. One can disable it, but there are few good reasons for doing
  876. so. It is normally preferable to raise the limit for fast unique table
  877. growth. (See below.)
  878. <P>
  879. <PRE>
  880. Limit for fast unique table growth: 1363148
  881. </PRE>
  882. See Section&nbsp;<A HREF="#sec:unique">4.5</A> and the comments above about reclaimed
  883. nodes and hard limit for the cache size. This value was chosen
  884. automatically by CUDD for a datasize limit of 1 GB.
  885. <P>
  886. <PRE>
  887. Maximum number of variables sifted per reordering: 1000
  888. Maximum number of variable swaps per reordering: 2000000
  889. Maximum growth while sifting a variable: 1.2
  890. </PRE>
  891. Lowering these numbers will cause reordering to be less accurate and
  892. faster. Results are somewhat unpredictable, because larger BDDs after one
  893. reordering do not necessarily mean the process will go faster or slower.
  894. <P>
  895. <PRE>
  896. Dynamic reordering of BDDs enabled: yes
  897. Default BDD reordering method: 4
  898. Dynamic reordering of ZDDs enabled: no
  899. Default ZDD reordering method: 4
  900. </PRE>
  901. These lines tell whether automatic reordering can take place and what
  902. method would be used. The mapping from numbers to methods is in
  903. <TT>cudd.h</TT>. One may want to try different BDD reordering
  904. methods. If variable groups are used, however, one should not expect
  905. to see big differences, because CUDD uses the reported method only to
  906. reorder each leaf variable group (typically corresponding present and
  907. next state variables). For the relative order of the groups, it
  908. always uses the same algorithm, which is effectively sifting.
  909. <P>
  910. As for enabling dynamic reordering or not, a sensible recommendation is the
  911. following: Unless the circuit is rather small or one has a pretty good
  912. idea of what the order should be, reordering should be enabled.
  913. <P>
  914. <PRE>
  915. Realignment of ZDDs to BDDs enabled: no
  916. Realignment of BDDs to ZDDs enabled: no
  917. Dead nodes counted in triggering reordering: no
  918. Group checking criterion: 7
  919. Recombination threshold: 0
  920. Symmetry violation threshold: 0
  921. Arc violation threshold: 0
  922. GA population size: 0
  923. Number of crossovers for GA: 0
  924. </PRE>
  925. Parameters for reordering. See the documentation of the functions used
  926. to control these parameters for the details.
  927. <P>
  928. <PRE>
  929. Next reordering threshold: 100000
  930. </PRE>
  931. When the number of nodes crosses this threshold, reordering will be
  932. triggered. (If enabled; in this case it is not.) This parameter is
  933. updated by the package whenever reordering takes place. The
  934. application can change it, for instance at start-up. Another
  935. possibility is to use a hook function (see Section&nbsp;<A HREF="node3.html#sec:hooks">3.16</A>) to
  936. override the default updating policy.
  937. <P>
  938. <H3><A NAME="SECTION00048300000000000000"></A>
  939. <A NAME="sec:extendedStats"></A>
  940. <BR>
  941. Extended Statistics and Reporting
  942. </H3>
  943. <P>
  944. The following symbols can be defined during compilation to increase
  945. the amount of statistics gathered and the number of messages produced
  946. by the package:
  947. <UL>
  948. <LI>DD_STATS<A NAME="1018"></A>;
  949. </LI>
  950. <LI>DD_CACHE_PROFILE<A NAME="1019"></A>;
  951. </LI>
  952. <LI>DD_UNIQUE_PROFILE<A NAME="1020"></A>.
  953. </LI>
  954. <LI>DD_VERBOSE<A NAME="1021"></A>;
  955. </LI>
  956. </UL>
  957. Defining DD_CACHE_PROFILE causes each entry of the cache to include
  958. an access counter, which is used to compute simple statistics on the
  959. distribution of the keys.
  960. <P>
  961. <H2><A NAME="SECTION00049000000000000000"></A>
  962. <A NAME="sec:doc"></A><A NAME="1025"></A>
  963. <BR>
  964. Guidelines for Documentation
  965. </H2>
  966. <P>
  967. The documentation of the CUDD functions is extracted automatically
  968. from the sources by Stephen Edwards's extdoc. (The Ext system is
  969. available via anonymous FTP<A NAME="1026"></A> from
  970. <A NAME="tex2html11"
  971. HREF="ftp://ic.eecs.berkeley.edu"><TT>ic.eecs.berkeley.edu</TT></A>.)
  972. The following guidelines are followed in CUDD to insure consistent and
  973. effective use of automatic extraction. It is recommended that
  974. extensions to CUDD follow the same documentation guidelines.
  975. <UL>
  976. <LI>The documentation of an exported procedure should be sufficient
  977. to allow one to use it without reading the code. It is not necessary
  978. to explain how the procedure works; only what it does.
  979. </LI>
  980. <LI>The <I>SeeAlso</I><A NAME="1096"></A>
  981. fields should be space-separated lists of function names. The
  982. <I>SeeAlso</I> field of an exported procedure should only reference
  983. other exported procedures. The <I>SeeAlso</I> field of an internal
  984. procedure may reference other internal procedures as well as
  985. exported procedures, but no static procedures.
  986. </LI>
  987. <LI>The return values are detailed in the
  988. <I>Description</I><A NAME="1097"></A>
  989. field, not in the
  990. <I>Synopsis</I><A NAME="1098"></A> field.
  991. </LI>
  992. <LI>The parameters are documented alongside their declarations.
  993. Further comments may appear in the <I>Description</I> field.
  994. </LI>
  995. <LI>If the <I>Description</I> field is non-empty--which is the
  996. normal case for an exported procedure--then the synopsis is
  997. repeated--possibly slightly changed--at the beginning of the
  998. <I>Description</I> field. This is so because extdoc will not put the
  999. synopsis in the same HTML file<A NAME="1041"></A> as
  1000. the description.
  1001. </LI>
  1002. <LI>The <I>Synopsis</I> field should be about one line long.
  1003. </LI>
  1004. </UL>
  1005. <P>
  1006. <HR>
  1007. <!--Navigation Panel-->
  1008. <A NAME="tex2html154"
  1009. HREF="node5.html">
  1010. <IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
  1011. SRC="icons/next.png"></A>
  1012. <A NAME="tex2html150"
  1013. HREF="cuddIntro.html">
  1014. <IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
  1015. SRC="icons/up.png"></A>
  1016. <A NAME="tex2html144"
  1017. HREF="node3.html">
  1018. <IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
  1019. SRC="icons/prev.png"></A>
  1020. <A NAME="tex2html152"
  1021. HREF="node8.html">
  1022. <IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index"
  1023. SRC="icons/index.png"></A>
  1024. <BR>
  1025. <B> Next:</B> <A NAME="tex2html155"
  1026. HREF="node5.html">The C++ Interface</A>
  1027. <B> Up:</B> <A NAME="tex2html151"
  1028. HREF="cuddIntro.html">CUDD: CU Decision Diagram</A>
  1029. <B> Previous:</B> <A NAME="tex2html145"
  1030. HREF="node3.html">User's Manual</A>
  1031. &nbsp; <B> <A NAME="tex2html153"
  1032. HREF="node8.html">Index</A></B>
  1033. <!--End of Navigation Panel-->
  1034. <ADDRESS>
  1035. Fabio Somenzi
  1036. 2012-02-04
  1037. </ADDRESS>
  1038. </BODY>
  1039. </HTML>