emergency commit
authorUtz-Uwe Haus <haus@uuhaus.de>
Fri, 23 Oct 2009 21:06:41 +0000 (23 23:06 +0200)
committerUtz-Uwe Haus <haus@uuhaus.de>
Fri, 23 Oct 2009 21:06:41 +0000 (23 23:06 +0200)
333 files changed:
.gitignore [new file with mode: 0644]
asdf-component-shared-unix-library.asd [new file with mode: 0644]
cudd-cffi.i [new file with mode: 0644]
cudd.asd [new file with mode: 0644]
cuddsat.lisp [new file with mode: 0644]
distr/LICENSE [new file with mode: 0644]
distr/Makefile [new file with mode: 0644]
distr/README [new file with mode: 0644]
distr/RELEASE.NOTES [new file with mode: 0644]
distr/cudd/Makefile [new file with mode: 0644]
distr/cudd/cudd.h [new file with mode: 0644]
distr/cudd/cuddAPI.c [new file with mode: 0644]
distr/cudd/cuddAddAbs.c [new file with mode: 0644]
distr/cudd/cuddAddApply.c [new file with mode: 0644]
distr/cudd/cuddAddFind.c [new file with mode: 0644]
distr/cudd/cuddAddInv.c [new file with mode: 0644]
distr/cudd/cuddAddIte.c [new file with mode: 0644]
distr/cudd/cuddAddNeg.c [new file with mode: 0644]
distr/cudd/cuddAddWalsh.c [new file with mode: 0644]
distr/cudd/cuddAndAbs.c [new file with mode: 0644]
distr/cudd/cuddAnneal.c [new file with mode: 0644]
distr/cudd/cuddApa.c [new file with mode: 0644]
distr/cudd/cuddApprox.c [new file with mode: 0644]
distr/cudd/cuddBddAbs.c [new file with mode: 0644]
distr/cudd/cuddBddCorr.c [new file with mode: 0644]
distr/cudd/cuddBddIte.c [new file with mode: 0644]
distr/cudd/cuddBridge.c [new file with mode: 0644]
distr/cudd/cuddCache.c [new file with mode: 0644]
distr/cudd/cuddCheck.c [new file with mode: 0644]
distr/cudd/cuddClip.c [new file with mode: 0644]
distr/cudd/cuddCof.c [new file with mode: 0644]
distr/cudd/cuddCompose.c [new file with mode: 0644]
distr/cudd/cuddDecomp.c [new file with mode: 0644]
distr/cudd/cuddEssent.c [new file with mode: 0644]
distr/cudd/cuddExact.c [new file with mode: 0644]
distr/cudd/cuddExport.c [new file with mode: 0644]
distr/cudd/cuddGenCof.c [new file with mode: 0644]
distr/cudd/cuddGenetic.c [new file with mode: 0644]
distr/cudd/cuddGroup.c [new file with mode: 0644]
distr/cudd/cuddHarwell.c [new file with mode: 0644]
distr/cudd/cuddInit.c [new file with mode: 0644]
distr/cudd/cuddInt.h [new file with mode: 0644]
distr/cudd/cuddInteract.c [new file with mode: 0644]
distr/cudd/cuddLCache.c [new file with mode: 0644]
distr/cudd/cuddLevelQ.c [new file with mode: 0644]
distr/cudd/cuddLinear.c [new file with mode: 0644]
distr/cudd/cuddLiteral.c [new file with mode: 0644]
distr/cudd/cuddMatMult.c [new file with mode: 0644]
distr/cudd/cuddPriority.c [new file with mode: 0644]
distr/cudd/cuddRead.c [new file with mode: 0644]
distr/cudd/cuddRef.c [new file with mode: 0644]
distr/cudd/cuddReorder.c [new file with mode: 0644]
distr/cudd/cuddSat.c [new file with mode: 0644]
distr/cudd/cuddSign.c [new file with mode: 0644]
distr/cudd/cuddSolve.c [new file with mode: 0644]
distr/cudd/cuddSplit.c [new file with mode: 0644]
distr/cudd/cuddSubsetHB.c [new file with mode: 0644]
distr/cudd/cuddSubsetSP.c [new file with mode: 0644]
distr/cudd/cuddSymmetry.c [new file with mode: 0644]
distr/cudd/cuddTable.c [new file with mode: 0644]
distr/cudd/cuddUtil.c [new file with mode: 0644]
distr/cudd/cuddWindow.c [new file with mode: 0644]
distr/cudd/cuddZddCount.c [new file with mode: 0644]
distr/cudd/cuddZddFuncs.c [new file with mode: 0644]
distr/cudd/cuddZddGroup.c [new file with mode: 0644]
distr/cudd/cuddZddIsop.c [new file with mode: 0644]
distr/cudd/cuddZddLin.c [new file with mode: 0644]
distr/cudd/cuddZddMisc.c [new file with mode: 0644]
distr/cudd/cuddZddPort.c [new file with mode: 0644]
distr/cudd/cuddZddReord.c [new file with mode: 0644]
distr/cudd/cuddZddSetop.c [new file with mode: 0644]
distr/cudd/cuddZddSymm.c [new file with mode: 0644]
distr/cudd/cuddZddUtil.c [new file with mode: 0644]
distr/cudd/doc/cudd.doc [new file with mode: 0644]
distr/cudd/doc/cudd.ps [new file with mode: 0644]
distr/cudd/doc/cuddAllAbs.html [new file with mode: 0644]
distr/cudd/doc/cuddAllByFile.html [new file with mode: 0644]
distr/cudd/doc/cuddAllByFunc.html [new file with mode: 0644]
distr/cudd/doc/cuddAllDet.html [new file with mode: 0644]
distr/cudd/doc/cuddAllFile.html [new file with mode: 0644]
distr/cudd/doc/cuddDesc.html [new file with mode: 0644]
distr/cudd/doc/cuddExt.html [new file with mode: 0644]
distr/cudd/doc/cuddExtAbs.html [new file with mode: 0644]
distr/cudd/doc/cuddExtDet.html [new file with mode: 0644]
distr/cudd/doc/cuddIntro.css [new file with mode: 0644]
distr/cudd/doc/cuddIntro.html [new file with mode: 0644]
distr/cudd/doc/cuddTitle.html [new file with mode: 0644]
distr/cudd/doc/footnode.html [new file with mode: 0644]
distr/cudd/doc/icons/blueball.png [new file with mode: 0644]
distr/cudd/doc/icons/ch_beg_r.png [new file with mode: 0644]
distr/cudd/doc/icons/ch_begin.png [new file with mode: 0644]
distr/cudd/doc/icons/ch_del_r.png [new file with mode: 0644]
distr/cudd/doc/icons/ch_delet.png [new file with mode: 0644]
distr/cudd/doc/icons/ch_end.png [new file with mode: 0644]
distr/cudd/doc/icons/ch_end_r.png [new file with mode: 0644]
distr/cudd/doc/icons/contents.png [new file with mode: 0644]
distr/cudd/doc/icons/crossref.png [new file with mode: 0644]
distr/cudd/doc/icons/footnote.png [new file with mode: 0644]
distr/cudd/doc/icons/greenball.png [new file with mode: 0644]
distr/cudd/doc/icons/image.png [new file with mode: 0644]
distr/cudd/doc/icons/index.png [new file with mode: 0644]
distr/cudd/doc/icons/next.png [new file with mode: 0644]
distr/cudd/doc/icons/next_g.png [new file with mode: 0644]
distr/cudd/doc/icons/nx_grp.png [new file with mode: 0644]
distr/cudd/doc/icons/nx_grp_g.png [new file with mode: 0644]
distr/cudd/doc/icons/orangeball.png [new file with mode: 0644]
distr/cudd/doc/icons/pinkball.png [new file with mode: 0644]
distr/cudd/doc/icons/prev.png [new file with mode: 0644]
distr/cudd/doc/icons/prev_g.png [new file with mode: 0644]
distr/cudd/doc/icons/purpleball.png [new file with mode: 0644]
distr/cudd/doc/icons/pv_grp.png [new file with mode: 0644]
distr/cudd/doc/icons/pv_grp_g.png [new file with mode: 0644]
distr/cudd/doc/icons/redball.png [new file with mode: 0644]
distr/cudd/doc/icons/up.png [new file with mode: 0644]
distr/cudd/doc/icons/up_g.png [new file with mode: 0644]
distr/cudd/doc/icons/whiteball.png [new file with mode: 0644]
distr/cudd/doc/icons/yellowball.png [new file with mode: 0644]
distr/cudd/doc/img1.png [new file with mode: 0644]
distr/cudd/doc/img10.png [new file with mode: 0644]
distr/cudd/doc/img11.png [new file with mode: 0644]
distr/cudd/doc/img12.png [new file with mode: 0644]
distr/cudd/doc/img13.png [new file with mode: 0644]
distr/cudd/doc/img14.png [new file with mode: 0644]
distr/cudd/doc/img15.png [new file with mode: 0644]
distr/cudd/doc/img16.png [new file with mode: 0644]
distr/cudd/doc/img17.png [new file with mode: 0644]
distr/cudd/doc/img18.png [new file with mode: 0644]
distr/cudd/doc/img19.png [new file with mode: 0644]
distr/cudd/doc/img2.png [new file with mode: 0644]
distr/cudd/doc/img20.png [new file with mode: 0644]
distr/cudd/doc/img21.png [new file with mode: 0644]
distr/cudd/doc/img22.png [new file with mode: 0644]
distr/cudd/doc/img3.png [new file with mode: 0644]
distr/cudd/doc/img4.png [new file with mode: 0644]
distr/cudd/doc/img5.png [new file with mode: 0644]
distr/cudd/doc/img6.png [new file with mode: 0644]
distr/cudd/doc/img7.png [new file with mode: 0644]
distr/cudd/doc/img8.png [new file with mode: 0644]
distr/cudd/doc/img9.png [new file with mode: 0644]
distr/cudd/doc/index.html [new file with mode: 0644]
distr/cudd/doc/node1.html [new file with mode: 0644]
distr/cudd/doc/node2.html [new file with mode: 0644]
distr/cudd/doc/node3.html [new file with mode: 0644]
distr/cudd/doc/node4.html [new file with mode: 0644]
distr/cudd/doc/node5.html [new file with mode: 0644]
distr/cudd/doc/node6.html [new file with mode: 0644]
distr/cudd/doc/node7.html [new file with mode: 0644]
distr/cudd/doc/node8.html [new file with mode: 0644]
distr/cudd/r7x8.1.mat [new file with mode: 0644]
distr/cudd/r7x8.1.out [new file with mode: 0644]
distr/cudd/testcudd.c [new file with mode: 0644]
distr/dddmp/Makefile [new file with mode: 0644]
distr/dddmp/README.dddmp [new file with mode: 0644]
distr/dddmp/README.testdddmp [new file with mode: 0644]
distr/dddmp/RELEASE_NOTES [new file with mode: 0644]
distr/dddmp/dddmp.h [new file with mode: 0644]
distr/dddmp/dddmpBinary.c [new file with mode: 0644]
distr/dddmp/dddmpConvert.c [new file with mode: 0644]
distr/dddmp/dddmpDbg.c [new file with mode: 0644]
distr/dddmp/dddmpDdNodeBdd.c [new file with mode: 0644]
distr/dddmp/dddmpDdNodeCnf.c [new file with mode: 0644]
distr/dddmp/dddmpInt.h [new file with mode: 0644]
distr/dddmp/dddmpLoad.c [new file with mode: 0644]
distr/dddmp/dddmpLoadCnf.c [new file with mode: 0644]
distr/dddmp/dddmpNodeAdd.c [new file with mode: 0644]
distr/dddmp/dddmpNodeBdd.c [new file with mode: 0644]
distr/dddmp/dddmpNodeCnf.c [new file with mode: 0644]
distr/dddmp/dddmpStoreAdd.c [new file with mode: 0644]
distr/dddmp/dddmpStoreBdd.c [new file with mode: 0644]
distr/dddmp/dddmpStoreCnf.c [new file with mode: 0644]
distr/dddmp/dddmpStoreMisc.c [new file with mode: 0644]
distr/dddmp/dddmpUtil.c [new file with mode: 0644]
distr/dddmp/doc/cmdIndex.html [new file with mode: 0644]
distr/dddmp/doc/commands.html [new file with mode: 0644]
distr/dddmp/doc/credit.html [new file with mode: 0644]
distr/dddmp/doc/dddmp-2.0-A4.ps [new file with mode: 0644]
distr/dddmp/doc/dddmp-2.0-Letter.ps [new file with mode: 0644]
distr/dddmp/doc/dddmpAllAbs.html [new file with mode: 0644]
distr/dddmp/doc/dddmpAllByFile.html [new file with mode: 0644]
distr/dddmp/doc/dddmpAllByFunc.html [new file with mode: 0644]
distr/dddmp/doc/dddmpAllDet.html [new file with mode: 0644]
distr/dddmp/doc/dddmpAllFile.html [new file with mode: 0644]
distr/dddmp/doc/dddmpDesc.html [new file with mode: 0644]
distr/dddmp/doc/dddmpDoc.txt [new file with mode: 0644]
distr/dddmp/doc/dddmpExt.html [new file with mode: 0644]
distr/dddmp/doc/dddmpExtAbs.html [new file with mode: 0644]
distr/dddmp/doc/dddmpExtDet.html [new file with mode: 0644]
distr/dddmp/doc/dddmpTitle.html [new file with mode: 0644]
distr/dddmp/doc/packages.html [new file with mode: 0644]
distr/dddmp/doc/pkgIndex.html [new file with mode: 0644]
distr/dddmp/exp/0.add [new file with mode: 0644]
distr/dddmp/exp/0.bdd [new file with mode: 0644]
distr/dddmp/exp/0or1.bdd [new file with mode: 0644]
distr/dddmp/exp/1.add [new file with mode: 0644]
distr/dddmp/exp/1.bdd [new file with mode: 0644]
distr/dddmp/exp/2.bdd [new file with mode: 0644]
distr/dddmp/exp/2and3.bdd [new file with mode: 0644]
distr/dddmp/exp/3.bdd [new file with mode: 0644]
distr/dddmp/exp/4.bdd [new file with mode: 0644]
distr/dddmp/exp/4.bdd.bis1 [new file with mode: 0644]
distr/dddmp/exp/4.bdd.bis2 [new file with mode: 0644]
distr/dddmp/exp/4.bdd.bis3 [new file with mode: 0644]
distr/dddmp/exp/4.bdd.bis4 [new file with mode: 0644]
distr/dddmp/exp/4.cnf [new file with mode: 0644]
distr/dddmp/exp/4.cnf.bis [new file with mode: 0644]
distr/dddmp/exp/4.max1 [new file with mode: 0644]
distr/dddmp/exp/4.max2 [new file with mode: 0644]
distr/dddmp/exp/4bis.bdd [new file with mode: 0644]
distr/dddmp/exp/4xor5.bdd [new file with mode: 0644]
distr/dddmp/exp/5.bdd [new file with mode: 0644]
distr/dddmp/exp/composeids.txt [new file with mode: 0644]
distr/dddmp/exp/one.bdd [new file with mode: 0644]
distr/dddmp/exp/runAllTest.out [new file with mode: 0644]
distr/dddmp/exp/runAllTest.script [new file with mode: 0755]
distr/dddmp/exp/s27RP1.bdd [new file with mode: 0644]
distr/dddmp/exp/s27deltaDddmp1.bdd [new file with mode: 0644]
distr/dddmp/exp/s27deltaDddmp1.bdd.bis [new file with mode: 0644]
distr/dddmp/exp/s27deltaDddmp2.bdd [new file with mode: 0644]
distr/dddmp/exp/test1.out [new file with mode: 0644]
distr/dddmp/exp/test1.script [new file with mode: 0755]
distr/dddmp/exp/test2.out [new file with mode: 0644]
distr/dddmp/exp/test2.script [new file with mode: 0755]
distr/dddmp/exp/test3.out [new file with mode: 0644]
distr/dddmp/exp/test3.script [new file with mode: 0755]
distr/dddmp/exp/test4.out [new file with mode: 0644]
distr/dddmp/exp/test4.script [new file with mode: 0755]
distr/dddmp/exp/test5.out [new file with mode: 0644]
distr/dddmp/exp/test5.script [new file with mode: 0755]
distr/dddmp/exp/test6.out [new file with mode: 0644]
distr/dddmp/exp/test6.script [new file with mode: 0755]
distr/dddmp/exp/test7.out [new file with mode: 0644]
distr/dddmp/exp/test7.script [new file with mode: 0755]
distr/dddmp/exp/varauxids.ord [new file with mode: 0644]
distr/dddmp/exp/varnames.ord [new file with mode: 0644]
distr/dddmp/exp/zero.bdd [new file with mode: 0644]
distr/dddmp/testdddmp.c [new file with mode: 0644]
distr/epd/Makefile [new file with mode: 0644]
distr/epd/epd.c [new file with mode: 0644]
distr/epd/epd.h [new file with mode: 0644]
distr/mnemosyne/Makefile [new file with mode: 0644]
distr/mnemosyne/README [new file with mode: 0644]
distr/mnemosyne/mnemalyse.c [new file with mode: 0644]
distr/mnemosyne/mnemconf.h [new file with mode: 0644]
distr/mnemosyne/mnemosyne.c [new file with mode: 0644]
distr/mnemosyne/mnemosyne.h [new file with mode: 0644]
distr/mnemosyne/mtest.c [new file with mode: 0644]
distr/mtr/Makefile [new file with mode: 0644]
distr/mtr/Makefile.sis [new file with mode: 0644]
distr/mtr/doc/mtr.doc [new file with mode: 0644]
distr/mtr/doc/mtrAllAbs.html [new file with mode: 0644]
distr/mtr/doc/mtrAllDet.html [new file with mode: 0644]
distr/mtr/doc/mtrExtAbs.html [new file with mode: 0644]
distr/mtr/doc/mtrExtDet.html [new file with mode: 0644]
distr/mtr/mtr.h [new file with mode: 0644]
distr/mtr/mtrBasic.c [new file with mode: 0644]
distr/mtr/mtrGroup.c [new file with mode: 0644]
distr/mtr/mtrInt.h [new file with mode: 0644]
distr/mtr/test.groups [new file with mode: 0644]
distr/mtr/testmtr.c [new file with mode: 0644]
distr/nanotrav/C17.blif [new file with mode: 0644]
distr/nanotrav/C17.out [new file with mode: 0644]
distr/nanotrav/C880.blif [new file with mode: 0644]
distr/nanotrav/C880.out [new file with mode: 0644]
distr/nanotrav/Makefile [new file with mode: 0644]
distr/nanotrav/README [new file with mode: 0644]
distr/nanotrav/bnet.c [new file with mode: 0644]
distr/nanotrav/bnet.h [new file with mode: 0644]
distr/nanotrav/chkMterm.c [new file with mode: 0644]
distr/nanotrav/doc/bnetAllAbs.html [new file with mode: 0644]
distr/nanotrav/doc/bnetAllDet.html [new file with mode: 0644]
distr/nanotrav/doc/bnetExtAbs.html [new file with mode: 0644]
distr/nanotrav/doc/bnetExtDet.html [new file with mode: 0644]
distr/nanotrav/doc/ntrAllAbs.html [new file with mode: 0644]
distr/nanotrav/doc/ntrAllDet.html [new file with mode: 0644]
distr/nanotrav/doc/ntrExtAbs.html [new file with mode: 0644]
distr/nanotrav/doc/ntrExtDet.html [new file with mode: 0644]
distr/nanotrav/main.c [new file with mode: 0644]
distr/nanotrav/mult32a.blif [new file with mode: 0644]
distr/nanotrav/mult32a.out [new file with mode: 0644]
distr/nanotrav/nanotrav.1 [new file with mode: 0644]
distr/nanotrav/ntr.c [new file with mode: 0644]
distr/nanotrav/ntr.h [new file with mode: 0644]
distr/nanotrav/ntrBddTest.c [new file with mode: 0644]
distr/nanotrav/ntrHeap.c [new file with mode: 0644]
distr/nanotrav/ntrMflow.c [new file with mode: 0644]
distr/nanotrav/ntrShort.c [new file with mode: 0644]
distr/nanotrav/ntrZddTest.c [new file with mode: 0644]
distr/nanotrav/rcn25.blif [new file with mode: 0644]
distr/nanotrav/rcn25.out [new file with mode: 0644]
distr/nanotrav/s27.blif [new file with mode: 0644]
distr/nanotrav/s27.out [new file with mode: 0644]
distr/nanotrav/tst.sh [new file with mode: 0755]
distr/nanotrav/ucbqsort.c [new file with mode: 0644]
distr/obj/Makefile [new file with mode: 0644]
distr/obj/cuddObj.cc [new file with mode: 0644]
distr/obj/cuddObj.hh [new file with mode: 0644]
distr/obj/test.out [new file with mode: 0644]
distr/obj/testobj.cc [new file with mode: 0644]
distr/setup.sh [new file with mode: 0755]
distr/shutdown.sh [new file with mode: 0755]
distr/sis/Makefile.sis [new file with mode: 0644]
distr/sis/cuddBdd.h [new file with mode: 0644]
distr/sis/cuddBddPort.c [new file with mode: 0644]
distr/sis/cuddPwPt.c [new file with mode: 0644]
distr/sis/st.c [new file with mode: 0644]
distr/sis/st.h [new file with mode: 0644]
distr/st/Makefile [new file with mode: 0644]
distr/st/doc/stAllAbs.html [new file with mode: 0644]
distr/st/doc/stAllDet.html [new file with mode: 0644]
distr/st/doc/stExtAbs.html [new file with mode: 0644]
distr/st/doc/stExtDet.html [new file with mode: 0644]
distr/st/st.c [new file with mode: 0644]
distr/st/st.h [new file with mode: 0644]
distr/util/Makefile [new file with mode: 0644]
distr/util/cpu_stats.c [new file with mode: 0644]
distr/util/cpu_time.c [new file with mode: 0644]
distr/util/datalimit.c [new file with mode: 0644]
distr/util/getopt.c [new file with mode: 0644]
distr/util/pathsearch.c [new file with mode: 0644]
distr/util/pipefork.c [new file with mode: 0644]
distr/util/prtime.c [new file with mode: 0644]
distr/util/ptime.c [new file with mode: 0644]
distr/util/restart.c [new file with mode: 0644]
distr/util/safe_mem.c [new file with mode: 0644]
distr/util/saveimage.c [new file with mode: 0644]
distr/util/state.c [new file with mode: 0644]
distr/util/strsav.c [new file with mode: 0644]
distr/util/stub.c [new file with mode: 0644]
distr/util/test-res.c [new file with mode: 0644]
distr/util/test-sav.c [new file with mode: 0644]
distr/util/texpand.c [new file with mode: 0644]
distr/util/tmpfile.c [new file with mode: 0644]
distr/util/util.h [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..07f0bf3
--- /dev/null
@@ -0,0 +1,8 @@
+*~
+*.o
+*.a
+*.so
+*.sw[pqrs]
+*.fasl
+# autogenerated:
+cuddapi.lisp
diff --git a/asdf-component-shared-unix-library.asd b/asdf-component-shared-unix-library.asd
new file mode 100644 (file)
index 0000000..5214a21
--- /dev/null
@@ -0,0 +1,47 @@
+;;; ASDF Definition.  -*- lisp -*-
+
+(defpackage :asdf-component-shared-unix-library-system
+  (:use :cl :asdf)
+  (:export #:shared-unix-library))
+
+(in-package :asdf-component-shared-unix-library-system)
+
+(defclass shared-unix-library (source-file)
+  ())
+
+(defmethod source-file-type ((component shared-unix-library) system)
+  "so")
+
+(defmethod input-files (operation (component shared-unix-library))
+  nil)
+
+(defmethod output-files ((operation compile-op) (component shared-unix-library))
+  nil)
+
+(defmethod perform ((operation compile-op) (component shared-unix-library))
+  nil)
+(defmethod operation-done-p ((o compile-op) (c shared-unix-library))
+  t)
+(defmethod operation-done-p ((o load-op) (c shared-unix-library))
+  nil)
+
+(defmethod perform ((operation load-op) (component shared-unix-library))
+  (flet ((load-lib (lib)
+          #+cffi
+          (cffi:load-foreign-library lib)
+          #+(and (not cffi) sbcl)
+          (sb-alien:load-shared-object lib)
+          #+(and (not cffi) allegro)
+          (load lib :foreign t)
+          #-(or sbcl allegro cffi)
+          (error "No foreign library support")))
+    (handler-case (load-lib (component-pathname component))
+       (error (e) (declare (ignore e))
+              nil))))
+
+(pushnew :asdf-component-shared-unix-library *features*)
+
+(asdf:defsystem :asdf-component-shared-unix-library
+  :name "ASDF component :shared-unix-library"
+  :components ())
+
diff --git a/cudd-cffi.i b/cudd-cffi.i
new file mode 100644 (file)
index 0000000..c20d27f
--- /dev/null
@@ -0,0 +1,496 @@
+/* swig interface wrapper file for cffi binding generation -*- lisp -*- */
+/* swig -cffi interface for CUDD */
+/* (c) 2009 Utz-Uwe Haus */
+
+%module "cuddapi"
+
+%feature("intern_function","1");   // use swig-lispify
+%feature("export");                // export wrapped things
+
+%insert("lisphead")%{
+;;; Auto-generated -*- lisp -*- file
+;;; generated from $Id:$
+(eval-when (:compile-toplevel :load-toplevel)
+  (declaim (optimize (speed 3) (debug 0) (safety 1))))
+
+(cl:defpackage :swig-macros
+  (:use :cl :cffi)
+  (:documentation "Package containing utility functions for SWIG cffi interface generation")
+  (:export #:swig-lispify #:defanonenum))
+
+(cl:in-package :swig-macros)
+
+(cl:defun swig-lispify (name flag cl:&optional (package (find-package :cuddapi)))
+      (cl:labels ((helper (lst last rest cl:&aux (c (cl:car lst)))
+                    (cl:cond
+                      ((cl:null lst)
+                       rest)
+                      ((cl:upper-case-p c)
+                       (helper (cl:cdr lst) 'upper
+                               (cl:case last
+                                 ((lower digit) (cl:list* c #\- rest))
+                                 (cl:t (cl:cons c rest)))))
+                      ((cl:lower-case-p c)
+                       (helper (cl:cdr lst) 'lower (cl:cons (cl:char-upcase c) rest)))
+                      ((cl:digit-char-p c)
+                       (helper (cl:cdr lst) 'digit 
+                               (cl:case last
+                                 ((upper lower) (cl:list* c #\- rest))
+                                 (cl:t (cl:cons c rest)))))
+                      ((cl:char-equal c #\_)
+                       (helper (cl:cdr lst) '_ (cl:cons #\- rest)))
+                     ((cl:char-equal c #\-)
+                       (helper (cl:cdr lst) '- (cl:cons #\- rest)))
+                      (cl:t
+                       (cl:error "Invalid character: ~A" c)))))
+        (cl:let ((fix (cl:case flag
+                        ((constant enumvalue) "+")
+                        (variable "*")
+                        (cl:t ""))))
+          (cl:intern
+           (cl:concatenate
+            'cl:string
+            fix
+            (cl:nreverse (helper (cl:concatenate 'cl:list name) cl:nil cl:nil))
+            fix)
+           package))))
+
+
+%}
+
+%{
+
+/* includes that SWIG needs to see to parse the cudd.h file go here */
+
+%}
+
+%insert ("swiglisp") %{
+
+(cl:defpackage #:cuddapi
+  (:use :cl :cffi :swig-macros)
+  (:export #:cudd-manager #:cudd-node)
+  ;; other exports done by swig
+  )
+(cl:in-package :cuddapi)
+%}
+%insert ("swiglisp") %{
+;; foreign type definitions to hide pointer values
+(defclass wrapped-pointer ()
+  ((ptrval :reader get-ptrval :initarg :ptrval)
+   (ctype  :reader get-ctype :initarg :ctype))
+  (:documentation "A wrapped pointer"))
+
+(defmethod print-object ((p wrapped-pointer) stream)
+  (print-unreadable-object (p stream :type nil :identity nil)
+    (format stream "wrapper around `~A' @0x~16R" (get-ctype p) (get-ptrval p))))
+
+(define-condition foreign-null-pointer-condition (error)
+  ((type :initarg :type
+        :reader foreign-null-pointer-condition-type))
+  (:report (lambda (condition stream)
+            (format stream "The foreign pointer of type ~A was NULL"
+                    (foreign-null-pointer-condition-type condition)))))
+
+%}
+
+%define TYPEMAP_WRAPPED_POINTER(PTRTYPE,LISPCLASS)
+
+%insert ("swiglisp") %{
+(define-foreign-type LISPCLASS ()
+  ()
+  (:actual-type :pointer)
+  (:documentation "cffi wrapper type around PTRTYPE."))
+
+(define-parse-method LISPCLASS ()
+  (make-instance 'LISPCLASS))
+
+(defmethod translate-from-foreign (value (type LISPCLASS))
+  "Wrap PTRTYPE, signaling a null-pointer-exception if value is NULL."
+  (if (cffi:null-pointer-p value)
+      (error 'foreign-null-pointer-condition :type type)
+      (make-instance 'wrapped-pointer :ptrval value :ctype "PTRTYPE")))
+
+(defmethod translate-to-foreign ((g wrapped-pointer) (type LISPCLASS))
+  "Unwrap PTRTYPE"
+  (get-ptrval g))
+
+%}
+%typemap (cin) PTRTYPE "LISPCLASS"
+%typemap (cout) PTRTYPE "LISPCLASS"
+%enddef
+
+TYPEMAP_WRAPPED_POINTER(DdManager *, cudd-manager)
+TYPEMAP_WRAPPED_POINTER(DdNode *, cudd-node)
+
+%typemap (cin)  DdManager * "cudd-manager"
+%typemap (cout) DdManager * "cudd-manager"
+%typemap (cin)  DdNode * "cudd-node"
+%typemap (cout) DdNode * "cudd-node"
+
+/* Now parse and wrap the API header */
+%insert ("swiglisp") %{
+(eval-when (:compile-toplevel :load-toplevel)
+  ;; Muffle compiler-notes globally
+  #+sbcl (declaim (sb-ext:muffle-conditions sb-ext:defconstant-uneql))
+  
+%}
+
+%include "cudd/cudd.h"
+%insert ("swiglisp") %{
+) ;; end of eval-when to avoid top-level export 
+%}
+
+%insert ("swiglisp") %{
+;; (defmethod translate-from-foreign :around (manager (type cudd-manager))
+;;   (let ((cudd-manager (call-next-method)))
+;;     (when manager
+;;       (trivial-garbage:finalize cudd-manager #'(lambda () 
+;;                                              ;; (break "finalize manager #x~x~%" manager)
+;;                                                                                           ;; (format T "kill mgmr ~A~%" manager) (force-output)
+                                                
+                                                
+                                                
+;;                                              (format T "~D nodes unfreed in manager ~A" (cuddapi:cudd-check-zero-ref manager) manager)
+;;                                              ;;                                              (cuddapi:cudd-quit manager)
+;; ;;                                                                                        (format T "killed mgmr ~A~%" manager) (force-output)
+;;                                              )))
+    
+;;     cudd-manager))
+%}
+%insert ("swiglisp") %{
+;; (defmethod translate-from-foreign :around (node (type cudd-node))
+;;   (let ((cudd-node (call-next-method)))
+;;     (when node
+;;       (trivial-garbage:finalize cudd-node #'(lambda () 
+;;                                           ;; (format T "finalize node #x~x~%" node)
+;;                                           ;; (format T "kill node ~A" node) (force-output)
+
+;; ;;                                        (format T "~&killed ~A~%" node)
+;;                                           ;;                                              (format T "killed node ~A~%" node) (force-output)
+;;                                           )))
+;;     cudd-node))
+%}
+
+
+\f
+
+%insert ("swiglisp") %{
+;;; Higher-level interface similar to de.uuhaus.bdd
+(defpackage #:cudd
+  (:use #:cuddapi #:cl)
+  (:export #:bdd-environment)
+  (:export #:with-bdd-environment #:make-bdd-environment)
+  ;  (:export #:make-bdd)
+  (:export #:bdd-true #:bdd-false)
+  (:export #:bdd-new-variable)
+  (:export #:bdd-and #:bdd-or #:bdd-not #:bdd-xor #:bdd-nand #:bdd-nor 
+          #:bdd-and-not #:bdd-or-not #:bdd-implies
+          #:bdd-iff #:bdd-restrict)
+  (:export #:bdd-exists #:bdd-forall)
+  (:export #:bdd-tautologyp #:bdd-satisfiablep)
+  (:export #:bdd-var-min #:bdd-var-max)
+  (:export #:bdd-var-fixed0 #:bdd-var-fixed0)
+  (:export #:deserialize-bdd))
+
+(cl:in-package :cudd)
+
+\f
+;; for garbage collection purposes we wrap a reference to the manager with each
+;; variable object
+(defvar *bdd-env* nil
+  "A special variable holding the current BDD Environment.")
+
+(deftype wrapped-bdd ()
+  `(simple-vector 2))
+
+(defmacro wrap-bdd (bdd env)
+  "Build a lisp object object around the cudd-node v."
+  `(the wrapped-bdd
+     (make-array 2 :adjustable NIL :fill-pointer NIL
+                :initial-contents 
+                (list ,bdd ,env)))
+  )
+
+(defmacro unwrap-bdd (bdd)
+  "Extract the cudd-node object from bdd."
+  `(svref (the wrapped-bdd ,bdd) 0)
+  )
+
+\f
+(defun make-cudd-manager (&key
+                         (initial-num-vars 0)
+                         (initial-num-slots 256) ;; #.(cuddapi:CUDD-UNIQUE-SLOTS)
+                         (cache-size 262144) ;; #.(cuddapi:CUDD-CACHE-SLOTS)
+                         (max-memory 0))
+  (cuddapi:cudd-init initial-num-vars
+                    0  ;; num-zvars
+                    initial-num-slots
+                    cache-size
+                    max-memory))
+
+(defstruct (bdd-environment (:constructor construct-bdd-environment))
+  "A wrapper object describing a CUDD-based BDD environment."
+  (manager )
+  (name "" :type string)
+  ;; caching of the T and F objects of this manager to save FF overhead
+  (true)
+  (false)
+  ;; mapping VARs to foreign IDs
+  (var->id (make-hash-table :test #'eq) :type hash-table)
+  (nextvar 0 :type (integer 0 #.(expt 2 (* 8 (- (cffi:foreign-type-size :int) 1))))))
+
+(defmethod print-object ((e bdd-environment) stream)
+  (print-unreadable-object (e stream :type T)
+    (format stream "~A (manager @#x~X, ~D vars)" 
+           (bdd-environment-name e)
+           (cuddapi::get-ptrval (bdd-environment-manager e))
+           (bdd-environment-nextvar e))))
+
+(defun make-bdd-environment (&key
+                            (manager (make-cudd-manager))
+                            (name (format nil "BDD Environment ~A" (gensym "BDDE"))))
+  (let ((res (construct-bdd-environment :manager manager :name name)))
+    (setf (bdd-environment-true res)
+         (wrap-bdd (cuddapi:cudd-read-one manager) res))
+    (setf (bdd-environment-false res)
+         (wrap-bdd (cuddapi:cudd-read-logic-zero manager) res))
+    ;; these need no finalization:
+    (trivial-garbage:cancel-finalization (unwrap-bdd (bdd-environment-false res)))
+    (trivial-garbage:cancel-finalization (unwrap-bdd (bdd-environment-true res)))
+
+    
+    (let ((vartab (bdd-environment-var->id res)))
+      (trivial-garbage:finalize res 
+                               #'(lambda ()
+                                   (format T "~&killing ~D vars in ~A~%"
+                                           (hash-table-size vartab)
+                                           manager)
+                                   (maphash #'(lambda (key val)
+                                                (declare (ignore val))
+                                                (cuddapi:cudd-recursive-deref
+                                                 (unwrap-bdd key)))
+                                            vartab))))
+    res))
+
+(eval-when (:load-toplevel)
+  (setf *bdd-env* (or *bdd-env*
+                     (make-bdd-environment :name "The global BDD Environment."))))
+
+(defmacro with-bdd-environment (env &body body)
+  "Execute BODY within the bdd environment ENV."
+  `(let ((*bdd-env* ,env))
+     ,@body))
+\f
+;;; utility functions for the environment
+(defun var->id (var &optional (env *bdd-env*))
+  "Return the ID for VAR in ENV (which defaults to *bdd-env*)."
+  (gethash var (bdd-environment-var->id env)))
+
+(defsetf var->id (var &optional (env *bdd-env*)) (id)
+  `(setf (gethash ,var (bdd-environment-var->id ,env)) ,id))
+
+(defun id->var (id &optional (env *bdd-env*))
+  "Return the VAR for ID  in ENV (which defaults to *bdd-env*)."
+  (wrap-bdd (cuddapi:cudd-bdd-ith-var (bdd-environment-manager env) id) env))
+
+\f
+(defun bdd-true ()
+  (bdd-environment-true *bdd-env*))
+
+(defun bdd-false ()
+  (bdd-environment-false *bdd-env*))
+
+(defun bdd-new-variable ()
+  (handler-case
+      (let ((v (wrap-bdd
+               (cuddapi:cudd-bdd-new-var (bdd-environment-manager *bdd-env*))
+               *bdd-env*))
+           (id (bdd-environment-nextvar *bdd-env*)))
+       (progn
+         (incf (bdd-environment-nextvar *bdd-env*))
+         (setf (var->id v *bdd-env*) id)
+         v))
+    (cuddapi::foreign-null-pointer-condition (c)
+      (declare (ignore c))
+      ;; FIXME: maybe try a garbage collection here
+      (error "CUDD failed to allocate a variable ~D:~%BDD environment ~A full." 
+            (bdd-environment-nextvar *bdd-env*)
+            *bdd-env*))))
+
+(defun bdd-restrict (var val bdd)
+  (wrap-bdd
+   (cuddapi:cudd-bdd-restrict (bdd-environment-manager *bdd-env*)
+                             (unwrap-bdd bdd)
+                             (unwrap-bdd (if val var (bdd-not var))))
+   *bdd-env*))
+
+(defun bdd-and (x y)
+  (wrap-bdd
+   (cuddapi:cudd-bdd-and (bdd-environment-manager *bdd-env*) 
+                        (unwrap-bdd x) (unwrap-bdd y))
+   *bdd-env*))
+
+(defun bdd-or (x y)
+  (wrap-bdd
+   (cuddapi:cudd-bdd-or (bdd-environment-manager *bdd-env*) 
+                       (unwrap-bdd x) (unwrap-bdd y))
+   *bdd-env*))
+
+(defun bdd-not (x)
+  ;; FIXME: cudd-not is a macro and hence not swig'ed, but would probably 
+  ;; perform be better
+  (wrap-bdd
+   (cuddapi:cudd-bdd-nand (bdd-environment-manager *bdd-env*)
+                         (unwrap-bdd x)
+                         (unwrap-bdd x))
+   *bdd-env*))
+
+(defun bdd-xor (x y)
+  (wrap-bdd
+   (cuddapi:cudd-bdd-xor (bdd-environment-manager *bdd-env*) 
+                        (unwrap-bdd x)
+                        (unwrap-bdd y))
+   *bdd-env*))
+
+(defun bdd-nand (x y)
+  (wrap-bdd
+   (cuddapi:cudd-bdd-nand (bdd-environment-manager *bdd-env*) 
+                         (unwrap-bdd x) 
+                         (unwrap-bdd y))
+   *bdd-env*))
+
+(defun bdd-nor (x y)
+  (wrap-bdd
+   (cuddapi:cudd-bdd-nor (bdd-environment-manager *bdd-env*) 
+                        (unwrap-bdd x)
+                        (unwrap-bdd y))
+   *bdd-env*))
+
+(defun bdd-and-not (bdd1 bdd2)
+  (bdd-and bdd1 (bdd-not bdd2)))
+
+(defun bdd-or-not (bdd1 bdd2)
+  (bdd-or bdd1 (bdd-not bdd2)))
+
+(defun bdd-implies (bdd1 bdd2)
+  (bdd-or-not bdd1 bdd2))
+
+(defun bdd-iff (bdd1 bdd2)
+  (bdd-and (bdd-implies bdd1 bdd2)
+          (bdd-implies bdd2 bdd1)))
+
+(defun bdd-equal (bdd1 bdd2)
+  "Check whether BDD1 and BDD2 are equal."
+  (let ((b1 (unwrap-bdd bdd1))
+       (b2 (unwrap-bdd bdd2)))
+    (and (= 1 (cuddapi:cudd-bdd-leq (bdd-environment-manager *bdd-env*) b1 b2))
+        (= 1 (cuddapi:cudd-bdd-leq (bdd-environment-manager *bdd-env*) b2 b1)))))
+
+(defun bdd-tautologyp (bdd &optional (fixings '()))
+  "Check whether BDD is tautologic, possibly under a given fixing in FIXINGS, a list of pairs (bddvar . value), value being T or NIL. "
+  (if fixings
+      (bdd-tautologyp (bdd-restrict (caar fixings) (cadr fixings) bdd)
+                     (cdr fixings))
+      (bdd-equal bdd (bdd-true))))
+
+(defun bdd-satisfiablep (bdd &optional (fixings '()))
+  "Check whether BDD is satisfiable, possibly under a given fixing in FIXINGS, a list of pairs (bddvar . value), value being T or NIL. "
+  (if fixings
+      (bdd-satisfiablep (bdd-restrict (caar fixings) (cadr fixings) bdd)
+                       (cdr fixings))
+      (not (bdd-equal bdd (bdd-false)))))
+
+(defun bdd-var-fixed0 (bdd var)
+  (ecase (cuddapi:cudd-bdd-is-var-essential (bdd-environment-manager *bdd-env*)
+                                           bdd
+                                           (var->id var *bdd-env*)
+                                           0)
+    (1 T)
+    (0 NIL)))
+
+(defun bdd-var-fixed1 (bdd var)
+  (ecase (cuddapi:cudd-bdd-is-var-essential (bdd-environment-manager *bdd-env*)
+                                           bdd
+                                           (var->id var)
+                                           1)
+    (1 T)
+    (0 NIL)))
+
+(defgeneric deserialize-bdd (source)
+  (:documentation "Parse a textual representation of a BDD from SOURCE within the current BDD environment."))
+
+(defmethod deserialize-bdd ((s string))
+  (with-input-from-string (f s)
+    (deserialize-bdd f)))
+
+(defmethod deserialize-bdd ((s pathname))
+  (with-open-file (f s :direction :input)
+    (deserialize-bdd f)))
+
+(defmethod deserialize-bdd ((l list))
+  (with-input-from-string (f (format nil "~W" l))
+    (deserialize-bdd f)))
+
+(defmethod deserialize-bdd ((s stream))
+  "Read a textual external representation of a bdd from STREAM.
+New variables are allocated in the current bdd environment.
+Returns two values: the bdd structure and an alist mapping variable numbers to the
+variable names specified in the bdd file."
+  (labels ((parse-bddfile (s)
+             (let* ((bddblock (read s))
+                    (data (member "BDD" bddblock :test #'string-equal) )
+                    (tree nil)
+                    (nodenames nil))
+               (unless data
+                 (error "Could not find BDD block in ~A" data))
+               (setf data (cdr data))
+               (setf tree (assoc "DAG" data :test #'string-equal))
+               (unless tree 
+                 (error "Could not find BDD DAG in ~A" data))
+               (setf tree (cadr tree))
+               (setf nodenames (assoc "VARNAMES" data :test #'string-equal))
+               (unless nodenames 
+                 (error "Could not find node name mapping in ~A" data))
+               (setf nodenames (cadr nodenames))
+               (values tree nodenames)))
+           (max-varnum (tree)
+             ;; we depend on having consecutive variable numbers in the bdd file
+             ;; starting above 0
+             ;; Deducing maxvarnum from tree instead of varnames is safer because some
+             ;; variable may be missing a name. In that case we fail softly: the tree will be
+             ;; fine, but the mapping returned to the caller will be defective in the same way
+             ;; that the user messed it up when calling serialize-bdd with an incomplete name map.
+             (if (consp tree)
+                 (max (second tree)
+                      (max-varnum (third tree))
+                      (max-varnum (fourth tree)))
+                 0)))
+    (multiple-value-bind (tree nodenames)
+        (parse-bddfile s)
+      (let* ((maxvar (max-varnum tree))
+             (mapping (make-hash-table :size maxvar :test #'eql)))
+       ;; fetch new variables
+       (loop :for i :from 2 :upto maxvar
+          :do (setf (gethash i mapping) (bdd-new-variable)))
+        (labels ((walk (bddtext)
+                   (cond
+                     ((eq bddtext NIL)
+                      (bdd-false))
+                     ((eq bddtext T)
+                      (bdd-true))
+                     (T
+                     (let ((thisvar (gethash (second bddtext) mapping))
+                           (t-child (walk (third bddtext)))
+                           (nil-child (walk (fourth bddtext))))
+                       (bdd-or (bdd-and thisvar t-child)
+                               (bdd-and (bdd-not thisvar) nil-child)))))))
+          (values
+           (walk tree)
+           (loop :for pair :in nodenames
+              :as oldnum := (car pair)
+              :do (setf (car pair)
+                       (gethash oldnum mapping))
+              :finally (return nodenames))))))))
+
+
+%}
\ No newline at end of file
diff --git a/cudd.asd b/cudd.asd
new file mode 100644 (file)
index 0000000..da12ad1
--- /dev/null
+++ b/cudd.asd
@@ -0,0 +1,60 @@
+;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10; -*-
+;;;
+;;; cudd.asd --- cudd wrapper
+
+;; Copyright (C) 2009 Utz-Uwe Haus <lisp@uuhaus.de>
+;;
+;; $Id:$
+;;
+;; This code is free software; you can redistribute it and/or modify
+;; it under the terms of the version 3 of the GNU General
+;; Public License as published by the Free Software Foundation, as
+;; clarified by the prequel found in LICENSE.Lisp-GPL-Preface.
+;;
+;; This code is distributed in the hope that it will be useful, but
+;; without any warranty; without even the implied warranty of
+;; merchantability or fitness for a particular purpose. See the GNU
+;; Lesser General Public License for more details.
+;;
+;; Version 3 of the GNU General Public License is in the file
+;; LICENSE.GPL that was distributed with this file. If it is not
+;; present, you can access it from
+;; http://www.gnu.org/copyleft/gpl.txt (until superseded by a
+;; newer version) or write to the Free Software Foundation, Inc., 59
+;; Temple Place, Suite 330, Boston, MA 02111-1307 USA
+;;
+;; Commentary:
+
+;; 
+
+;;; Code:
+
+#-asdf-component-shared-unix-library
+(asdf:operate 'asdf:load-op :asdf-component-shared-unix-library)
+
+(defpackage #:cudd-system
+  (:use #:cl #:asdf #:asdf-component-shared-unix-library-system))
+(in-package #:cudd-system)
+
+(defsystem #:cudd
+  :description "?"
+  :version     "0"
+  :author      "Utz-Uwe Haus <lisp@uuhaus.de>"
+  :license     "ask me"
+  :depends-on  (:cffi :trivial-garbage)
+  :components  ((:module "foreignlib"
+                        :if-component-dep-fails :try-next
+                        :pathname "distr/"
+                        :components
+                        (;; try installed copy
+                         (:shared-unix-library "installed_libcudd"
+                                               :pathname "/usr/local/lib/libcudd.so")
+                         ;; try local copy
+                         (:shared-unix-library "temp_libcudd"
+                                               :pathname "./cudd/libcudd.so")))
+
+               ;;              (:file "package")
+               (:file "cuddapi" :depends-on ("foreignlib"))
+               (:file "cuddsat" :depends-on ("cuddapi"))
+                ))
+
diff --git a/cuddsat.lisp b/cuddsat.lisp
new file mode 100644 (file)
index 0000000..d979b91
--- /dev/null
@@ -0,0 +1,254 @@
+;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10; -*-
+;;;
+;;; cuddsat.lisp --- SAT solver based on CUDD BDDs
+
+;; Copyright (C) 2009 Utz-Uwe Haus <lisp@uuhaus.de>
+;; $Id:$
+;; This code is free software; you can redistribute it and/or modify
+;; it under the terms of the version 3 of the GNU General
+;; Public License as published by the Free Software Foundation, as
+;; clarified by the prequel found in LICENSE.Lisp-GPL-Preface.
+;;
+;; This code is distributed in the hope that it will be useful, but
+;; without any warranty; without even the implied warranty of
+;; merchantability or fitness for a particular purpose. See the GNU
+;; Lesser General Public License for more details.
+;;
+;; Version 3 of the GNU General Public License is in the file
+;; LICENSE.GPL that was distributed with this file. If it is not
+;; present, you can access it from
+;; http://www.gnu.org/copyleft/gpl.txt (until superseded by a
+;; newer version) or write to the Free Software Foundation, Inc., 59
+;; Temple Place, Suite 330, Boston, MA 02111-1307 USA
+;;
+;; Commentary:
+
+;; 
+
+;;; Code:
+
+(eval-when (:compile-toplevel :load-toplevel)
+  (declaim (optimize (speed 3) (debug 1) (safety 1))))
+
+
+(in-package #:CUDD)
+\f
+
+(defstruct sat-env 
+  (name)
+  (manager)
+  (cnf)
+  (true)
+  (false)
+  (vars #() :type simple-vector))
+
+(defmacro reference (f)
+  (let ((x (gensym)))
+    `(let ((,x ,f))
+       (cuddapi:cudd-ref ,x)
+       ,x)))
+
+(defmacro dereference (f manager)
+  (let ((x (gensym)))
+    `(let ((,x ,f))
+       (cuddapi:cudd-recursive-deref ,manager ,x)
+       ,x)))
+
+(defun make-clause-tree (env c)
+  (loop :with f := (reference (sat-env-false env))
+     :with manager := (sat-env-manager env)
+     :with vars := (sat-env-vars env)
+     :for x :of-type fixnum :in c
+     :as var := (svref vars (the cudd-int (abs x)))
+     :as phase := (signum x)
+     :do (let* ((var (if (= 1 phase)
+                        var
+                        (cuddapi:cudd-bdd-nand manager var var)))
+               (tmp (cuddapi:cudd-bdd-or manager var f)))
+          (reference tmp)
+          (dereference f manager)
+          (setf f tmp))
+     :finally (return f)))
+
+(defun sat-env-add-clause (env c)
+  (let* ((subtree (make-clause-tree env c))
+        (newcnf (cuddapi:cudd-bdd-and (sat-env-manager env)
+                                      (sat-env-cnf env) subtree)))
+    ;; reference new tree
+    (cuddapi:cudd-ref newcnf)
+    ;; deref consumed old tree
+    (cuddapi:cudd-recursive-deref (sat-env-manager env) (sat-env-cnf env))
+    (cuddapi:cudd-recursive-deref (sat-env-manager env) subtree)
+    (setf (sat-env-cnf env) newcnf))
+  (values))
+
+(deftype cudd-int ()
+   `(integer ,#.(1- (- (expt 2 (* 8 (- (cffi:foreign-type-size :int) 1)))))
+           ,#.(expt 2 (* 8 (- (cffi:foreign-type-size :int) 1)))))
+
+(defun destroy-sat-env (env)
+  (with-slots (name manager cnf vars)
+      env
+    (declare (type simple-vector vars))
+    (format *debug-io* "~&Cleaning up sat-env ~A, tree has ~D nodes~%" name
+           (cuddapi:cudd-dag-size  cnf))
+    ;; goes to stderr, unfortunately:
+    ;;     (cuddapi:cudd-print-debug manager cnf (length (sat-env-vars env)) 4)
+    ;;    (cuddapi:cudd-print-minterm manager cnf)
+    
+    ;;     (format *debug-io* " ~D refs initially~%"
+    ;;             (cuddapi:cudd-check-zero-ref manager))
+    (cuddapi:cudd-recursive-deref manager cnf)
+    (when (= 0 (the cudd-int (cuddapi:cudd-check-zero-ref manager)))
+      (break "env ~A empty too early: ~A" name env))
+
+    ;;     (format *debug-io* " destroyed tree, ~D left~%" 
+    ;;             (cuddapi:cudd-check-zero-ref manager))
+    (when (/= (length vars) (the cudd-int (cuddapi:cudd-check-zero-ref manager)))
+      (break "env ~A occupation does not match varcount: ~D vs ~D; ~A"
+            name
+            (length vars)
+            (cuddapi:cudd-check-zero-ref manager)
+            env))
+
+    (loop :for x :across vars
+       :do (cuddapi:cudd-deref x))
+;;      (format *debug-io* " ~D vars deleted, ~D left~%"
+;;         (length vars) (cuddapi:cudd-check-zero-ref manager))
+    (unless (= 0 (the cudd-int (cuddapi:cudd-check-zero-ref manager)))
+      (break "env ~A unclean: ~A" name env))
+    (unless (= 0 (the cudd-int (cuddapi:cudd-debug-check manager)))
+      (break "debug check failed ~D~%" (cuddapi:cudd-debug-check manager)))
+
+    (cuddapi:cudd-quit manager)
+;;    (format *debug-io* " done.~%")
+    
+    ))
+
+(defun make-cnf (numatoms clauses)
+  (let* ((name (gensym "cnf-sat-env"))
+        (manager (make-cudd-manager :initial-num-vars (1+ numatoms)))
+        (truevar (cuddapi:cudd-read-one manager))
+        (falsevar (cuddapi:cudd-read-logic-zero manager))
+        (vars (coerce (the list
+                        (loop :for i :of-type fixnum :from 0 :upto numatoms
+                           :collecting (reference (cuddapi:cudd-bdd-new-var manager))))
+                      'simple-vector))
+        (env (make-sat-env :name name
+                           :manager manager
+                           :cnf truevar
+                           :true truevar
+                           :false falsevar
+                           :vars vars)))
+    (cuddapi:cudd-ref truevar) ;; it is used as inital cnf
+    (cuddapi:cudd-enable-reordering-reporting manager)
+    (cuddapi:cudd-autodyn-enable manager :cudd-reorder-symm-sift)
+    ;    (cuddapi:cudd-autodyn-enable manager :cudd-reorder-symm-sift-conv)
+    ;    (cuddapi:cudd-autodyn-enable manager :cudd-reorder-symm-sift)
+    (loop :for c :in clauses
+       :do (sat-env-add-clause env c))
+    env))
+
+
+
+(defmacro with-sat-bdd ((name numatoms clauses) &body body)
+  `(let ((,name (make-cnf ,numatoms ,clauses)))
+     (declare (dynamic-extent ,name))
+     (unwind-protect
+         (progn ,@body)
+       (destroy-sat-env ,name))))
+
+(defun satisfiablep (sat-env f)
+  (= 0
+     (the cudd-int
+       (cuddapi:cudd-bdd-leq (sat-env-manager sat-env) 
+                            f (sat-env-false sat-env)))))
+
+(defun get-essential-vars (sat-env)
+  "Return a list of two lists: the indices of vars fixed to FALSE and those
+fixed to TRUE in the current cnf of sat-env"
+  (let ((t-ess '())
+       (f-ess '()))
+    (loop :with bdd := (reference (sat-env-cnf sat-env))
+       :with manager := (sat-env-manager sat-env)
+       :for i :of-type fixnum :from 1 :below (length (sat-env-vars sat-env))
+       :as var := (svref (sat-env-vars sat-env) i)
+       :as negvar := (cuddapi:cudd-bdd-nand manager var var)
+       :do (let ((tmp1 (reference
+                       (cuddapi:cudd-bdd-and manager var bdd)))
+                (tmp2 (reference
+                       (cuddapi:cudd-bdd-and manager negvar bdd))))
+            (let ((sat-with-T (satisfiablep sat-env tmp1))
+                  (sat-with-F (satisfiablep sat-env tmp2)))
+              (cond
+                ((or (and sat-with-T sat-with-F)
+                     (and (not sat-with-T) (not sat-with-F)))
+                 (dereference tmp1 manager)
+                 (dereference tmp2 manager))
+                ((and sat-with-T (not sat-with-F))
+                 (push i t-ess)
+                 (dereference bdd manager)
+                 (dereference tmp2 manager)
+                 (setf bdd tmp1))
+                ((and (not sat-with-T) sat-with-F)
+                 (push i f-ess)
+                 (dereference bdd manager)
+                 (dereference tmp1 manager)
+                 (setf bdd tmp2)))))
+       :finally (dereference bdd manager))
+     (list f-ess t-ess)))
+
+
+\f
+
+(defun satcheck (numatoms clauses)
+  "Check the CNF of CLAUSES or satisfiability. 
+NUMATOMS is the number of variables occuring in clauses, they are numbered from 1 through NUMATOMS.
+CLAUSES is a list of lists, where the sublists are (sparse) disjunctions of atom-indices. Positive/negative sign of index determine phase of literal in the clause.
+Return 3 values: T or NIL to answer SAT(clauses), and two lists of fixed-to-1 and fixed-to-0 atoms."
+  (with-sat-bdd (bdd numatoms clauses)
+    (apply #'values
+          (satisfiablep bdd (sat-env-cnf bdd))
+          (get-essential-vars bdd)) 
+    
+    ;; (format T "computing...~%")
+    ))
+
+(defmacro with-index-hash ((mapping &key (test 'cl:eq)) objects &body body)
+  "Execute BODY while binding MAPPING to a hash-table (with predicate
+TEST, defaults to #'cl:eq) mapping the OBJECTS to small integers."
+  `(let ((,mapping (loop :with ht := (make-hash-table :test ,test)
+                    :for x :in ,objects
+                     :for num :from 1
+                     :do (setf (gethash x ht) num)
+                     :finally (return ht))))
+     ,@body))
+
+(defun clauses-for-if (lhs rhs)
+  "Return clauses for LHS -> RHS, both being disjunctions."
+  (mapcar #'(lambda (lhsatom)
+             (cons (- lhsatom) rhs))
+         lhs))
+
+(defun clauses-for-iff (lhs rhs)
+  "Return clauses for LHS -> RHS, both being disjunctions."
+  (append (clauses-for-if lhs rhs)
+         (clauses-for-if rhs lhs)))
+
+(defun testsat (numvars numclauses &key
+               (maxlhs (/ numvars 2))
+               (maxrhs (/ numvars 2)))
+  (declare (type fixnum numvars numclauses))
+  (setf maxlhs (ceiling maxlhs))
+  (setf maxrhs (ceiling maxrhs))
+  (let ((clauses '()))
+    (declare (type fixnum maxlhs maxrhs))
+    (loop :repeat numclauses
+       :as lhs := (loop :repeat (random maxlhs)
+                    :collecting (1+ (random numvars)))
+       :as rhs := (loop :repeat (random maxrhs)
+                    :collecting (1+ (random numvars)))
+       :do (dolist (c (clauses-for-iff lhs rhs))
+            (push c clauses)))
+    ;    (format T "~D ~A~%" numvars clauses)
+    (satcheck numvars clauses)))
\ No newline at end of file
diff --git a/distr/LICENSE b/distr/LICENSE
new file mode 100644 (file)
index 0000000..99c7fba
--- /dev/null
@@ -0,0 +1,31 @@
+Copyright (c) 1995-2004, Regents of the University of Colorado
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+Neither the name of the University of Colorado nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/distr/Makefile b/distr/Makefile
new file mode 100644 (file)
index 0000000..d931d8c
--- /dev/null
@@ -0,0 +1,322 @@
+# $Id$
+#
+# Makefile for the CUDD distribution kit
+#---------------------------------------------------------------------------
+
+# Beginning of the configuration section. These symbol definitions can
+# be overridden from the command line.
+
+# C++ compiler
+CPP    = g++
+#CPP   = icpc
+#CPP   = ecpc
+#CPP   = CC
+#CPP   = /usr/local/opt/SUNWspro/bin/CC
+#CPP   = cxx
+
+# Specific options for compilation of C++ files.
+CPPFLAGS =
+# Stricter standard conformance for g++.
+#CPPFLAGS = -std=c++98
+# For Sun CC version 5, this invokes compatibility mode.
+#CPPFLAGS = -compat
+# On some versions of UP-UX, it is necessary to pass the option +a1
+# to CC for the C++ test program to compile successfully.
+#CPPFLAGS = +a1
+
+# C compiler used for all targets except optimize_dec, which always uses cc.
+#CC    = cc
+#CC    = /usr/local/opt/SUNWspro/bin/cc
+CC     = gcc
+#CC    = icc
+#CC    = ecc
+#CC    = /usr/ucb/cc
+#CC    = c89
+#CC    = $(CPP)
+
+# On some machines ranlib is either non-existent or redundant.
+# Use the following definition if your machine has ranlib and you think
+# it is needed.
+RANLIB = ranlib
+# Use the following definition if your machine either does not have
+# ranlib (e.g., SUN running solaris) or can do without it (e.g., DEC Alpha).
+#RANLIB        = :
+
+# Use ICFLAGS to specify machine-independent compilation flags.
+# These three are typical settings for cc.
+#ICFLAGS       = -g
+#ICFLAGS       = -O
+#ICFLAGS       =
+# These four are typical settings for optimized code with gcc.  The
+# last two also work with icc/ecc.
+#ICFLAGS       = -g -O6 -Wall
+ICFLAGS        = -g -O6
+#ICFLAGS       = -g -O3 -Wall
+#ICFLAGS       = -g -O3
+
+# Use XCFLAGS to specify machine-dependent compilation flags.
+# For some platforms no special flags are needed.
+#XCFLAGS       = -DHAVE_IEEE_754 -DBSD
+#
+#==========================
+#  Linux
+#
+# Gcc 3.2.2 or higher on i686.
+XCFLAGS        = -mtune=pentium4 -malign-double -DHAVE_IEEE_754 -DBSD
+# Gcc 2.8.1 on i686.
+#XCFLAGS       = -mcpu=pentiumpro -malign-double -DHAVE_IEEE_754 -DBSD
+# Gcc 4.2.4 or higher on x86_64 (64-bit compilation)
+#XCFLAGS       = -mtune=native -DHAVE_IEEE_754 -DBSD -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8
+# Gcc 4.2.4 or higher on x86_64 (32-bit compilation)
+#XCFLAGS       = -m32 -mtune=native -malign-double -DHAVE_IEEE_754 -DBSD
+# Icc on i686 (older versions may not support -xHost).
+#XCFLAGS       = -ansi -xHost -align -ip -DHAVE_IEEE_754 -DBSD
+# Icc on x86_64 (64-bit compilation).
+#XCFLAGS       = -ansi -xHost -align -ip -DHAVE_IEEE_754 -DBSD -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8
+# Gcc on ia64.
+#XCFLAGS       = -DHAVE_IEEE_754 -DBSD -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8
+# Icc/ecc on ia64.
+#XCFLAGS = -ansi -DBSD -DHAVE_IEEE_754 -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8
+#
+#==========================
+#  Solaris
+#
+# For Solaris, BSD should not be replaced by UNIX100.
+#XCFLAGS       = -DHAVE_IEEE_754 -DUNIX100 -DEPD_BIG_ENDIAN
+# Gcc 2.8.1 or higher on Ultrasparc.
+#XCFLAGS       = -mcpu=ultrasparc -DHAVE_IEEE_754 -DUNIX100 -DEPD_BIG_ENDIAN
+# For Solaris 2.5 and higher, optimized code with /usr/bin/cc or CC.
+#XCFLAGS       = -DHAVE_IEEE_754 -DUNIX100 -xO5 -native -dalign -DEPD_BIG_ENDIAN
+# On IA platforms, -dalign is not supported and causes warnings.
+#XCFLAGS       = -DHAVE_IEEE_754 -DUNIX100 -xO5 -native
+# Recent Sun compilers won't let you use -native on old Ultras.
+#XCFLAGS       = -DHAVE_IEEE_754 -DUNIX100 -xO5 -dalign -xlibmil -DEPD_BIG_ENDIAN
+# For Solaris 2.4, optimized code with /usr/bin/cc.
+#XCFLAGS       = -DHAVE_IEEE_754 -DUNIX100 -xO4 -dalign -DEPD_BIG_ENDIAN
+# For Solaris 2.5 and higher, optimized code with /usr/ucb/cc.
+#XCFLAGS       = -DHAVE_IEEE_754 -DBSD -xO5 -native -dalign -DEPD_BIG_ENDIAN
+#XCFLAGS       = -DHAVE_IEEE_754 -DBSD -xO5 -dalign -xlibmil -DEPD_BIG_ENDIAN
+# For Solaris 2.4, optimized code with /usr/ucb/cc.
+#XCFLAGS       = -DHAVE_IEEE_754 -DBSD -xO4 -dalign -DEPD_BIG_ENDIAN
+#
+#==========================
+#  DEC Alphas running Digital Unix
+#
+# For DEC Alphas either -ieee_with_inexact or -ieee_with_no_inexact is
+# needed. If you use only BDDs, -ieee_with_no_inexact is enough.
+# In the following, we consider three different compilers:
+# - the old native compiler (the one of MIPS ancestry that produces u-code);
+# - the new native compiler;
+# - gcc
+# On the Alphas, gcc (as of release 2.7.2) does not support 32-bit pointers
+# and IEEE 754 floating point arithmetic. Therefore, for this architecture
+# only, the native compilers provide a substatial advantage.
+# With the native compilers, specify -xtaso for 32-bit pointers.
+# Do not use -xtaso_short because explicit reference to stdout and stderr
+# does not work with this option. (Among other things.)
+# Notice that -taso must be included in LDFLAGS for -xtaso to work.
+# Given the number of possible choices, only some typical configurations
+# are proposed here.
+#
+# Old native compiler for the Alphas; 64-bit pointers.
+#XCFLAGS       = -DBSD -DHAVE_IEEE_754 -ieee_with_no_inexact -tune host -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8
+# Old native compiler for the Alphas; 32-bit pointers.
+#XCFLAGS       = -DBSD -DHAVE_IEEE_754 -ieee_with_no_inexact -tune host -xtaso -DSIZEOF_LONG=8
+# New native compiler for the Alphas; 64-bit pointers.
+#XCFLAGS       = -g3 -O4 -std -DBSD -DHAVE_IEEE_754 -ieee_with_no_inexact -tune host -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8
+# New native compiler for the Alphas; 32-bit pointers.
+#XCFLAGS       = -g3 -O4 -std -DBSD -DHAVE_IEEE_754 -ieee_with_no_inexact -tune host -xtaso -DSIZEOF_LONG=8
+# gcc for the Alphas: compile without HAVE_IEEE_754.
+#XCFLAGS       = -DBSD -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8
+#
+#==========================
+#
+#  IBM RS6000
+#
+# For the IBM RS6000 -qstrict is necessary when specifying -O3 with cc.
+#XCFLAGS       = -DBSD -DHAVE_IEEE_754 -DEPD_BIG_ENDIAN -O3 -qstrict
+#
+#==========================
+#
+#  HP-UX
+#
+# I haven't figured out how to enable IEEE 754 on the HPs I've tried...
+# For HP-UX using gcc.
+#XCFLAGS       = -DUNIX100 -DEPD_BIG_ENDIAN
+# For HP-UX using c89.
+#XCFLAGS       = +O3 -DUNIX100 -DEPD_BIG_ENDIAN
+#
+#==========================
+#
+#  Windows 95/98/NT/XP/Vista with Cygwin tools
+#
+# The value of RLIMIT_DATA_DEFAULT should reflect the amount of
+# available memory (expressed in bytes).
+# Recent versions of cygwin have getrlimit, but the datasize limit
+# cannot be set.
+#XCFLAGS       = -mtune=pentium4 -malign-double -DHAVE_IEEE_754 -DHAVE_GETRLIMIT=0 -DRLIMIT_DATA_DEFAULT=268435456
+
+
+# Define the level of self-checking and verbosity of the CUDD package.
+#DDDEBUG = -DDD_DEBUG -DDD_VERBOSE -DDD_STATS -DDD_CACHE_PROFILE -DDD_UNIQUE_PROFILE -DDD_COUNT
+DDDEBUG        =
+
+# Define the level of self-checking and verbosity of the MTR package.
+#MTRDEBUG = -DMTR_DEBUG
+MTRDEBUG =
+
+# Loader options.
+LDFLAGS        =
+# This may produce faster code on the DECstations.
+#LDFLAGS       = -jmpopt -Olimit 1000
+# This may be necessary under some old versions of Linux.
+#LDFLAGS       = -static
+# This normally makes the program faster on the DEC Alphas.
+#LDFLAGS       = -non_shared -om
+# This is for 32-bit pointers on the DEC Alphas.
+#LDFLAGS       = -non_shared -om -taso
+#LDFLAGS       = -non_shared -taso
+
+# Define PURE as purify to link with purify.
+# Define PURE as quantify to link with quantify.
+# Remember to compile with -g if you want line-by-line info with quantify.
+PURE =
+#PURE  = purify
+#PURE  = quantify
+
+# Define EXE as .exe for MS-DOS and derivatives.  Not required by recent
+# versions of cygwin.
+EXE    =
+#EXE   = .exe
+
+# End of the configuration section.
+#---------------------------------------------------------------------------
+
+MFLAG   = -DMNEMOSYNE
+MNEMLIB        = ../mnemosyne/libmnem.a
+
+DDWDIR = .
+IDIR   = $(DDWDIR)/include
+INCLUDE = -I$(IDIR)
+
+BDIRS  = cudd dddmp mtr st util epd
+DIRS   = $(BDIRS) nanotrav
+
+#------------------------------------------------------------------------
+
+.PHONY : build
+.PHONY : nanotrav
+.PHONY : check_leaks
+.PHONY : optimize_dec
+.PHONY : testcudd
+.PHONY : libobj
+.PHONY : testobj
+.PHONY : testdddmp
+.PHONY : testmtr
+.PHONY : lint
+.PHONY : all
+.PHONY : clean
+.PHONY : distclean
+
+
+build:
+       sh ./setup.sh
+       @for dir in $(DIRS); do \
+               (cd $$dir; \
+               echo Making $$dir ...; \
+               make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" )\
+       done
+
+nanotrav: build
+
+check_leaks:
+       sh ./setup.sh
+       @for dir in mnemosyne $(DIRS); do \
+               (cd $$dir; \
+               echo Making $$dir ...; \
+               make CC=$(CC) RANLIB=$(RANLIB) MFLAG=$(MFLAG) MNEMLIB=$(MNEMLIB) ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" EXE="$(EXE)" )\
+       done
+
+optimize_dec:
+       sh ./setup.sh
+       @for dir in $(DIRS); do \
+               (cd $$dir; \
+               echo Making $$dir ...; \
+               make CC=$(CC) RANLIB=$(RANLIB) XCFLAGS="$(XCFLAGS)" LDFLAGS="$(LDFLAGS)" optimize_dec )\
+       done
+
+lint:
+       sh ./setup.sh
+       @for dir in $(DIRS) obj; do \
+               (cd $$dir; \
+               echo Making lint in $$dir ...; \
+               make CC=$(CC) lint )\
+       done
+
+tags:
+       sh ./setup.sh
+       @for dir in $(DIRS) obj; do \
+               (cd $$dir; \
+               echo Making tags in $$dir ...; \
+               make CC=$(CC) tags )\
+       done
+
+all:
+       sh ./setup.sh
+       @for dir in $(DIRS); do \
+               (cd $$dir; \
+               echo Making all in $$dir ...; \
+               make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" all )\
+       done
+
+testcudd:
+       sh ./setup.sh
+       @for dir in util st mtr epd; do \
+               (cd $$dir; \
+               echo Making $$dir ...; \
+               make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" )\
+       done
+       @(cd cudd; \
+       echo Making testcudd ...; \
+       make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" testcudd$(EXE) )
+
+objlib:
+       sh ./setup.sh
+       @for dir in $(BDIRS); do \
+               (cd $$dir; \
+               echo Making $$dir ...; \
+               make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" )\
+       done
+       @(cd obj; \
+       echo Making obj ...; \
+       make CPP=$(CPP) CPPFLAGS=$(CPPFLAGS) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" )
+
+testobj: objlib
+       @(cd obj; \
+       echo Making testobj ...; \
+       make CPP=$(CPP) CPPFLAGS=$(CPPFLAGS) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" testobj$(EXE) )
+
+testdddmp: build
+       @(cd dddmp; \
+       echo Making testdddmp ...; \
+       make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" testdddmp$(EXE) )
+
+testmtr: build
+       @(cd mtr; \
+       echo Making testmtr ...; \
+       make CC=$(CC) RANLIB=$(RANLIB) MFLAG= MNEMLIB= ICFLAGS="$(ICFLAGS)" XCFLAGS="$(XCFLAGS)" DDDEBUG="$(DDDEBUG)" MTRDEBUG="$(MTRDEBUG)" LDFLAGS="$(LDFLAGS)" PURE="$(PURE)" EXE="$(EXE)" testmtr$(EXE) )
+
+clean:
+       @for dir in mnemosyne $(DIRS) obj; do   \
+           (cd $$dir;  \
+            echo Cleaning $$dir ...; \
+            make -s clean      ) \
+       done
+
+distclean:
+       @for dir in mnemosyne $(DIRS) obj; do   \
+           (cd $$dir;  \
+            echo Cleaning $$dir ...; \
+            make -s EXE="$(EXE)" distclean     ) \
+       done
+       sh ./shutdown.sh
diff --git a/distr/README b/distr/README
new file mode 100644 (file)
index 0000000..c53383f
--- /dev/null
@@ -0,0 +1,181 @@
+$Id$
+
+This directory contains a set of packages that allow you to build a toy
+application based on the CUDD package.
+
+The CUDD package is a package written in C for the manipulation of
+decision diagrams.  It supports binary decision diagrams (BDDs),
+algebraic decision diagrams (ADDs), and Zero-Suppressed BDDs (ZDDs).
+
+The toy application provided in this kit is called nanotrav and is a
+simple-minded FSM traversal program. (See the README file and the man
+page nanotrav.1 in the nanotrav directory for the details.)  It is
+included so that you can run a sanity check on your installation.
+
+INSTALLATION
+
+Before you build the libraries and programs, you need to check the
+Makefile in the top directory.  Go through the definitions contained in the
+configuration section, and select the desired compiler and compilation
+flags.  Instructions are provided in the comments of the Makefile.
+
+You can always specify the options on the command line.  For instance,
+on some machines you can build a "fast" version of the program by typing:
+
+    make DDDEBUG= MTRDEBUG= ICFLAGS=-O2
+
+The Makefile supports several targets:
+
+    make:
+       Creates a "plain" version of the program.
+
+    make testdddmp:
+       Builds a test program (testdddmp) for BDD loading from and
+       storing to disk. See file README.test in the dddmp directory for
+       how to run the program.
+
+    make testobj:
+       Builds a test program for the C++ interface. Requires a C++
+       compiler. To run the program, run obj/testobj.
+
+    make testcudd:
+       Builds a test program for CUDD. To run the program, go to the
+       cudd directory and type "./testcudd -p 2 r7x8.1.mat". The result
+       can be compared to r7x7.1.out.
+
+    make testmtr:
+        Builds a test program for the mtr package.  To run the program,
+       go to the mtr directory and type "./testmtr -p 1 test.groups".
+    
+    make clean:
+       Cleans directories, but leaves libraries and programs.
+
+    make distclean:
+       Cleans thoroughly, returning the directories to their pristine
+       state.
+
+The following targets are more or less obsolete and may disappear or
+change in the future.
+
+    make check_leaks: 
+       Creates a version of the program with the mnemosyne library
+       linked to it. It also builds the mnemalyse program, which
+       helps in finding memory leaks. This target does not work on the
+       IBM RS6000. The makefile also supports purify. To use purify,
+       set the PURE variable in the Makefile, and use the standard
+       target.
+
+    make optimize_dec:
+       Builds a version of the program using the u-code compiler
+       available on DEC machines (DECstations and Alphas). The newer
+       native compiler on the Alphas does not use u-code, though.
+       Therefore the standard target should be used with it.
+
+    make lint:
+       Runs lint on all subdirectories except mnemosyne. Creates lint
+       libraries for all object libraries.
+
+    make tags:
+       Builds ctags-style tag files for all subdirectories except
+       mnemosyne.
+
+    make all:
+       Makes all of the above, except check_leaks, which is
+       incompatible with a plain "make."
+
+All targets, except clean and distclean, will create the include
+directory if it does not already exist.
+
+The Makefile does not compile the SIS interface (cuddBddPort.c and
+cuddPwPt.c found in subdirectory sis).  To compile the interface, you
+also need array.h and var_set.h, which are not part of this
+distribution, but come with SIS.  Detailed instructions on how to
+integrate the CUDD package in SIS can be found in the documentation
+(cudd/doc).
+
+PLATFORMS
+
+This kit has been successfully built on the following configurations:
+    PC (ia32 and ia64) running Linux RedHat with gcc
+    PC (ia32 and ia64) running Linux RedHat with g++
+    PC (ia32) running Linux RedHat with icc
+    PC (ia32) running Linux RedHat with icpc
+    PC (ia64) running Linux RedHat with ecc
+    PC (ia64) running Linux RedHat with ecpc
+    SUN running Solaris 2.8 with cc
+    SUN running Solaris 2.8 with CC
+    SUN running Solaris 2.8 with gcc
+    SUN running Solaris 2.8 with g++
+
+Platforms to which I have no longer access and therefore are no longer
+supported.
+
+    DECstation running Ultrix with cc
+    DECstation running Ultrix with gcc
+    IBM RS6000 running AIX 3.2.4 with cc (**)
+    IBM RS6000 running AIX 3.2.4 with gcc
+    IBM RS6000 running AIX 3.2.4 with g++
+    SUN running SunOS with gcc
+    DEC Alpha running Digital Unix with cc
+    DEC Alpha running Digital Unix with cxx
+    DEC Alpha running Digital Unix with gcc
+    HP 9000/770 running HP-UX with c89
+    HP 9000/770 running HP-UX with CC
+    HP 9000/770 running HP-UX with gcc
+    HP 9000/770 running HP-UX with g++ (*)
+    SUN running Solaris 2.8 with /usr/ucb/cc
+    PC running Solaris 2.8 with /usr/bin/cc
+    PC running Solaris 2.8 with /usr/ucb/cc
+    PC running Solaris 2.8 with CC
+    PC running Solaris 2.8 with gcc
+    PC running Solaris 2.8 with g++
+
+NOTES
+    (*) C programs were compiled with g++, but linked with gcc.
+
+    (**) Some old versions of the AIX cc compiler have buggy optimizers:
+    Try compiling with -O2 instead of -O3 if the program crashes.
+
+Running lint and compiling with gcc -Wall still produces warnings.
+Running `purify' under Solaris 2.8 generates no messages.
+
+CUDD AND WIN32
+
+This kit has also been built on a PC running Windows98, Windows NT,
+and Windows XP using the Cygnus port of the GNU tools
+(http://www.cygwin.com/.)  This release of CUDD was tested under Windows
+XP with versions 1.5.5-1 of the Cygwin DLL.  Both gcc and g++ were used.
+The time measurement functions do not work under Windows98.  You must have
+bash set up properly for make to work.  See also the instructions in Makefile.
+
+SANITY CHECK
+
+The directory `nanotrav' contains a very simple application based on the
+CUDD package. The `nanotrav' directory contains a man page that
+describes the options nanotrav supports. The files *.blif are sample
+input files for nanotrav.
+
+If you have built the mnemosyne library (make check_leaks), you can do
+    cd mnemosyne
+    make runmtest
+This does not work on machines running SunOS, but the version of
+nanotrav that uses mnemosyne may work.
+
+DOCUMENTATION
+
+Directory cudd-2.4.1/cudd/doc contains HTML documentation for the CUDD
+package. The recommended starting point is cuddIntro.html. Documentation
+in both postscript(tm) format and plain text format is also provided.
+Documentation for the auxiliary libraries (except for the util library)
+is in the doc subdirectories.
+
+FEEDBACK:
+
+Send feedback to:
+
+Fabio Somenzi
+University of Colorado at Boulder
+ECE Dept.
+Boulder, CO 80309-0425
+Fabio@Colorado.EDU
+http://vlsi.colorado.edu/~fabio
diff --git a/distr/RELEASE.NOTES b/distr/RELEASE.NOTES
new file mode 100644 (file)
index 0000000..6eba803
--- /dev/null
@@ -0,0 +1,38 @@
+Release 2.4.2 of Cudd features several bug fixes.  The most important
+are those that prevented Cudd from making full use of up to 4 GB of
+memory when using 32-bit pointers.  A handful of bugs were discovered by
+Coverity.  (Thanks to Christian Stangier!)
+
+This release can be compiled with either 64-bit pointers or 32-bit
+pointers on x86_64 platforms if sizeof(long) = sizeof(void *) = 8 and
+sizeof(int) = 4.  This is known as the LP64 model.  For 32-bit pointers,
+one usually needs supplementary libraries.  On Ubuntu and Debian Linux,
+one needs g++-multilib, which can be installed with
+"apt-get install g++-multilib."
+
+Added functions 
+
+DdNode *Cudd_Inequality (DdManager * dd, int  N, int c, DdNode ** x,
+DdNode ** y);
+
+DdNode * Cudd_Disequality (DdManager * dd, int  N, int c, DdNode ** x,
+DdNode ** y);
+
+DdNode * Cudd_bddInterval (DdManager * dd, int  N, DdNode ** x,
+unsigned int lowerB, unsigned int upperB);
+
+Changed prototypes:
+
+int Cudd_DumpBlif (DdManager *dd, int n, DdNode **f, char
+**inames, char **onames, char *mname, FILE *fp, int mv);
+
+int Cudd_DumpBlifBody (DdManager *dd, int n, DdNode **f, char
+**inames, char **onames, FILE *fp, int mv);
+
+The additional parameter allows the caller to choose between plain blif
+and blif-MV.
+
+----------------------------------------------------------------------
+
+Release 2.4.1 of Cudd features one major change with respect to previous
+releases.  The licensing terms are now explicitly stated.
diff --git a/distr/cudd/Makefile b/distr/cudd/Makefile
new file mode 100644 (file)
index 0000000..bf8ab71
--- /dev/null
@@ -0,0 +1,127 @@
+# $Id$
+#
+#    Cudd - DD package
+#---------------------------
+.SUFFIXES: .o .c .u
+
+CC     = gcc
+RANLIB = ranlib
+PURE   =
+# Define EXE as .exe for MS-DOS and derivatives.
+EXE    =
+#EXE   = .exe
+
+MFLAG  =
+ICFLAGS        = -g
+XCFLAGS        = -DDD_STATS
+CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS)
+#DDDEBUG       = -DDD_DEBUG -DDD_CACHE_PROFILE -DDD_VERBOSE -DDD_UNIQUE_PROFILE
+DDDEBUG        =
+
+LINTFLAGS = -u -n -DDD_STATS -DDD_CACHE_PROFILE -DDD_VERBOSE -DDD_DEBUG -DDD_UNIQUE_PROFILE
+
+# this is to create the lint library
+LINTSWITCH = -o
+
+WHERE  = ..
+
+INCLUDE = $(WHERE)/include
+
+LIBS   = ./libcudd.a $(WHERE)/mtr/libmtr.a \
+       $(WHERE)/st/libst.a $(WHERE)/util/libutil.a $(WHERE)/epd/libepd.a
+
+MNEMLIB =
+
+BLIBS  = -kL. -klcudd -kL$(WHERE)/mtr -klmtr \
+       -kL$(WHERE)/st -klst -kL$(WHERE)/util -klutil -kL$(WHERE)/epd -klepd
+
+LINTLIBS = ./llib-lcudd.ln $(WHERE)/mtr/llib-lmtr.ln \
+       $(WHERE)/st/llib-lst.ln $(WHERE)/util/llib-lutil.ln \
+       $(WHERE)/epd/llib-lepd.ln
+
+LDFLAGS        =
+
+# files for the package
+P      = cudd
+PSRC   = cuddAPI.c cuddAddAbs.c cuddAddApply.c cuddAddFind.c cuddAddIte.c \
+         cuddAddInv.c cuddAddNeg.c cuddAddWalsh.c cuddAndAbs.c \
+         cuddAnneal.c cuddApa.c cuddApprox.c cuddBddAbs.c cuddBddCorr.c \
+         cuddBddIte.c cuddBridge.c cuddCache.c cuddCheck.c cuddClip.c \
+         cuddCof.c cuddCompose.c cuddDecomp.c cuddEssent.c \
+         cuddExact.c cuddExport.c cuddGenCof.c cuddGenetic.c \
+         cuddGroup.c cuddHarwell.c cuddInit.c cuddInteract.c \
+         cuddLCache.c cuddLevelQ.c \
+         cuddLinear.c cuddLiteral.c cuddMatMult.c cuddPriority.c \
+         cuddRead.c cuddRef.c cuddReorder.c cuddSat.c cuddSign.c \
+         cuddSolve.c cuddSplit.c cuddSubsetHB.c cuddSubsetSP.c cuddSymmetry.c \
+         cuddTable.c cuddUtil.c cuddWindow.c cuddZddCount.c cuddZddFuncs.c \
+         cuddZddGroup.c cuddZddIsop.c cuddZddLin.c cuddZddMisc.c \
+         cuddZddPort.c cuddZddReord.c cuddZddSetop.c cuddZddSymm.c \
+         cuddZddUtil.c
+PHDR    = cudd.h cuddInt.h
+POBJ   = $(PSRC:.c=.o)
+PUBJ   = $(PSRC:.c=.u)
+TARGET = test$(P)$(EXE)
+TARGETu = test$(P)-u
+
+# files for the test program
+SRC    = test$(P).c
+OBJ    = $(SRC:.c=.o)
+UBJ    = $(SRC:.c=.u)
+
+#------------------------------------------------------
+
+lib$(P).so: $(POBJ)
+       gcc --shared -o $@ $? $(LIBS)
+lib$(P).a: $(POBJ)
+       ar rv $@ $?
+       $(RANLIB) $@
+
+
+.c.o: $(PSRC) $(PHDR)
+       $(CC) -c  $< -I$(INCLUDE) $(CFLAGS) $(DDDEBUG) 
+
+optimize_dec: lib$(P).b
+
+lib$(P).b: $(PUBJ)
+       ar rv $@ $?
+       $(RANLIB) $@
+
+.c.u: $(PSRC) $(PHDR)
+       cc -j $< -I$(INCLUDE) $(XCFLAGS)
+
+# if the header files change, recompile
+$(POBJ): $(PHDR)
+$(PUBJ): $(PHDR)
+$(OBJ): $(PHDR)
+$(UBJ): $(PHDR)
+
+$(TARGET): $(SRC) $(OBJ) $(HDR) $(LIBS) $(MNEMLIB)
+       $(PURE) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(MNEMLIB) -lm
+
+# optimize (DECstations and Alphas only: uses u-code)
+$(TARGETu): $(SRC) $(UBJ) $(HDR) $(LIBS:.a=.b)
+       $(CC) -O3 -Olimit 1000 $(XCFLAGS) $(LDFLAGS) -o $@ $(UBJ) $(BLIBS) -lm
+
+lint: llib-l$(P).ln
+
+llib-l$(P).ln: $(PSRC) $(PHDR)
+       lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC)
+
+lintpgm: lint
+       lint $(LINTFLAGS) -I$(INCLUDE) $(SRC) $(LINTLIBS)
+
+tags: $(PSRC) $(PHDR)
+       ctags $(PSRC) $(PHDR)
+
+all: lib$(P).a lib$(P).so lib$(P).b llib-l$(P).ln tags
+
+programs: $(TARGET) $(TARGETu) lintpgm
+
+clean:
+       rm -f *.o *.u mon.out gmon.out *.pixie *.Addrs *.Counts mnem.* \
+       .pure core *.warnings
+
+distclean: clean
+       rm -f $(TARGET) $(TARGETu) lib*.a lib$(P).b llib-l$(P).ln \
+       *.bak *~ tags .gdb_history *.qv *.qx
diff --git a/distr/cudd/cudd.h b/distr/cudd/cudd.h
new file mode 100644 (file)
index 0000000..7b005ae
--- /dev/null
@@ -0,0 +1,1053 @@
+/**CHeaderFile*****************************************************************
+
+  FileName    [cudd.h]
+
+  PackageName [cudd]
+
+  Synopsis    [The University of Colorado decision diagram package.]
+
+  Description [External functions and data strucures of the CUDD package.
+  <ul>
+  <li> To turn on the gathering of statistics, define DD_STATS.
+  <li> To link with mis, define DD_MIS.
+  </ul>
+  Modified by Abelardo Pardo to interface it to VIS.
+  ]
+
+  SeeAlso     []
+
+  Author      [Fabio Somenzi]
+
+  Copyright   [Copyright (c) 1995-2004, Regents of the University of Colorado
+
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+  Redistributions of source code must retain the above copyright
+  notice, this list of conditions and the following disclaimer.
+
+  Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in the
+  documentation and/or other materials provided with the distribution.
+
+  Neither the name of the University of Colorado nor the names of its
+  contributors may be used to endorse or promote products derived from
+  this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.]
+
+  Revision    [$Id: cudd.h,v 1.174 2009/02/21 05:55:18 fabio Exp $]
+
+******************************************************************************/
+
+#ifndef _CUDD
+#define _CUDD
+
+/*---------------------------------------------------------------------------*/
+/* Nested includes                                                           */
+/*---------------------------------------------------------------------------*/
+
+#include "mtr.h"
+#include "epd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* Constant declarations                                                     */
+/*---------------------------------------------------------------------------*/
+
+#define CUDD_VERSION "2.4.2"
+
+#ifndef SIZEOF_VOID_P
+#define SIZEOF_VOID_P 4
+#endif
+#ifndef SIZEOF_INT
+#define SIZEOF_INT 4
+#endif
+#ifndef SIZEOF_LONG
+#define SIZEOF_LONG 4
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define CUDD_VALUE_TYPE                double
+#define CUDD_OUT_OF_MEM                -1
+/* The sizes of the subtables and the cache must be powers of two. */
+#define CUDD_UNIQUE_SLOTS      256     /* initial size of subtables */
+#define CUDD_CACHE_SLOTS       262144  /* default size of the cache */
+
+/* Constants for residue functions. */
+#define CUDD_RESIDUE_DEFAULT   0
+#define CUDD_RESIDUE_MSB       1
+#define CUDD_RESIDUE_TC                2
+
+/* CUDD_MAXINDEX is defined in such a way that on 32-bit and 64-bit
+** machines one can cast an index to (int) without generating a negative
+** number.
+*/
+#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
+#define CUDD_MAXINDEX          (((DdHalfWord) ~0) >> 1)
+#else
+#define CUDD_MAXINDEX          ((DdHalfWord) ~0)
+#endif
+
+/* CUDD_CONST_INDEX is the index of constant nodes.  Currently this
+** is a synonim for CUDD_MAXINDEX. */
+#define CUDD_CONST_INDEX       CUDD_MAXINDEX
+
+/* These constants define the digits used in the representation of
+** arbitrary precision integers.  The configurations tested use 8, 16,
+** and 32 bits for each digit.  The typedefs should be in agreement
+** with these definitions.
+*/
+#if SIZEOF_LONG == 8
+#define DD_APA_BITS    32
+#define DD_APA_BASE    (1L << DD_APA_BITS)
+#define DD_APA_HEXPRINT        "%08x"
+#else
+#define DD_APA_BITS    16
+#define DD_APA_BASE    (1 << DD_APA_BITS)
+#define DD_APA_HEXPRINT        "%04x"
+#endif
+#define DD_APA_MASK    (DD_APA_BASE - 1)
+
+/*---------------------------------------------------------------------------*/
+/* Stucture declarations                                                     */
+/*---------------------------------------------------------------------------*/
+
+
+/*---------------------------------------------------------------------------*/
+/* Type declarations                                                         */
+/*---------------------------------------------------------------------------*/
+
+/**Enum************************************************************************
+
+  Synopsis    [Type of reordering algorithm.]
+
+  Description [Type of reordering algorithm.]
+
+******************************************************************************/
+typedef enum {
+    CUDD_REORDER_SAME,
+    CUDD_REORDER_NONE,
+    CUDD_REORDER_RANDOM,
+    CUDD_REORDER_RANDOM_PIVOT,
+    CUDD_REORDER_SIFT,
+    CUDD_REORDER_SIFT_CONVERGE,
+    CUDD_REORDER_SYMM_SIFT,
+    CUDD_REORDER_SYMM_SIFT_CONV,
+    CUDD_REORDER_WINDOW2,
+    CUDD_REORDER_WINDOW3,
+    CUDD_REORDER_WINDOW4,
+    CUDD_REORDER_WINDOW2_CONV,
+    CUDD_REORDER_WINDOW3_CONV,
+    CUDD_REORDER_WINDOW4_CONV,
+    CUDD_REORDER_GROUP_SIFT,
+    CUDD_REORDER_GROUP_SIFT_CONV,
+    CUDD_REORDER_ANNEALING,
+    CUDD_REORDER_GENETIC,
+    CUDD_REORDER_LINEAR,
+    CUDD_REORDER_LINEAR_CONVERGE,
+    CUDD_REORDER_LAZY_SIFT,
+    CUDD_REORDER_EXACT
+} Cudd_ReorderingType;
+
+
+/**Enum************************************************************************
+
+  Synopsis    [Type of aggregation methods.]
+
+  Description [Type of aggregation methods.]
+
+******************************************************************************/
+typedef enum {
+    CUDD_NO_CHECK,
+    CUDD_GROUP_CHECK,
+    CUDD_GROUP_CHECK2,
+    CUDD_GROUP_CHECK3,
+    CUDD_GROUP_CHECK4,
+    CUDD_GROUP_CHECK5,
+    CUDD_GROUP_CHECK6,
+    CUDD_GROUP_CHECK7,
+    CUDD_GROUP_CHECK8,
+    CUDD_GROUP_CHECK9
+} Cudd_AggregationType;
+
+
+/**Enum************************************************************************
+
+  Synopsis    [Type of hooks.]
+
+  Description [Type of hooks.]
+
+******************************************************************************/
+typedef enum {
+    CUDD_PRE_GC_HOOK,
+    CUDD_POST_GC_HOOK,
+    CUDD_PRE_REORDERING_HOOK,
+    CUDD_POST_REORDERING_HOOK
+} Cudd_HookType;
+
+
+/**Enum************************************************************************
+
+  Synopsis    [Type of error codes.]
+
+  Description [Type of  error codes.]
+
+******************************************************************************/
+typedef enum {
+    CUDD_NO_ERROR,
+    CUDD_MEMORY_OUT,
+    CUDD_TOO_MANY_NODES,
+    CUDD_MAX_MEM_EXCEEDED,
+    CUDD_INVALID_ARG,
+    CUDD_INTERNAL_ERROR
+} Cudd_ErrorType;
+
+
+/**Enum************************************************************************
+
+  Synopsis    [Group type for lazy sifting.]
+
+  Description [Group type for lazy sifting.]
+
+******************************************************************************/
+typedef enum {
+    CUDD_LAZY_NONE,
+    CUDD_LAZY_SOFT_GROUP,
+    CUDD_LAZY_HARD_GROUP,
+    CUDD_LAZY_UNGROUP
+} Cudd_LazyGroupType;
+
+
+/**Enum************************************************************************
+
+  Synopsis    [Variable type.]
+
+  Description [Variable type. Currently used only in lazy sifting.]
+
+******************************************************************************/
+typedef enum {
+    CUDD_VAR_PRIMARY_INPUT,
+    CUDD_VAR_PRESENT_STATE,
+    CUDD_VAR_NEXT_STATE
+} Cudd_VariableType;
+
+
+#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
+typedef unsigned int   DdHalfWord;
+#else
+typedef unsigned short DdHalfWord;
+#endif
+
+#ifdef __osf__
+#pragma pointer_size save
+#pragma pointer_size short
+#endif
+
+typedef struct DdNode DdNode;
+
+typedef struct DdChildren {
+    struct DdNode *T;
+    struct DdNode *E;
+} DdChildren;
+
+/* The DdNode structure is the only one exported out of the package */
+struct DdNode {
+    DdHalfWord index;
+    DdHalfWord ref;            /* reference count */
+    DdNode *next;              /* next pointer for unique table */
+    union {
+       CUDD_VALUE_TYPE value;  /* for constant nodes */
+       DdChildren kids;        /* for internal nodes */
+    } type;
+};
+
+#ifdef __osf__
+#pragma pointer_size restore
+#endif
+
+typedef struct DdManager DdManager;
+
+typedef struct DdGen DdGen;
+
+/* These typedefs for arbitrary precision arithmetic should agree with
+** the corresponding constant definitions above. */
+#if SIZEOF_LONG == 8
+typedef unsigned int DdApaDigit;
+typedef unsigned long int DdApaDoubleDigit;
+#else
+typedef unsigned short int DdApaDigit;
+typedef unsigned int DdApaDoubleDigit;
+#endif
+typedef DdApaDigit * DdApaNumber;
+
+/* Return type for function computing two-literal clauses. */
+typedef struct DdTlcInfo DdTlcInfo;
+
+/* Type of hook function. */
+typedef int (*DD_HFP)(DdManager *, const char *, void *);
+/* Type of priority function */
+typedef DdNode * (*DD_PRFP)(DdManager * , int, DdNode **, DdNode **,
+                           DdNode **);
+/* Type of apply operator. */
+typedef DdNode * (*DD_AOP)(DdManager *, DdNode **, DdNode **);
+/* Type of monadic apply operator. */
+typedef DdNode * (*DD_MAOP)(DdManager *, DdNode *);
+/* Types of cache tag functions. */
+typedef DdNode * (*DD_CTFP)(DdManager *, DdNode *, DdNode *);
+typedef DdNode * (*DD_CTFP1)(DdManager *, DdNode *);
+/* Type of memory-out function. */
+typedef void (*DD_OOMFP)(long);
+/* Type of comparison function for qsort. */
+typedef int (*DD_QSFP)(const void *, const void *);
+
+/*---------------------------------------------------------------------------*/
+/* Variable declarations                                                     */
+/*---------------------------------------------------------------------------*/
+
+
+/*---------------------------------------------------------------------------*/
+/* Macro declarations                                                        */
+/*---------------------------------------------------------------------------*/
+
+
+/**Macro***********************************************************************
+
+  Synopsis     [Returns 1 if the node is a constant node.]
+
+  Description  [Returns 1 if the node is a constant node (rather than an
+  internal node). All constant nodes have the same index
+  (CUDD_CONST_INDEX). The pointer passed to Cudd_IsConstant may be either
+  regular or complemented.]
+
+  SideEffects  [none]
+
+  SeeAlso      []
+
+******************************************************************************/
+#define Cudd_IsConstant(node) ((Cudd_Regular(node))->index == CUDD_CONST_INDEX)
+
+
+/**Macro***********************************************************************
+
+  Synopsis     [Complements a DD.]
+
+  Description  [Complements a DD by flipping the complement attribute of
+  the pointer (the least significant bit).]
+
+  SideEffects  [none]
+
+  SeeAlso      [Cudd_NotCond]
+
+******************************************************************************/
+#define Cudd_Not(node) ((DdNode *)((long)(node) ^ 01))
+
+
+/**Macro***********************************************************************
+
+  Synopsis     [Complements a DD if a condition is true.]
+
+  Description  [Complements a DD if condition c is true; c should be
+  either 0 or 1, because it is used directly (for efficiency). If in
+  doubt on the values c may take, use "(c) ? Cudd_Not(node) : node".]
+
+  SideEffects  [none]
+
+  SeeAlso      [Cudd_Not]
+
+******************************************************************************/
+#define Cudd_NotCond(node,c) ((DdNode *)((long)(node) ^ (c)))
+
+
+/**Macro***********************************************************************
+
+  Synopsis     [Returns the regular version of a pointer.]
+
+  Description  []
+
+  SideEffects  [none]
+
+  SeeAlso      [Cudd_Complement Cudd_IsComplement]
+
+******************************************************************************/
+#define Cudd_Regular(node) ((DdNode *)((unsigned long)(node) & ~01))
+
+
+/**Macro***********************************************************************
+
+  Synopsis     [Returns the complemented version of a pointer.]
+
+  Description  []
+
+  SideEffects  [none]
+
+  SeeAlso      [Cudd_Regular Cudd_IsComplement]
+
+******************************************************************************/
+#define Cudd_Complement(node) ((DdNode *)((unsigned long)(node) | 01))
+
+
+/**Macro***********************************************************************
+
+  Synopsis     [Returns 1 if a pointer is complemented.]
+
+  Description  []
+
+  SideEffects  [none]
+
+  SeeAlso      [Cudd_Regular Cudd_Complement]
+
+******************************************************************************/
+#define Cudd_IsComplement(node)        ((int) ((long) (node) & 01))
+
+
+/**Macro***********************************************************************
+
+  Synopsis     [Returns the then child of an internal node.]
+
+  Description  [Returns the then child of an internal node. If
+  <code>node</code> is a constant node, the result is unpredictable.]
+
+  SideEffects  [none]
+
+  SeeAlso      [Cudd_E Cudd_V]
+
+******************************************************************************/
+#define Cudd_T(node) ((Cudd_Regular(node))->type.kids.T)
+
+
+/**Macro***********************************************************************
+
+  Synopsis     [Returns the else child of an internal node.]
+
+  Description  [Returns the else child of an internal node. If
+  <code>node</code> is a constant node, the result is unpredictable.]
+
+  SideEffects  [none]
+
+  SeeAlso      [Cudd_T Cudd_V]
+
+******************************************************************************/
+#define Cudd_E(node) ((Cudd_Regular(node))->type.kids.E)
+
+
+/**Macro***********************************************************************
+
+  Synopsis     [Returns the value of a constant node.]
+
+  Description  [Returns the value of a constant node. If
+  <code>node</code> is an internal node, the result is unpredictable.]
+
+  SideEffects  [none]
+
+  SeeAlso      [Cudd_T Cudd_E]
+
+******************************************************************************/
+#define Cudd_V(node) ((Cudd_Regular(node))->type.value)
+
+
+/**Macro***********************************************************************
+
+  Synopsis     [Returns the current position in the order of variable
+  index.]
+
+  Description [Returns the current position in the order of variable
+  index. This macro is obsolete and is kept for compatibility. New
+  applications should use Cudd_ReadPerm instead.]
+
+  SideEffects  [none]
+
+  SeeAlso      [Cudd_ReadPerm]
+
+******************************************************************************/
+#define Cudd_ReadIndex(dd,index) (Cudd_ReadPerm(dd,index))
+
+
+/**Macro***********************************************************************
+
+  Synopsis     [Iterates over the cubes of a decision diagram.]
+
+  Description  [Iterates over the cubes of a decision diagram f.
+  <ul>
+  <li> DdManager *manager;
+  <li> DdNode *f;
+  <li> DdGen *gen;
+  <li> int *cube;
+  <li> CUDD_VALUE_TYPE value;
+  </ul>
+  Cudd_ForeachCube allocates and frees the generator. Therefore the
+  application should not try to do that. Also, the cube is freed at the
+  end of Cudd_ForeachCube and hence is not available outside of the loop.<p>
+  CAUTION: It is assumed that dynamic reordering will not occur while
+  there are open generators. It is the user's responsibility to make sure
+  that dynamic reordering does not occur. As long as new nodes are not created
+  during generation, and dynamic reordering is not called explicitly,
+  dynamic reordering will not occur. Alternatively, it is sufficient to
+  disable dynamic reordering. It is a mistake to dispose of a diagram
+  on which generation is ongoing.]
+
+  SideEffects  [none]
+
+  SeeAlso      [Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube Cudd_GenFree
+  Cudd_IsGenEmpty Cudd_AutodynDisable]
+
+******************************************************************************/
+#define Cudd_ForeachCube(manager, f, gen, cube, value)\
+    for((gen) = Cudd_FirstCube(manager, f, &cube, &value);\
+       Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\
+       (void) Cudd_NextCube(gen, &cube, &value))
+
+
+/**Macro***********************************************************************
+
+  Synopsis     [Iterates over the primes of a Boolean function.]
+
+  Description  [Iterates over the primes of a Boolean function producing
+  a prime and irredundant cover.
+  <ul>
+  <li> DdManager *manager;
+  <li> DdNode *l;
+  <li> DdNode *u;
+  <li> DdGen *gen;
+  <li> int *cube;
+  </ul>
+  The Boolean function is described by an upper bound and a lower bound.  If
+  the function is completely specified, the two bounds coincide.
+  Cudd_ForeachPrime allocates and frees the generator.  Therefore the
+  application should not try to do that.  Also, the cube is freed at the
+  end of Cudd_ForeachPrime and hence is not available outside of the loop.<p>
+  CAUTION: It is a mistake to change a diagram on which generation is ongoing.]
+
+  SideEffects  [none]
+
+  SeeAlso      [Cudd_ForeachCube Cudd_FirstPrime Cudd_NextPrime Cudd_GenFree
+  Cudd_IsGenEmpty]
+
+******************************************************************************/
+#define Cudd_ForeachPrime(manager, l, u, gen, cube)\
+    for((gen) = Cudd_FirstPrime(manager, l, u, &cube);\
+       Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\
+       (void) Cudd_NextPrime(gen, &cube))
+
+
+/**Macro***********************************************************************
+
+  Synopsis     [Iterates over the nodes of a decision diagram.]
+
+  Description  [Iterates over the nodes of a decision diagram f.
+  <ul>
+  <li> DdManager *manager;
+  <li> DdNode *f;
+  <li> DdGen *gen;
+  <li> DdNode *node;
+  </ul>
+  The nodes are returned in a seemingly random order.
+  Cudd_ForeachNode allocates and frees the generator. Therefore the
+  application should not try to do that.<p>
+  CAUTION: It is assumed that dynamic reordering will not occur while
+  there are open generators. It is the user's responsibility to make sure
+  that dynamic reordering does not occur. As long as new nodes are not created
+  during generation, and dynamic reordering is not called explicitly,
+  dynamic reordering will not occur. Alternatively, it is sufficient to
+  disable dynamic reordering. It is a mistake to dispose of a diagram
+  on which generation is ongoing.]
+
+  SideEffects  [none]
+
+  SeeAlso      [Cudd_ForeachCube Cudd_FirstNode Cudd_NextNode Cudd_GenFree
+  Cudd_IsGenEmpty Cudd_AutodynDisable]
+
+******************************************************************************/
+#define Cudd_ForeachNode(manager, f, gen, node)\
+    for((gen) = Cudd_FirstNode(manager, f, &node);\
+       Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\
+       (void) Cudd_NextNode(gen, &node))
+
+
+/**Macro***********************************************************************
+
+  Synopsis     [Iterates over the paths of a ZDD.]
+
+  Description  [Iterates over the paths of a ZDD f.
+  <ul>
+  <li> DdManager *manager;
+  <li> DdNode *f;
+  <li> DdGen *gen;
+  <li> int *path;
+  </ul>
+  Cudd_zddForeachPath allocates and frees the generator. Therefore the
+  application should not try to do that. Also, the path is freed at the
+  end of Cudd_zddForeachPath and hence is not available outside of the loop.<p>
+  CAUTION: It is assumed that dynamic reordering will not occur while
+  there are open generators.  It is the user's responsibility to make sure
+  that dynamic reordering does not occur.  As long as new nodes are not created
+  during generation, and dynamic reordering is not called explicitly,
+  dynamic reordering will not occur.  Alternatively, it is sufficient to
+  disable dynamic reordering.  It is a mistake to dispose of a diagram
+  on which generation is ongoing.]
+
+  SideEffects  [none]
+
+  SeeAlso      [Cudd_zddFirstPath Cudd_zddNextPath Cudd_GenFree
+  Cudd_IsGenEmpty Cudd_AutodynDisable]
+
+******************************************************************************/
+#define Cudd_zddForeachPath(manager, f, gen, path)\
+    for((gen) = Cudd_zddFirstPath(manager, f, &path);\
+       Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\
+       (void) Cudd_zddNextPath(gen, &path))
+
+
+
+/**AutomaticStart*************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* Function prototypes                                                       */
+/*---------------------------------------------------------------------------*/
+
+extern DdNode * Cudd_addNewVar (DdManager *dd);
+extern DdNode * Cudd_addNewVarAtLevel (DdManager *dd, int level);
+extern DdNode * Cudd_bddNewVar (DdManager *dd);
+extern DdNode * Cudd_bddNewVarAtLevel (DdManager *dd, int level);
+extern DdNode * Cudd_addIthVar (DdManager *dd, int i);
+extern DdNode * Cudd_bddIthVar (DdManager *dd, int i);
+extern DdNode * Cudd_zddIthVar (DdManager *dd, int i);
+extern int Cudd_zddVarsFromBddVars (DdManager *dd, int multiplicity);
+extern DdNode * Cudd_addConst (DdManager *dd, CUDD_VALUE_TYPE c);
+extern int Cudd_IsNonConstant (DdNode *f);
+extern void Cudd_AutodynEnable (DdManager *unique, Cudd_ReorderingType method);
+extern void Cudd_AutodynDisable (DdManager *unique);
+extern int Cudd_ReorderingStatus (DdManager *unique, Cudd_ReorderingType *method);
+extern void Cudd_AutodynEnableZdd (DdManager *unique, Cudd_ReorderingType method);
+extern void Cudd_AutodynDisableZdd (DdManager *unique);
+extern int Cudd_ReorderingStatusZdd (DdManager *unique, Cudd_ReorderingType *method);
+extern int Cudd_zddRealignmentEnabled (DdManager *unique);
+extern void Cudd_zddRealignEnable (DdManager *unique);
+extern void Cudd_zddRealignDisable (DdManager *unique);
+extern int Cudd_bddRealignmentEnabled (DdManager *unique);
+extern void Cudd_bddRealignEnable (DdManager *unique);
+extern void Cudd_bddRealignDisable (DdManager *unique);
+extern DdNode * Cudd_ReadOne (DdManager *dd);
+extern DdNode * Cudd_ReadZddOne (DdManager *dd, int i);
+extern DdNode * Cudd_ReadZero (DdManager *dd);
+extern DdNode * Cudd_ReadLogicZero (DdManager *dd);
+extern DdNode * Cudd_ReadPlusInfinity (DdManager *dd);
+extern DdNode * Cudd_ReadMinusInfinity (DdManager *dd);
+extern DdNode * Cudd_ReadBackground (DdManager *dd);
+extern void Cudd_SetBackground (DdManager *dd, DdNode *bck);
+extern unsigned int Cudd_ReadCacheSlots (DdManager *dd);
+extern double Cudd_ReadCacheUsedSlots (DdManager * dd);
+extern double Cudd_ReadCacheLookUps (DdManager *dd);
+extern double Cudd_ReadCacheHits (DdManager *dd);
+extern double Cudd_ReadRecursiveCalls (DdManager * dd);
+extern unsigned int Cudd_ReadMinHit (DdManager *dd);
+extern void Cudd_SetMinHit (DdManager *dd, unsigned int hr);
+extern unsigned int Cudd_ReadLooseUpTo (DdManager *dd);
+extern void Cudd_SetLooseUpTo (DdManager *dd, unsigned int lut);
+extern unsigned int Cudd_ReadMaxCache (DdManager *dd);
+extern unsigned int Cudd_ReadMaxCacheHard (DdManager *dd);
+extern void Cudd_SetMaxCacheHard (DdManager *dd, unsigned int mc);
+extern int Cudd_ReadSize (DdManager *dd);
+extern int Cudd_ReadZddSize (DdManager *dd);
+extern unsigned int Cudd_ReadSlots (DdManager *dd);
+extern double Cudd_ReadUsedSlots (DdManager * dd);
+extern double Cudd_ExpectedUsedSlots (DdManager * dd);
+extern unsigned int Cudd_ReadKeys (DdManager *dd);
+extern unsigned int Cudd_ReadDead (DdManager *dd);
+extern unsigned int Cudd_ReadMinDead (DdManager *dd);
+extern int Cudd_ReadReorderings (DdManager *dd);
+extern long Cudd_ReadReorderingTime (DdManager * dd);
+extern int Cudd_ReadGarbageCollections (DdManager * dd);
+extern long Cudd_ReadGarbageCollectionTime (DdManager * dd);
+extern double Cudd_ReadNodesFreed (DdManager * dd);
+extern double Cudd_ReadNodesDropped (DdManager * dd);
+extern double Cudd_ReadUniqueLookUps (DdManager * dd);
+extern double Cudd_ReadUniqueLinks (DdManager * dd);
+extern int Cudd_ReadSiftMaxVar (DdManager *dd);
+extern void Cudd_SetSiftMaxVar (DdManager *dd, int smv);
+extern int Cudd_ReadSiftMaxSwap (DdManager *dd);
+extern void Cudd_SetSiftMaxSwap (DdManager *dd, int sms);
+extern double Cudd_ReadMaxGrowth (DdManager *dd);
+extern void Cudd_SetMaxGrowth (DdManager *dd, double mg);
+extern double Cudd_ReadMaxGrowthAlternate (DdManager * dd);
+extern void Cudd_SetMaxGrowthAlternate (DdManager * dd, double mg);
+extern int Cudd_ReadReorderingCycle (DdManager * dd);
+extern void Cudd_SetReorderingCycle (DdManager * dd, int cycle);
+extern MtrNode * Cudd_ReadTree (DdManager *dd);
+extern void Cudd_SetTree (DdManager *dd, MtrNode *tree);
+extern void Cudd_FreeTree (DdManager *dd);
+extern MtrNode * Cudd_ReadZddTree (DdManager *dd);
+extern void Cudd_SetZddTree (DdManager *dd, MtrNode *tree);
+extern void Cudd_FreeZddTree (DdManager *dd);
+extern unsigned int Cudd_NodeReadIndex (DdNode *node);
+extern int Cudd_ReadPerm (DdManager *dd, int i);
+extern int Cudd_ReadPermZdd (DdManager *dd, int i);
+extern int Cudd_ReadInvPerm (DdManager *dd, int i);
+extern int Cudd_ReadInvPermZdd (DdManager *dd, int i);
+extern DdNode * Cudd_ReadVars (DdManager *dd, int i);
+extern CUDD_VALUE_TYPE Cudd_ReadEpsilon (DdManager *dd);
+extern void Cudd_SetEpsilon (DdManager *dd, CUDD_VALUE_TYPE ep);
+extern Cudd_AggregationType Cudd_ReadGroupcheck (DdManager *dd);
+extern void Cudd_SetGroupcheck (DdManager *dd, Cudd_AggregationType gc);
+extern int Cudd_GarbageCollectionEnabled (DdManager *dd);
+extern void Cudd_EnableGarbageCollection (DdManager *dd);
+extern void Cudd_DisableGarbageCollection (DdManager *dd);
+extern int Cudd_DeadAreCounted (DdManager *dd);
+extern void Cudd_TurnOnCountDead (DdManager *dd);
+extern void Cudd_TurnOffCountDead (DdManager *dd);
+extern int Cudd_ReadRecomb (DdManager *dd);
+extern void Cudd_SetRecomb (DdManager *dd, int recomb);
+extern int Cudd_ReadSymmviolation (DdManager *dd);
+extern void Cudd_SetSymmviolation (DdManager *dd, int symmviolation);
+extern int Cudd_ReadArcviolation (DdManager *dd);
+extern void Cudd_SetArcviolation (DdManager *dd, int arcviolation);
+extern int Cudd_ReadPopulationSize (DdManager *dd);
+extern void Cudd_SetPopulationSize (DdManager *dd, int populationSize);
+extern int Cudd_ReadNumberXovers (DdManager *dd);
+extern void Cudd_SetNumberXovers (DdManager *dd, int numberXovers);
+extern unsigned long Cudd_ReadMemoryInUse (DdManager *dd);
+extern int Cudd_PrintInfo (DdManager *dd, FILE *fp);
+extern long Cudd_ReadPeakNodeCount (DdManager *dd);
+extern int Cudd_ReadPeakLiveNodeCount (DdManager * dd);
+extern long Cudd_ReadNodeCount (DdManager *dd);
+extern long Cudd_zddReadNodeCount (DdManager *dd);
+extern int Cudd_AddHook (DdManager *dd, DD_HFP f, Cudd_HookType where);
+extern int Cudd_RemoveHook (DdManager *dd, DD_HFP f, Cudd_HookType where);
+extern int Cudd_IsInHook (DdManager * dd, DD_HFP f, Cudd_HookType where);
+extern int Cudd_StdPreReordHook (DdManager *dd, const char *str, void *data);
+extern int Cudd_StdPostReordHook (DdManager *dd, const char *str, void *data);
+extern int Cudd_EnableReorderingReporting (DdManager *dd);
+extern int Cudd_DisableReorderingReporting (DdManager *dd);
+extern int Cudd_ReorderingReporting (DdManager *dd);
+extern Cudd_ErrorType Cudd_ReadErrorCode (DdManager *dd);
+extern void Cudd_ClearErrorCode (DdManager *dd);
+extern FILE * Cudd_ReadStdout (DdManager *dd);
+extern void Cudd_SetStdout (DdManager *dd, FILE *fp);
+extern FILE * Cudd_ReadStderr (DdManager *dd);
+extern void Cudd_SetStderr (DdManager *dd, FILE *fp);
+extern unsigned int Cudd_ReadNextReordering (DdManager *dd);
+extern void Cudd_SetNextReordering (DdManager *dd, unsigned int next);
+extern double Cudd_ReadSwapSteps (DdManager *dd);
+extern unsigned int Cudd_ReadMaxLive (DdManager *dd);
+extern void Cudd_SetMaxLive (DdManager *dd, unsigned int maxLive);
+extern unsigned long Cudd_ReadMaxMemory (DdManager *dd);
+extern void Cudd_SetMaxMemory (DdManager *dd, unsigned long maxMemory);
+extern int Cudd_bddBindVar (DdManager *dd, int index);
+extern int Cudd_bddUnbindVar (DdManager *dd, int index);
+extern int Cudd_bddVarIsBound (DdManager *dd, int index);
+extern DdNode * Cudd_addExistAbstract (DdManager *manager, DdNode *f, DdNode *cube);
+extern DdNode * Cudd_addUnivAbstract (DdManager *manager, DdNode *f, DdNode *cube);
+extern DdNode * Cudd_addOrAbstract (DdManager *manager, DdNode *f, DdNode *cube);
+extern DdNode * Cudd_addApply (DdManager *dd, DdNode * (*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g);
+extern DdNode * Cudd_addPlus (DdManager *dd, DdNode **f, DdNode **g);
+extern DdNode * Cudd_addTimes (DdManager *dd, DdNode **f, DdNode **g);
+extern DdNode * Cudd_addThreshold (DdManager *dd, DdNode **f, DdNode **g);
+extern DdNode * Cudd_addSetNZ (DdManager *dd, DdNode **f, DdNode **g);
+extern DdNode * Cudd_addDivide (DdManager *dd, DdNode **f, DdNode **g);
+extern DdNode * Cudd_addMinus (DdManager *dd, DdNode **f, DdNode **g);
+extern DdNode * Cudd_addMinimum (DdManager *dd, DdNode **f, DdNode **g);
+extern DdNode * Cudd_addMaximum (DdManager *dd, DdNode **f, DdNode **g);
+extern DdNode * Cudd_addOneZeroMaximum (DdManager *dd, DdNode **f, DdNode **g);
+extern DdNode * Cudd_addDiff (DdManager *dd, DdNode **f, DdNode **g);
+extern DdNode * Cudd_addAgreement (DdManager *dd, DdNode **f, DdNode **g);
+extern DdNode * Cudd_addOr (DdManager *dd, DdNode **f, DdNode **g);
+extern DdNode * Cudd_addNand (DdManager *dd, DdNode **f, DdNode **g);
+extern DdNode * Cudd_addNor (DdManager *dd, DdNode **f, DdNode **g);
+extern DdNode * Cudd_addXor (DdManager *dd, DdNode **f, DdNode **g);
+extern DdNode * Cudd_addXnor (DdManager *dd, DdNode **f, DdNode **g);
+extern DdNode * Cudd_addMonadicApply (DdManager * dd, DdNode * (*op)(DdManager *, DdNode *), DdNode * f);
+extern DdNode * Cudd_addLog (DdManager * dd, DdNode * f);
+extern DdNode * Cudd_addFindMax (DdManager *dd, DdNode *f);
+extern DdNode * Cudd_addFindMin (DdManager *dd, DdNode *f);
+extern DdNode * Cudd_addIthBit (DdManager *dd, DdNode *f, int bit);
+extern DdNode * Cudd_addScalarInverse (DdManager *dd, DdNode *f, DdNode *epsilon);
+extern DdNode * Cudd_addIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h);
+extern DdNode * Cudd_addIteConstant (DdManager *dd, DdNode *f, DdNode *g, DdNode *h);
+extern DdNode * Cudd_addEvalConst (DdManager *dd, DdNode *f, DdNode *g);
+extern int Cudd_addLeq (DdManager * dd, DdNode * f, DdNode * g);
+extern DdNode * Cudd_addCmpl (DdManager *dd, DdNode *f);
+extern DdNode * Cudd_addNegate (DdManager *dd, DdNode *f);
+extern DdNode * Cudd_addRoundOff (DdManager *dd, DdNode *f, int N);
+extern DdNode * Cudd_addWalsh (DdManager *dd, DdNode **x, DdNode **y, int n);
+extern DdNode * Cudd_addResidue (DdManager *dd, int n, int m, int options, int top);
+extern DdNode * Cudd_bddAndAbstract (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube);
+extern DdNode * Cudd_bddAndAbstractLimit (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, unsigned int limit);
+extern int Cudd_ApaNumberOfDigits (int binaryDigits);
+extern DdApaNumber Cudd_NewApaNumber (int digits);
+extern void Cudd_ApaCopy (int digits, DdApaNumber source, DdApaNumber dest);
+extern DdApaDigit Cudd_ApaAdd (int digits, DdApaNumber a, DdApaNumber b, DdApaNumber sum);
+extern DdApaDigit Cudd_ApaSubtract (int digits, DdApaNumber a, DdApaNumber b, DdApaNumber diff);
+extern DdApaDigit Cudd_ApaShortDivision (int digits, DdApaNumber dividend, DdApaDigit divisor, DdApaNumber quotient);
+extern unsigned int Cudd_ApaIntDivision (int  digits, DdApaNumber dividend, unsigned int  divisor, DdApaNumber  quotient);
+extern void Cudd_ApaShiftRight (int digits, DdApaDigit in, DdApaNumber a, DdApaNumber b);
+extern void Cudd_ApaSetToLiteral (int digits, DdApaNumber number, DdApaDigit literal);
+extern void Cudd_ApaPowerOfTwo (int digits, DdApaNumber number, int power);
+extern int Cudd_ApaCompare (int digitsFirst, DdApaNumber  first, int digitsSecond, DdApaNumber  second);
+extern int Cudd_ApaCompareRatios (int digitsFirst, DdApaNumber firstNum, unsigned int firstDen, int digitsSecond, DdApaNumber secondNum, unsigned int secondDen);
+extern int Cudd_ApaPrintHex (FILE *fp, int digits, DdApaNumber number);
+extern int Cudd_ApaPrintDecimal (FILE *fp, int digits, DdApaNumber number);
+extern int Cudd_ApaPrintExponential (FILE * fp, int  digits, DdApaNumber  number, int precision);
+extern DdApaNumber Cudd_ApaCountMinterm (DdManager *manager, DdNode *node, int nvars, int *digits);
+extern int Cudd_ApaPrintMinterm (FILE *fp, DdManager *dd, DdNode *node, int nvars);
+extern int Cudd_ApaPrintMintermExp (FILE * fp, DdManager * dd, DdNode * node, int  nvars, int precision);
+extern int Cudd_ApaPrintDensity (FILE * fp, DdManager * dd, DdNode * node, int  nvars);
+extern DdNode * Cudd_UnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality);
+extern DdNode * Cudd_OverApprox (DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality);
+extern DdNode * Cudd_RemapUnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, double quality);
+extern DdNode * Cudd_RemapOverApprox (DdManager *dd, DdNode *f, int numVars, int threshold, double quality);
+extern DdNode * Cudd_BiasedUnderApprox (DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0);
+extern DdNode * Cudd_BiasedOverApprox (DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0);
+extern DdNode * Cudd_bddExistAbstract (DdManager *manager, DdNode *f, DdNode *cube);
+extern DdNode * Cudd_bddXorExistAbstract (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube);
+extern DdNode * Cudd_bddUnivAbstract (DdManager *manager, DdNode *f, DdNode *cube);
+extern DdNode * Cudd_bddBooleanDiff (DdManager *manager, DdNode *f, int x);
+extern int Cudd_bddVarIsDependent (DdManager *dd, DdNode *f, DdNode *var);
+extern double Cudd_bddCorrelation (DdManager *manager, DdNode *f, DdNode *g);
+extern double Cudd_bddCorrelationWeights (DdManager *manager, DdNode *f, DdNode *g, double *prob);
+extern DdNode * Cudd_bddIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h);
+extern DdNode * Cudd_bddIteConstant (DdManager *dd, DdNode *f, DdNode *g, DdNode *h);
+extern DdNode * Cudd_bddIntersect (DdManager *dd, DdNode *f, DdNode *g);
+extern DdNode * Cudd_bddAnd (DdManager *dd, DdNode *f, DdNode *g);
+extern DdNode * Cudd_bddAndLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit);
+extern DdNode * Cudd_bddOr (DdManager *dd, DdNode *f, DdNode *g);
+extern DdNode * Cudd_bddNand (DdManager *dd, DdNode *f, DdNode *g);
+extern DdNode * Cudd_bddNor (DdManager *dd, DdNode *f, DdNode *g);
+extern DdNode * Cudd_bddXor (DdManager *dd, DdNode *f, DdNode *g);
+extern DdNode * Cudd_bddXnor (DdManager *dd, DdNode *f, DdNode *g);
+extern int Cudd_bddLeq (DdManager *dd, DdNode *f, DdNode *g);
+extern DdNode * Cudd_addBddThreshold (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE value);
+extern DdNode * Cudd_addBddStrictThreshold (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE value);
+extern DdNode * Cudd_addBddInterval (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE lower, CUDD_VALUE_TYPE upper);
+extern DdNode * Cudd_addBddIthBit (DdManager *dd, DdNode *f, int bit);
+extern DdNode * Cudd_BddToAdd (DdManager *dd, DdNode *B);
+extern DdNode * Cudd_addBddPattern (DdManager *dd, DdNode *f);
+extern DdNode * Cudd_bddTransfer (DdManager *ddSource, DdManager *ddDestination, DdNode *f);
+extern int Cudd_DebugCheck (DdManager *table);
+extern int Cudd_CheckKeys (DdManager *table);
+extern DdNode * Cudd_bddClippingAnd (DdManager *dd, DdNode *f, DdNode *g, int maxDepth, int direction);
+extern DdNode * Cudd_bddClippingAndAbstract (DdManager *dd, DdNode *f, DdNode *g, DdNode *cube, int maxDepth, int direction);
+extern DdNode * Cudd_Cofactor (DdManager *dd, DdNode *f, DdNode *g);
+extern DdNode * Cudd_bddCompose (DdManager *dd, DdNode *f, DdNode *g, int v);
+extern DdNode * Cudd_addCompose (DdManager *dd, DdNode *f, DdNode *g, int v);
+extern DdNode * Cudd_addPermute (DdManager *manager, DdNode *node, int *permut);
+extern DdNode * Cudd_addSwapVariables (DdManager *dd, DdNode *f, DdNode **x, DdNode **y, int n);
+extern DdNode * Cudd_bddPermute (DdManager *manager, DdNode *node, int *permut);
+extern DdNode * Cudd_bddVarMap (DdManager *manager, DdNode *f);
+extern int Cudd_SetVarMap (DdManager *manager, DdNode **x, DdNode **y, int n);
+extern DdNode * Cudd_bddSwapVariables (DdManager *dd, DdNode *f, DdNode **x, DdNode **y, int n);
+extern DdNode * Cudd_bddAdjPermuteX (DdManager *dd, DdNode *B, DdNode **x, int n);
+extern DdNode * Cudd_addVectorCompose (DdManager *dd, DdNode *f, DdNode **vector);
+extern DdNode * Cudd_addGeneralVectorCompose (DdManager *dd, DdNode *f, DdNode **vectorOn, DdNode **vectorOff);
+extern DdNode * Cudd_addNonSimCompose (DdManager *dd, DdNode *f, DdNode **vector);
+extern DdNode * Cudd_bddVectorCompose (DdManager *dd, DdNode *f, DdNode **vector);
+extern int Cudd_bddApproxConjDecomp (DdManager *dd, DdNode *f, DdNode ***conjuncts);
+extern int Cudd_bddApproxDisjDecomp (DdManager *dd, DdNode *f, DdNode ***disjuncts);
+extern int Cudd_bddIterConjDecomp (DdManager *dd, DdNode *f, DdNode ***conjuncts);
+extern int Cudd_bddIterDisjDecomp (DdManager *dd, DdNode *f, DdNode ***disjuncts);
+extern int Cudd_bddGenConjDecomp (DdManager *dd, DdNode *f, DdNode ***conjuncts);
+extern int Cudd_bddGenDisjDecomp (DdManager *dd, DdNode *f, DdNode ***disjuncts);
+extern int Cudd_bddVarConjDecomp (DdManager *dd, DdNode * f, DdNode ***conjuncts);
+extern int Cudd_bddVarDisjDecomp (DdManager *dd, DdNode * f, DdNode ***disjuncts);
+extern DdNode * Cudd_FindEssential (DdManager *dd, DdNode *f);
+extern int Cudd_bddIsVarEssential (DdManager *manager, DdNode *f, int id, int phase);
+extern DdTlcInfo * Cudd_FindTwoLiteralClauses (DdManager * dd, DdNode * f);
+extern int Cudd_PrintTwoLiteralClauses (DdManager * dd, DdNode * f, char **names, FILE *fp);
+extern int Cudd_ReadIthClause (DdTlcInfo * tlc, int i, DdHalfWord *var1, DdHalfWord *var2, int *phase1, int *phase2);
+extern void Cudd_tlcInfoFree (DdTlcInfo * t);
+extern int Cudd_DumpBlif (DdManager *dd, int n, DdNode **f, char **inames, char **onames, char *mname, FILE *fp, int mv);
+extern int Cudd_DumpBlifBody (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp, int mv);
+extern int Cudd_DumpDot (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp);
+extern int Cudd_DumpDaVinci (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp);
+extern int Cudd_DumpDDcal (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp);
+extern int Cudd_DumpFactoredForm (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp);
+extern DdNode * Cudd_bddConstrain (DdManager *dd, DdNode *f, DdNode *c);
+extern DdNode * Cudd_bddRestrict (DdManager *dd, DdNode *f, DdNode *c);
+extern DdNode * Cudd_bddNPAnd (DdManager *dd, DdNode *f, DdNode *c);
+extern DdNode * Cudd_addConstrain (DdManager *dd, DdNode *f, DdNode *c);
+extern DdNode ** Cudd_bddConstrainDecomp (DdManager *dd, DdNode *f);
+extern DdNode * Cudd_addRestrict (DdManager *dd, DdNode *f, DdNode *c);
+extern DdNode ** Cudd_bddCharToVect (DdManager *dd, DdNode *f);
+extern DdNode * Cudd_bddLICompaction (DdManager *dd, DdNode *f, DdNode *c);
+extern DdNode * Cudd_bddSqueeze (DdManager *dd, DdNode *l, DdNode *u);
+extern DdNode * Cudd_bddMinimize (DdManager *dd, DdNode *f, DdNode *c);
+extern DdNode * Cudd_SubsetCompress (DdManager *dd, DdNode *f, int nvars, int threshold);
+extern DdNode * Cudd_SupersetCompress (DdManager *dd, DdNode *f, int nvars, int threshold);
+extern MtrNode * Cudd_MakeTreeNode (DdManager *dd, unsigned int low, unsigned int size, unsigned int type);
+extern int Cudd_addHarwell (FILE *fp, DdManager *dd, DdNode **E, DdNode ***x, DdNode ***y, DdNode ***xn, DdNode ***yn_, int *nx, int *ny, int *m, int *n, int bx, int sx, int by, int sy, int pr);
+extern DdManager * Cudd_Init (unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory);
+extern void Cudd_Quit (DdManager *unique);
+extern int Cudd_PrintLinear (DdManager *table);
+extern int Cudd_ReadLinear (DdManager *table, int x, int y);
+extern DdNode * Cudd_bddLiteralSetIntersection (DdManager *dd, DdNode *f, DdNode *g);
+extern DdNode * Cudd_addMatrixMultiply (DdManager *dd, DdNode *A, DdNode *B, DdNode **z, int nz);
+extern DdNode * Cudd_addTimesPlus (DdManager *dd, DdNode *A, DdNode *B, DdNode **z, int nz);
+extern DdNode * Cudd_addTriangle (DdManager *dd, DdNode *f, DdNode *g, DdNode **z, int nz);
+extern DdNode * Cudd_addOuterSum (DdManager *dd, DdNode *M, DdNode *r, DdNode *c);
+extern DdNode * Cudd_PrioritySelect (DdManager *dd, DdNode *R, DdNode **x, DdNode **y, DdNode **z, DdNode *Pii, int n, DdNode * (*)(DdManager *, int, DdNode **, DdNode **, DdNode **));
+extern DdNode * Cudd_Xgty (DdManager *dd, int N, DdNode **z, DdNode **x, DdNode **y);
+extern DdNode * Cudd_Xeqy (DdManager *dd, int N, DdNode **x, DdNode **y);
+extern DdNode * Cudd_addXeqy (DdManager *dd, int N, DdNode **x, DdNode **y);
+extern DdNode * Cudd_Dxygtdxz (DdManager *dd, int N, DdNode **x, DdNode **y, DdNode **z);
+extern DdNode * Cudd_Dxygtdyz (DdManager *dd, int N, DdNode **x, DdNode **y, DdNode **z);
+extern DdNode * Cudd_Inequality (DdManager * dd, int  N, int c, DdNode ** x, DdNode ** y);
+extern DdNode * Cudd_Disequality (DdManager * dd, int  N, int c, DdNode ** x, DdNode ** y);
+extern DdNode * Cudd_bddInterval (DdManager * dd, int  N, DdNode ** x, unsigned int lowerB, unsigned int upperB);
+extern DdNode * Cudd_CProjection (DdManager *dd, DdNode *R, DdNode *Y);
+extern DdNode * Cudd_addHamming (DdManager *dd, DdNode **xVars, DdNode **yVars, int nVars);
+extern int Cudd_MinHammingDist (DdManager *dd, DdNode *f, int *minterm, int upperBound);
+extern DdNode * Cudd_bddClosestCube (DdManager *dd, DdNode * f, DdNode *g, int *distance);
+extern int Cudd_addRead (FILE *fp, DdManager *dd, DdNode **E, DdNode ***x, DdNode ***y, DdNode ***xn, DdNode ***yn_, int *nx, int *ny, int *m, int *n, int bx, int sx, int by, int sy);
+extern int Cudd_bddRead (FILE *fp, DdManager *dd, DdNode **E, DdNode ***x, DdNode ***y, int *nx, int *ny, int *m, int *n, int bx, int sx, int by, int sy);
+extern void Cudd_Ref (DdNode *n);
+extern void Cudd_RecursiveDeref (DdManager *table, DdNode *n);
+extern void Cudd_IterDerefBdd (DdManager *table, DdNode *n);
+extern void Cudd_DelayedDerefBdd (DdManager * table, DdNode * n);
+extern void Cudd_RecursiveDerefZdd (DdManager *table, DdNode *n);
+extern void Cudd_Deref (DdNode *node);
+extern int Cudd_CheckZeroRef (DdManager *manager);
+extern int Cudd_ReduceHeap (DdManager *table, Cudd_ReorderingType heuristic, int minsize);
+extern int Cudd_ShuffleHeap (DdManager *table, int *permutation);
+extern DdNode * Cudd_Eval (DdManager *dd, DdNode *f, int *inputs);
+extern DdNode * Cudd_ShortestPath (DdManager *manager, DdNode *f, int *weight, int *support, int *length);
+extern DdNode * Cudd_LargestCube (DdManager *manager, DdNode *f, int *length);
+extern int Cudd_ShortestLength (DdManager *manager, DdNode *f, int *weight);
+extern DdNode * Cudd_Decreasing (DdManager *dd, DdNode *f, int i);
+extern DdNode * Cudd_Increasing (DdManager *dd, DdNode *f, int i);
+extern int Cudd_EquivDC (DdManager *dd, DdNode *F, DdNode *G, DdNode *D);
+extern int Cudd_bddLeqUnless (DdManager *dd, DdNode *f, DdNode *g, DdNode *D);
+extern int Cudd_EqualSupNorm (DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE tolerance, int pr);
+extern DdNode * Cudd_bddMakePrime (DdManager *dd, DdNode *cube, DdNode *f);
+extern double * Cudd_CofMinterm (DdManager *dd, DdNode *node);
+extern DdNode * Cudd_SolveEqn (DdManager * bdd, DdNode *F, DdNode *Y, DdNode **G, int **yIndex, int n);
+extern DdNode * Cudd_VerifySol (DdManager * bdd, DdNode *F, DdNode **G, int *yIndex, int n);
+extern DdNode * Cudd_SplitSet (DdManager *manager, DdNode *S, DdNode **xVars, int n, double m);
+extern DdNode * Cudd_SubsetHeavyBranch (DdManager *dd, DdNode *f, int numVars, int threshold);
+extern DdNode * Cudd_SupersetHeavyBranch (DdManager *dd, DdNode *f, int numVars, int threshold);
+extern DdNode * Cudd_SubsetShortPaths (DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit);
+extern DdNode * Cudd_SupersetShortPaths (DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit);
+extern void Cudd_SymmProfile (DdManager *table, int lower, int upper);
+extern unsigned int Cudd_Prime (unsigned int p);
+extern int Cudd_PrintMinterm (DdManager *manager, DdNode *node);
+extern int Cudd_bddPrintCover (DdManager *dd, DdNode *l, DdNode *u);
+extern int Cudd_PrintDebug (DdManager *dd, DdNode *f, int n, int pr);
+extern int Cudd_DagSize (DdNode *node);
+extern int Cudd_EstimateCofactor (DdManager *dd, DdNode * node, int i, int phase);
+extern int Cudd_EstimateCofactorSimple (DdNode * node, int i);
+extern int Cudd_SharingSize (DdNode **nodeArray, int n);
+extern double Cudd_CountMinterm (DdManager *manager, DdNode *node, int nvars);
+extern int Cudd_EpdCountMinterm (DdManager *manager, DdNode *node, int nvars, EpDouble *epd);
+extern double Cudd_CountPath (DdNode *node);
+extern double Cudd_CountPathsToNonZero (DdNode *node);
+extern DdNode * Cudd_Support (DdManager *dd, DdNode *f);
+extern int * Cudd_SupportIndex (DdManager *dd, DdNode *f);
+extern int Cudd_SupportSize (DdManager *dd, DdNode *f);
+extern DdNode * Cudd_VectorSupport (DdManager *dd, DdNode **F, int n);
+extern int * Cudd_VectorSupportIndex (DdManager *dd, DdNode **F, int n);
+extern int Cudd_VectorSupportSize (DdManager *dd, DdNode **F, int n);
+extern int Cudd_ClassifySupport (DdManager *dd, DdNode *f, DdNode *g, DdNode **common, DdNode **onlyF, DdNode **onlyG);
+extern int Cudd_CountLeaves (DdNode *node);
+extern int Cudd_bddPickOneCube (DdManager *ddm, DdNode *node, char *string);
+extern DdNode * Cudd_bddPickOneMinterm (DdManager *dd, DdNode *f, DdNode **vars, int n);
+extern DdNode ** Cudd_bddPickArbitraryMinterms (DdManager *dd, DdNode *f, DdNode **vars, int n, int k);
+extern DdNode * Cudd_SubsetWithMaskVars (DdManager *dd, DdNode *f, DdNode **vars, int nvars, DdNode **maskVars, int mvars);
+extern DdGen * Cudd_FirstCube (DdManager *dd, DdNode *f, int **cube, CUDD_VALUE_TYPE *value);
+extern int Cudd_NextCube (DdGen *gen, int **cube, CUDD_VALUE_TYPE *value);
+extern DdGen * Cudd_FirstPrime(DdManager *dd, DdNode *l, DdNode *u, int **cube);
+extern int Cudd_NextPrime(DdGen *gen, int **cube);
+extern DdNode * Cudd_bddComputeCube (DdManager *dd, DdNode **vars, int *phase, int n);
+extern DdNode * Cudd_addComputeCube (DdManager *dd, DdNode **vars, int *phase, int n);
+extern DdNode * Cudd_CubeArrayToBdd (DdManager *dd, int *array);
+extern int Cudd_BddToCubeArray (DdManager *dd, DdNode *cube, int *array);
+extern DdGen * Cudd_FirstNode (DdManager *dd, DdNode *f, DdNode **node);
+extern int Cudd_NextNode (DdGen *gen, DdNode **node);
+extern int Cudd_GenFree (DdGen *gen);
+extern int Cudd_IsGenEmpty (DdGen *gen);
+extern DdNode * Cudd_IndicesToCube (DdManager *dd, int *array, int n);
+extern void Cudd_PrintVersion (FILE *fp);
+extern double Cudd_AverageDistance (DdManager *dd);
+extern long Cudd_Random (void);
+extern void Cudd_Srandom (long seed);
+extern double Cudd_Density (DdManager *dd, DdNode *f, int nvars);
+extern void Cudd_OutOfMem (long size);
+extern int Cudd_zddCount (DdManager *zdd, DdNode *P);
+extern double Cudd_zddCountDouble (DdManager *zdd, DdNode *P);
+extern DdNode  * Cudd_zddProduct (DdManager *dd, DdNode *f, DdNode *g);
+extern DdNode  * Cudd_zddUnateProduct (DdManager *dd, DdNode *f, DdNode *g);
+extern DdNode  * Cudd_zddWeakDiv (DdManager *dd, DdNode *f, DdNode *g);
+extern DdNode  * Cudd_zddDivide (DdManager *dd, DdNode *f, DdNode *g);
+extern DdNode  * Cudd_zddWeakDivF (DdManager *dd, DdNode *f, DdNode *g);
+extern DdNode  * Cudd_zddDivideF (DdManager *dd, DdNode *f, DdNode *g);
+extern DdNode  * Cudd_zddComplement (DdManager *dd, DdNode *node);
+extern MtrNode * Cudd_MakeZddTreeNode (DdManager *dd, unsigned int low, unsigned int size, unsigned int type);
+extern DdNode  * Cudd_zddIsop (DdManager *dd, DdNode *L, DdNode *U, DdNode **zdd_I);
+extern DdNode  * Cudd_bddIsop (DdManager *dd, DdNode *L, DdNode *U);
+extern DdNode  * Cudd_MakeBddFromZddCover (DdManager *dd, DdNode *node);
+extern int Cudd_zddDagSize (DdNode *p_node);
+extern double Cudd_zddCountMinterm (DdManager *zdd, DdNode *node, int path);
+extern void Cudd_zddPrintSubtable (DdManager *table);
+extern DdNode * Cudd_zddPortFromBdd (DdManager *dd, DdNode *B);
+extern DdNode * Cudd_zddPortToBdd (DdManager *dd, DdNode *f);
+extern int Cudd_zddReduceHeap (DdManager *table, Cudd_ReorderingType heuristic, int minsize);
+extern int Cudd_zddShuffleHeap (DdManager *table, int *permutation);
+extern DdNode * Cudd_zddIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h);
+extern DdNode * Cudd_zddUnion (DdManager *dd, DdNode *P, DdNode *Q);
+extern DdNode * Cudd_zddIntersect (DdManager *dd, DdNode *P, DdNode *Q);
+extern DdNode * Cudd_zddDiff (DdManager *dd, DdNode *P, DdNode *Q);
+extern DdNode * Cudd_zddDiffConst (DdManager *zdd, DdNode *P, DdNode *Q);
+extern DdNode * Cudd_zddSubset1 (DdManager *dd, DdNode *P, int var);
+extern DdNode * Cudd_zddSubset0 (DdManager *dd, DdNode *P, int var);
+extern DdNode * Cudd_zddChange (DdManager *dd, DdNode *P, int var);
+extern void Cudd_zddSymmProfile (DdManager *table, int lower, int upper);
+extern int Cudd_zddPrintMinterm (DdManager *zdd, DdNode *node);
+extern int Cudd_zddPrintCover (DdManager *zdd, DdNode *node);
+extern int Cudd_zddPrintDebug (DdManager *zdd, DdNode *f, int n, int pr);
+extern DdGen * Cudd_zddFirstPath (DdManager *zdd, DdNode *f, int **path);
+extern int Cudd_zddNextPath (DdGen *gen, int **path);
+extern char * Cudd_zddCoverPathToString (DdManager *zdd, int *path, char *str);
+extern int Cudd_zddDumpDot (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp);
+extern int Cudd_bddSetPiVar (DdManager *dd, int index);
+extern int Cudd_bddSetPsVar (DdManager *dd, int index);
+extern int Cudd_bddSetNsVar (DdManager *dd, int index);
+extern int Cudd_bddIsPiVar (DdManager *dd, int index);
+extern int Cudd_bddIsPsVar (DdManager *dd, int index);
+extern int Cudd_bddIsNsVar (DdManager *dd, int index);
+extern int Cudd_bddSetPairIndex (DdManager *dd, int index, int pairIndex);
+extern int Cudd_bddReadPairIndex (DdManager *dd, int index);
+extern int Cudd_bddSetVarToBeGrouped (DdManager *dd, int index);
+extern int Cudd_bddSetVarHardGroup (DdManager *dd, int index);
+extern int Cudd_bddResetVarToBeGrouped (DdManager *dd, int index);
+extern int Cudd_bddIsVarToBeGrouped (DdManager *dd, int index);
+extern int Cudd_bddSetVarToBeUngrouped (DdManager *dd, int index);
+extern int Cudd_bddIsVarToBeUngrouped (DdManager *dd, int index);
+extern int Cudd_bddIsVarHardGroup (DdManager *dd, int index);
+
+/**AutomaticEnd***************************************************************/
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif /* _CUDD */
diff --git a/distr/cudd/cuddAPI.c b/distr/cudd/cuddAPI.c
new file mode 100644 (file)
index 0000000..0d931e9
--- /dev/null
@@ -0,0 +1,4437 @@
+/**CFile***********************************************************************
+
+  FileName    [cuddAPI.c]
+
+  PackageName [cudd]
+
+  Synopsis    [Application interface functions.]
+
+  Description [External procedures included in this module:
+               <ul>
+               <li> Cudd_addNewVar()
+               <li> Cudd_addNewVarAtLevel()
+               <li> Cudd_bddNewVar()
+               <li> Cudd_bddNewVarAtLevel()
+               <li> Cudd_addIthVar()
+               <li> Cudd_bddIthVar()
+               <li> Cudd_zddIthVar()
+               <li> Cudd_zddVarsFromBddVars()
+               <li> Cudd_addConst()
+               <li> Cudd_IsNonConstant()
+               <li> Cudd_AutodynEnable()
+               <li> Cudd_AutodynDisable()
+               <li> Cudd_ReorderingStatus()
+               <li> Cudd_AutodynEnableZdd()
+               <li> Cudd_AutodynDisableZdd()
+               <li> Cudd_ReorderingStatusZdd()
+               <li> Cudd_zddRealignmentEnabled()
+               <li> Cudd_zddRealignEnable()
+               <li> Cudd_zddRealignDisable()
+               <li> Cudd_bddRealignmentEnabled()
+               <li> Cudd_bddRealignEnable()
+               <li> Cudd_bddRealignDisable()
+               <li> Cudd_ReadOne()
+               <li> Cudd_ReadZddOne()
+               <li> Cudd_ReadZero()
+               <li> Cudd_ReadLogicZero()
+               <li> Cudd_ReadPlusInfinity()
+               <li> Cudd_ReadMinusInfinity()
+               <li> Cudd_ReadBackground()
+               <li> Cudd_SetBackground()
+               <li> Cudd_ReadCacheSlots()
+               <li> Cudd_ReadCacheUsedSlots()
+               <li> Cudd_ReadCacheLookUps()
+               <li> Cudd_ReadCacheHits()
+               <li> Cudd_ReadMinHit()
+               <li> Cudd_SetMinHit()
+               <li> Cudd_ReadLooseUpTo()
+               <li> Cudd_SetLooseUpTo()
+               <li> Cudd_ReadMaxCache()
+               <li> Cudd_ReadMaxCacheHard()
+               <li> Cudd_SetMaxCacheHard()
+               <li> Cudd_ReadSize()
+               <li> Cudd_ReadSlots()
+               <li> Cudd_ReadUsedSlots()
+               <li> Cudd_ExpectedUsedSlots()
+               <li> Cudd_ReadKeys()
+               <li> Cudd_ReadDead()
+               <li> Cudd_ReadMinDead()
+               <li> Cudd_ReadReorderings()
+               <li> Cudd_ReadReorderingTime()
+               <li> Cudd_ReadGarbageCollections()
+               <li> Cudd_ReadGarbageCollectionTime()
+               <li> Cudd_ReadNodesFreed()
+               <li> Cudd_ReadNodesDropped()
+               <li> Cudd_ReadUniqueLookUps()
+               <li> Cudd_ReadUniqueLinks()
+               <li> Cudd_ReadSiftMaxVar()
+               <li> Cudd_SetSiftMaxVar()
+               <li> Cudd_ReadMaxGrowth()
+               <li> Cudd_SetMaxGrowth()
+               <li> Cudd_ReadMaxGrowthAlternate()
+               <li> Cudd_SetMaxGrowthAlternate()
+               <li> Cudd_ReadReorderingCycle()
+               <li> Cudd_SetReorderingCycle()
+               <li> Cudd_ReadTree()
+               <li> Cudd_SetTree()
+               <li> Cudd_FreeTree()
+               <li> Cudd_ReadZddTree()
+               <li> Cudd_SetZddTree()
+               <li> Cudd_FreeZddTree()
+               <li> Cudd_NodeReadIndex()
+               <li> Cudd_ReadPerm()
+               <li> Cudd_ReadInvPerm()
+               <li> Cudd_ReadVars()
+               <li> Cudd_ReadEpsilon()
+               <li> Cudd_SetEpsilon()
+               <li> Cudd_ReadGroupCheck()
+               <li> Cudd_SetGroupcheck()
+               <li> Cudd_GarbageCollectionEnabled()
+               <li> Cudd_EnableGarbageCollection()
+               <li> Cudd_DisableGarbageCollection()
+               <li> Cudd_DeadAreCounted()
+               <li> Cudd_TurnOnCountDead()
+               <li> Cudd_TurnOffCountDead()
+               <li> Cudd_ReadRecomb()
+               <li> Cudd_SetRecomb()
+               <li> Cudd_ReadSymmviolation()
+               <li> Cudd_SetSymmviolation()
+               <li> Cudd_ReadArcviolation()
+               <li> Cudd_SetArcviolation()
+               <li> Cudd_ReadPopulationSize()
+               <li> Cudd_SetPopulationSize()
+               <li> Cudd_ReadNumberXovers()
+               <li> Cudd_SetNumberXovers()
+               <li> Cudd_ReadMemoryInUse()
+               <li> Cudd_PrintInfo()
+               <li> Cudd_ReadPeakNodeCount()
+               <li> Cudd_ReadPeakLiveNodeCount()
+               <li> Cudd_ReadNodeCount()
+               <li> Cudd_zddReadNodeCount()
+               <li> Cudd_AddHook()
+               <li> Cudd_RemoveHook()
+               <li> Cudd_IsInHook()
+               <li> Cudd_StdPreReordHook()
+               <li> Cudd_StdPostReordHook()
+               <li> Cudd_EnableReorderingReporting()
+               <li> Cudd_DisableReorderingReporting()
+               <li> Cudd_ReorderingReporting()
+               <li> Cudd_ReadErrorCode()
+               <li> Cudd_ClearErrorCode()
+               <li> Cudd_ReadStdout()
+               <li> Cudd_SetStdout()
+               <li> Cudd_ReadStderr()
+               <li> Cudd_SetStderr()
+               <li> Cudd_ReadNextReordering()
+               <li> Cudd_SetNextReordering()
+               <li> Cudd_ReadSwapSteps()
+               <li> Cudd_ReadMaxLive()
+               <li> Cudd_SetMaxLive()
+               <li> Cudd_ReadMaxMemory()
+               <li> Cudd_SetMaxMemory()
+               <li> Cudd_bddBindVar()
+               <li> Cudd_bddUnbindVar()
+               <li> Cudd_bddVarIsBound()
+               <li> Cudd_bddSetPiVar()
+               <li> Cudd_bddSetPsVar()
+               <li> Cudd_bddSetNsVar()
+               <li> Cudd_bddIsPiVar()
+               <li> Cudd_bddIsPsVar()
+               <li> Cudd_bddIsNsVar()
+               <li> Cudd_bddSetPairIndex()
+               <li> Cudd_bddReadPairIndex()
+               <li> Cudd_bddSetVarToBeGrouped()
+               <li> Cudd_bddSetVarHardGroup()
+               <li> Cudd_bddResetVarToBeGrouped()
+               <li> Cudd_bddIsVarToBeGrouped()
+               <li> Cudd_bddSetVarToBeUngrouped()
+               <li> Cudd_bddIsVarToBeUngrouped()
+               <li> Cudd_bddIsVarHardGroup()
+               </ul>
+             Static procedures included in this module:
+               <ul>
+               <li> fixVarTree()
+               </ul>]
+
+  SeeAlso     []
+
+  Author      [Fabio Somenzi]
+
+  Copyright   [Copyright (c) 1995-2004, Regents of the University of Colorado
+
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+  Redistributions of source code must retain the above copyright
+  notice, this list of conditions and the following disclaimer.
+
+  Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in the
+  documentation and/or other materials provided with the distribution.
+
+  Neither the name of the University of Colorado nor the names of its
+  contributors may be used to endorse or promote products derived from
+  this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.]
+
+******************************************************************************/
+
+#include "util.h"
+#include "cuddInt.h"
+
+/*---------------------------------------------------------------------------*/
+/* Constant declarations                                                     */
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/* Stucture declarations                                                     */
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/* Type declarations                                                         */
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/* Variable declarations                                                     */
+/*---------------------------------------------------------------------------*/
+
+#ifndef lint
+static char rcsid[] DD_UNUSED = "$Id: cuddAPI.c,v 1.59 2009/02/19 16:14:14 fabio Exp $";
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* Macro declarations                                                        */
+/*---------------------------------------------------------------------------*/
+
+/**AutomaticStart*************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* Static function prototypes                                                */
+/*---------------------------------------------------------------------------*/
+
+static void fixVarTree (MtrNode *treenode, int *perm, int size);
+static int addMultiplicityGroups (DdManager *dd, MtrNode *treenode, int multiplicity, char *vmask, char *lmask);
+
+/**AutomaticEnd***************************************************************/
+
+
+/*---------------------------------------------------------------------------*/
+/* Definition of exported functions                                          */
+/*---------------------------------------------------------------------------*/
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns a new ADD variable.]
+
+  Description [Creates a new ADD variable.  The new variable has an
+  index equal to the largest previous index plus 1.  Returns a
+  pointer to the new variable if successful; NULL otherwise.
+  An ADD variable differs from a BDD variable because it points to the
+  arithmetic zero, instead of having a complement pointer to 1. ]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_bddNewVar Cudd_addIthVar Cudd_addConst
+  Cudd_addNewVarAtLevel]
+
+******************************************************************************/
+DdNode *
+Cudd_addNewVar(
+  DdManager * dd)
+{
+    DdNode *res;
+
+    if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL);
+    do {
+       dd->reordered = 0;
+       res = cuddUniqueInter(dd,dd->size,DD_ONE(dd),DD_ZERO(dd));
+    } while (dd->reordered == 1);
+
+    return(res);
+
+} /* end of Cudd_addNewVar */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns a new ADD variable at a specified level.]
+
+  Description [Creates a new ADD variable.  The new variable has an
+  index equal to the largest previous index plus 1 and is positioned at
+  the specified level in the order.  Returns a pointer to the new
+  variable if successful; NULL otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addNewVar Cudd_addIthVar Cudd_bddNewVarAtLevel]
+
+******************************************************************************/
+DdNode *
+Cudd_addNewVarAtLevel(
+  DdManager * dd,
+  int  level)
+{
+    DdNode *res;
+
+    if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL);
+    if (level >= dd->size) return(Cudd_addIthVar(dd,level));
+    if (!cuddInsertSubtables(dd,1,level)) return(NULL);
+    do {
+       dd->reordered = 0;
+       res = cuddUniqueInter(dd,dd->size - 1,DD_ONE(dd),DD_ZERO(dd));
+    } while (dd->reordered == 1);
+
+    return(res);
+
+} /* end of Cudd_addNewVarAtLevel */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns a new BDD variable.]
+
+  Description [Creates a new BDD variable.  The new variable has an
+  index equal to the largest previous index plus 1.  Returns a
+  pointer to the new variable if successful; NULL otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addNewVar Cudd_bddIthVar Cudd_bddNewVarAtLevel]
+
+******************************************************************************/
+DdNode *
+Cudd_bddNewVar(
+  DdManager * dd)
+{
+    DdNode *res;
+
+    if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL);
+    res = cuddUniqueInter(dd,dd->size,dd->one,Cudd_Not(dd->one));
+
+    return(res);
+
+} /* end of Cudd_bddNewVar */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns a new BDD variable at a specified level.]
+
+  Description [Creates a new BDD variable.  The new variable has an
+  index equal to the largest previous index plus 1 and is positioned at
+  the specified level in the order.  Returns a pointer to the new
+  variable if successful; NULL otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_bddNewVar Cudd_bddIthVar Cudd_addNewVarAtLevel]
+
+******************************************************************************/
+DdNode *
+Cudd_bddNewVarAtLevel(
+  DdManager * dd,
+  int  level)
+{
+    DdNode *res;
+
+    if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL);
+    if (level >= dd->size) return(Cudd_bddIthVar(dd,level));
+    if (!cuddInsertSubtables(dd,1,level)) return(NULL);
+    res = dd->vars[dd->size - 1];
+
+    return(res);
+
+} /* end of Cudd_bddNewVarAtLevel */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the ADD variable with index i.]
+
+  Description [Retrieves the ADD variable with index i if it already
+  exists, or creates a new ADD variable.  Returns a pointer to the
+  variable if successful; NULL otherwise.  An ADD variable differs from
+  a BDD variable because it points to the arithmetic zero, instead of
+  having a complement pointer to 1. ]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addNewVar Cudd_bddIthVar Cudd_addConst
+  Cudd_addNewVarAtLevel]
+
+******************************************************************************/
+DdNode *
+Cudd_addIthVar(
+  DdManager * dd,
+  int  i)
+{
+    DdNode *res;
+
+    if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL);
+    do {
+       dd->reordered = 0;
+       res = cuddUniqueInter(dd,i,DD_ONE(dd),DD_ZERO(dd));
+    } while (dd->reordered == 1);
+
+    return(res);
+
+} /* end of Cudd_addIthVar */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the BDD variable with index i.]
+
+  Description [Retrieves the BDD variable with index i if it already
+  exists, or creates a new BDD variable.  Returns a pointer to the
+  variable if successful; NULL otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_bddNewVar Cudd_addIthVar Cudd_bddNewVarAtLevel
+  Cudd_ReadVars]
+
+******************************************************************************/
+DdNode *
+Cudd_bddIthVar(
+  DdManager * dd,
+  int  i)
+{
+    DdNode *res;
+
+    if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL);
+    if (i < dd->size) {
+       res = dd->vars[i];
+    } else {
+       res = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one));
+    }
+
+    return(res);
+
+} /* end of Cudd_bddIthVar */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the ZDD variable with index i.]
+
+  Description [Retrieves the ZDD variable with index i if it already
+  exists, or creates a new ZDD variable.  Returns a pointer to the
+  variable if successful; NULL otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_bddIthVar Cudd_addIthVar]
+
+******************************************************************************/
+DdNode *
+Cudd_zddIthVar(
+  DdManager * dd,
+  int  i)
+{
+    DdNode *res;
+    DdNode *zvar;
+    DdNode *lower;
+    int j;
+
+    if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL);
+
+    /* The i-th variable function has the following structure:
+    ** at the level corresponding to index i there is a node whose "then"
+    ** child points to the universe, and whose "else" child points to zero.
+    ** Above that level there are nodes with identical children.
+    */
+
+    /* First we build the node at the level of index i. */
+    lower = (i < dd->sizeZ - 1) ? dd->univ[dd->permZ[i]+1] : DD_ONE(dd);
+    do {
+       dd->reordered = 0;
+       zvar = cuddUniqueInterZdd(dd, i, lower, DD_ZERO(dd));
+    } while (dd->reordered == 1);
+
+    if (zvar == NULL)
+       return(NULL);
+    cuddRef(zvar);
+
+    /* Now we add the "filler" nodes above the level of index i. */
+    for (j = dd->permZ[i] - 1; j >= 0; j--) {
+       do {
+           dd->reordered = 0;
+           res = cuddUniqueInterZdd(dd, dd->invpermZ[j], zvar, zvar);
+       } while (dd->reordered == 1);
+       if (res == NULL) {
+           Cudd_RecursiveDerefZdd(dd,zvar);
+           return(NULL);
+       }
+       cuddRef(res);
+       Cudd_RecursiveDerefZdd(dd,zvar);
+       zvar = res;
+    }
+    cuddDeref(zvar);
+    return(zvar);
+
+} /* end of Cudd_zddIthVar */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Creates one or more ZDD variables for each BDD variable.]
+
+  Description [Creates one or more ZDD variables for each BDD
+  variable.  If some ZDD variables already exist, only the missing
+  variables are created.  Parameter multiplicity allows the caller to
+  control how many variables are created for each BDD variable in
+  existence. For instance, if ZDDs are used to represent covers, two
+  ZDD variables are required for each BDD variable.  The order of the
+  BDD variables is transferred to the ZDD variables. If a variable
+  group tree exists for the BDD variables, a corresponding ZDD
+  variable group tree is created by expanding the BDD variable
+  tree. In any case, the ZDD variables derived from the same BDD
+  variable are merged in a ZDD variable group. If a ZDD variable group
+  tree exists, it is freed. Returns 1 if successful; 0 otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_bddNewVar Cudd_bddIthVar Cudd_bddNewVarAtLevel]
+
+******************************************************************************/
+int
+Cudd_zddVarsFromBddVars(
+  DdManager * dd /* DD manager */,
+  int multiplicity /* how many ZDD variables are created for each BDD variable */)
+{
+    int res;
+    int i, j;
+    int allnew;
+    int *permutation;
+
+    if (multiplicity < 1) return(0);
+    allnew = dd->sizeZ == 0;
+    if (dd->size * multiplicity > dd->sizeZ) {
+       res = cuddResizeTableZdd(dd,dd->size * multiplicity - 1);
+       if (res == 0) return(0);
+    }
+    /* Impose the order of the BDD variables to the ZDD variables. */
+    if (allnew) {
+       for (i = 0; i < dd->size; i++) {
+           for (j = 0; j < multiplicity; j++) {
+               dd->permZ[i * multiplicity + j] =
+                   dd->perm[i] * multiplicity + j;
+               dd->invpermZ[dd->permZ[i * multiplicity + j]] =
+                   i * multiplicity + j;
+           }
+       }
+       for (i = 0; i < dd->sizeZ; i++) {
+           dd->univ[i]->index = dd->invpermZ[i];
+       }
+    } else {
+       permutation = ALLOC(int,dd->sizeZ);
+       if (permutation == NULL) {
+           dd->errorCode = CUDD_MEMORY_OUT;
+           return(0);
+       }
+       for (i = 0; i < dd->size; i++) {
+           for (j = 0; j < multiplicity; j++) {
+               permutation[i * multiplicity + j] =
+                   dd->invperm[i] * multiplicity + j;
+           }
+       }
+       for (i = dd->size * multiplicity; i < dd->sizeZ; i++) {
+           permutation[i] = i;
+       }
+       res = Cudd_zddShuffleHeap(dd, permutation);
+       FREE(permutation);
+       if (res == 0) return(0);
+    }
+    /* Copy and expand the variable group tree if it exists. */
+    if (dd->treeZ != NULL) {
+       Cudd_FreeZddTree(dd);
+    }
+    if (dd->tree != NULL) {
+       dd->treeZ = Mtr_CopyTree(dd->tree, multiplicity);
+       if (dd->treeZ == NULL) return(0);
+    } else if (multiplicity > 1) {
+       dd->treeZ = Mtr_InitGroupTree(0, dd->sizeZ);
+       if (dd->treeZ == NULL) return(0);
+       dd->treeZ->index = dd->invpermZ[0];
+    }
+    /* Create groups for the ZDD variables derived from the same BDD variable.
+    */
+    if (multiplicity > 1) {
+       char *vmask, *lmask;
+
+       vmask = ALLOC(char, dd->size);
+       if (vmask == NULL) {
+           dd->errorCode = CUDD_MEMORY_OUT;
+           return(0);
+       }
+       lmask =  ALLOC(char, dd->size);
+       if (lmask == NULL) {
+           dd->errorCode = CUDD_MEMORY_OUT;
+           return(0);
+       }
+       for (i = 0; i < dd->size; i++) {
+           vmask[i] = lmask[i] = 0;
+       }
+       res = addMultiplicityGroups(dd,dd->treeZ,multiplicity,vmask,lmask);
+       FREE(vmask);
+       FREE(lmask);
+       if (res == 0) return(0);
+    }
+    return(1);
+
+} /* end of Cudd_zddVarsFromBddVars */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the ADD for constant c.]
+
+  Description [Retrieves the ADD for constant c if it already
+  exists, or creates a new ADD.  Returns a pointer to the
+  ADD if successful; NULL otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addNewVar Cudd_addIthVar]
+
+******************************************************************************/
+DdNode *
+Cudd_addConst(
+  DdManager * dd,
+  CUDD_VALUE_TYPE  c)
+{
+    return(cuddUniqueConst(dd,c));
+
+} /* end of Cudd_addConst */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns 1 if a DD node is not constant.]
+
+  Description [Returns 1 if a DD node is not constant. This function is
+  useful to test the results of Cudd_bddIteConstant, Cudd_addIteConstant,
+  Cudd_addEvalConst. These results may be a special value signifying
+  non-constant. In the other cases the macro Cudd_IsConstant can be used.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_IsConstant Cudd_bddIteConstant Cudd_addIteConstant
+  Cudd_addEvalConst]
+
+******************************************************************************/
+int
+Cudd_IsNonConstant(
+  DdNode *f)
+{
+    return(f == DD_NON_CONSTANT || !Cudd_IsConstant(f));
+
+} /* end of Cudd_IsNonConstant */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Enables automatic dynamic reordering of BDDs and ADDs.]
+
+  Description [Enables automatic dynamic reordering of BDDs and
+  ADDs. Parameter method is used to determine the method used for
+  reordering. If CUDD_REORDER_SAME is passed, the method is
+  unchanged.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_AutodynDisable Cudd_ReorderingStatus
+  Cudd_AutodynEnableZdd]
+
+******************************************************************************/
+void
+Cudd_AutodynEnable(
+  DdManager * unique,
+  Cudd_ReorderingType  method)
+{
+    unique->autoDyn = 1;
+    if (method != CUDD_REORDER_SAME) {
+       unique->autoMethod = method;
+    }
+#ifndef DD_NO_DEATH_ROW
+    /* If reordering is enabled, using the death row causes too many
+    ** invocations. Hence, we shrink the death row to just one entry.
+    */
+    cuddClearDeathRow(unique);
+    unique->deathRowDepth = 1;
+    unique->deadMask = unique->deathRowDepth - 1;
+    if ((unsigned) unique->nextDead > unique->deadMask) {
+       unique->nextDead = 0;
+    }
+    unique->deathRow = REALLOC(DdNodePtr, unique->deathRow,
+       unique->deathRowDepth);
+#endif
+    return;
+
+} /* end of Cudd_AutodynEnable */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Disables automatic dynamic reordering.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_AutodynEnable Cudd_ReorderingStatus
+  Cudd_AutodynDisableZdd]
+
+******************************************************************************/
+void
+Cudd_AutodynDisable(
+  DdManager * unique)
+{
+    unique->autoDyn = 0;
+    return;
+
+} /* end of Cudd_AutodynDisable */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reports the status of automatic dynamic reordering of BDDs
+  and ADDs.]
+
+  Description [Reports the status of automatic dynamic reordering of
+  BDDs and ADDs. Parameter method is set to the reordering method
+  currently selected. Returns 1 if automatic reordering is enabled; 0
+  otherwise.]
+
+  SideEffects [Parameter method is set to the reordering method currently
+  selected.]
+
+  SeeAlso     [Cudd_AutodynEnable Cudd_AutodynDisable
+  Cudd_ReorderingStatusZdd]
+
+******************************************************************************/
+int
+Cudd_ReorderingStatus(
+  DdManager * unique,
+  Cudd_ReorderingType * method)
+{
+    *method = unique->autoMethod;
+    return(unique->autoDyn);
+
+} /* end of Cudd_ReorderingStatus */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Enables automatic dynamic reordering of ZDDs.]
+
+  Description [Enables automatic dynamic reordering of ZDDs. Parameter
+  method is used to determine the method used for reordering ZDDs. If
+  CUDD_REORDER_SAME is passed, the method is unchanged.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_AutodynDisableZdd Cudd_ReorderingStatusZdd
+  Cudd_AutodynEnable]
+
+******************************************************************************/
+void
+Cudd_AutodynEnableZdd(
+  DdManager * unique,
+  Cudd_ReorderingType method)
+{
+    unique->autoDynZ = 1;
+    if (method != CUDD_REORDER_SAME) {
+       unique->autoMethodZ = method;
+    }
+    return;
+
+} /* end of Cudd_AutodynEnableZdd */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Disables automatic dynamic reordering of ZDDs.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_AutodynEnableZdd Cudd_ReorderingStatusZdd
+  Cudd_AutodynDisable]
+
+******************************************************************************/
+void
+Cudd_AutodynDisableZdd(
+  DdManager * unique)
+{
+    unique->autoDynZ = 0;
+    return;
+
+} /* end of Cudd_AutodynDisableZdd */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reports the status of automatic dynamic reordering of ZDDs.]
+
+  Description [Reports the status of automatic dynamic reordering of
+  ZDDs. Parameter method is set to the ZDD reordering method currently
+  selected. Returns 1 if automatic reordering is enabled; 0
+  otherwise.]
+
+  SideEffects [Parameter method is set to the ZDD reordering method currently
+  selected.]
+
+  SeeAlso     [Cudd_AutodynEnableZdd Cudd_AutodynDisableZdd
+  Cudd_ReorderingStatus]
+
+******************************************************************************/
+int
+Cudd_ReorderingStatusZdd(
+  DdManager * unique,
+  Cudd_ReorderingType * method)
+{
+    *method = unique->autoMethodZ;
+    return(unique->autoDynZ);
+
+} /* end of Cudd_ReorderingStatusZdd */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Tells whether the realignment of ZDD order to BDD order is
+  enabled.]
+
+  Description [Returns 1 if the realignment of ZDD order to BDD order is
+  enabled; 0 otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_zddRealignEnable Cudd_zddRealignDisable
+  Cudd_bddRealignEnable Cudd_bddRealignDisable]
+
+******************************************************************************/
+int
+Cudd_zddRealignmentEnabled(
+  DdManager * unique)
+{
+    return(unique->realign);
+
+} /* end of Cudd_zddRealignmentEnabled */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Enables realignment of ZDD order to BDD order.]
+
+  Description [Enables realignment of the ZDD variable order to the
+  BDD variable order after the BDDs and ADDs have been reordered.  The
+  number of ZDD variables must be a multiple of the number of BDD
+  variables for realignment to make sense. If this condition is not met,
+  Cudd_ReduceHeap will return 0. Let <code>M</code> be the
+  ratio of the two numbers. For the purpose of realignment, the ZDD
+  variables from <code>M*i</code> to <code>(M+1)*i-1</code> are
+  reagarded as corresponding to BDD variable <code>i</code>. Realignment
+  is initially disabled.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReduceHeap Cudd_zddRealignDisable
+  Cudd_zddRealignmentEnabled Cudd_bddRealignDisable
+  Cudd_bddRealignmentEnabled]
+
+******************************************************************************/
+void
+Cudd_zddRealignEnable(
+  DdManager * unique)
+{
+    unique->realign = 1;
+    return;
+
+} /* end of Cudd_zddRealignEnable */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Disables realignment of ZDD order to BDD order.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_zddRealignEnable Cudd_zddRealignmentEnabled
+  Cudd_bddRealignEnable Cudd_bddRealignmentEnabled]
+
+******************************************************************************/
+void
+Cudd_zddRealignDisable(
+  DdManager * unique)
+{
+    unique->realign = 0;
+    return;
+
+} /* end of Cudd_zddRealignDisable */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Tells whether the realignment of BDD order to ZDD order is
+  enabled.]
+
+  Description [Returns 1 if the realignment of BDD order to ZDD order is
+  enabled; 0 otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_bddRealignEnable Cudd_bddRealignDisable
+  Cudd_zddRealignEnable Cudd_zddRealignDisable]
+
+******************************************************************************/
+int
+Cudd_bddRealignmentEnabled(
+  DdManager * unique)
+{
+    return(unique->realignZ);
+
+} /* end of Cudd_bddRealignmentEnabled */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Enables realignment of BDD order to ZDD order.]
+
+  Description [Enables realignment of the BDD variable order to the
+  ZDD variable order after the ZDDs have been reordered.  The
+  number of ZDD variables must be a multiple of the number of BDD
+  variables for realignment to make sense. If this condition is not met,
+  Cudd_zddReduceHeap will return 0. Let <code>M</code> be the
+  ratio of the two numbers. For the purpose of realignment, the ZDD
+  variables from <code>M*i</code> to <code>(M+1)*i-1</code> are
+  reagarded as corresponding to BDD variable <code>i</code>. Realignment
+  is initially disabled.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_zddReduceHeap Cudd_bddRealignDisable
+  Cudd_bddRealignmentEnabled Cudd_zddRealignDisable
+  Cudd_zddRealignmentEnabled]
+
+******************************************************************************/
+void
+Cudd_bddRealignEnable(
+  DdManager * unique)
+{
+    unique->realignZ = 1;
+    return;
+
+} /* end of Cudd_bddRealignEnable */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Disables realignment of ZDD order to BDD order.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_bddRealignEnable Cudd_bddRealignmentEnabled
+  Cudd_zddRealignEnable Cudd_zddRealignmentEnabled]
+
+******************************************************************************/
+void
+Cudd_bddRealignDisable(
+  DdManager * unique)
+{
+    unique->realignZ = 0;
+    return;
+
+} /* end of Cudd_bddRealignDisable */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the one constant of the manager.]
+
+  Description [Returns the one constant of the manager. The one
+  constant is common to ADDs and BDDs.]
+
+  SideEffects [None]
+
+  SeeAlso [Cudd_ReadZero Cudd_ReadLogicZero Cudd_ReadZddOne]
+
+******************************************************************************/
+DdNode *
+Cudd_ReadOne(
+  DdManager * dd)
+{
+    return(dd->one);
+
+} /* end of Cudd_ReadOne */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the ZDD for the constant 1 function.]
+
+  Description [Returns the ZDD for the constant 1 function.
+  The representation of the constant 1 function as a ZDD depends on
+  how many variables it (nominally) depends on. The index of the
+  topmost variable in the support is given as argument <code>i</code>.]
+
+  SideEffects [None]
+
+  SeeAlso [Cudd_ReadOne]
+
+******************************************************************************/
+DdNode *
+Cudd_ReadZddOne(
+  DdManager * dd,
+  int  i)
+{
+    if (i < 0)
+       return(NULL);
+    return(i < dd->sizeZ ? dd->univ[i] : DD_ONE(dd));
+
+} /* end of Cudd_ReadZddOne */
+
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the zero constant of the manager.]
+
+  Description [Returns the zero constant of the manager. The zero
+  constant is the arithmetic zero, rather than the logic zero. The
+  latter is the complement of the one constant.]
+
+  SideEffects [None]
+
+  SeeAlso [Cudd_ReadOne Cudd_ReadLogicZero]
+
+******************************************************************************/
+DdNode *
+Cudd_ReadZero(
+  DdManager * dd)
+{
+    return(DD_ZERO(dd));
+
+} /* end of Cudd_ReadZero */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the logic zero constant of the manager.]
+
+  Description [Returns the zero constant of the manager. The logic zero
+  constant is the complement of the one constant, and is distinct from
+  the arithmetic zero.]
+
+  SideEffects [None]
+
+  SeeAlso [Cudd_ReadOne Cudd_ReadZero]
+
+******************************************************************************/
+DdNode *
+Cudd_ReadLogicZero(
+  DdManager * dd)
+{
+    return(Cudd_Not(DD_ONE(dd)));
+
+} /* end of Cudd_ReadLogicZero */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the plus-infinity constant from the manager.]
+
+  Description []
+
+  SideEffects [None]
+
+******************************************************************************/
+DdNode *
+Cudd_ReadPlusInfinity(
+  DdManager * dd)
+{
+    return(dd->plusinfinity);
+
+} /* end of Cudd_ReadPlusInfinity */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the minus-infinity constant from the manager.]
+
+  Description []
+
+  SideEffects [None]
+
+******************************************************************************/
+DdNode *
+Cudd_ReadMinusInfinity(
+  DdManager * dd)
+{
+    return(dd->minusinfinity);
+
+} /* end of Cudd_ReadMinusInfinity */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the background constant of the manager.]
+
+  Description []
+
+  SideEffects [None]
+
+******************************************************************************/
+DdNode *
+Cudd_ReadBackground(
+  DdManager * dd)
+{
+    return(dd->background);
+
+} /* end of Cudd_ReadBackground */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the background constant of the manager.]
+
+  Description [Sets the background constant of the manager. It assumes
+  that the DdNode pointer bck is already referenced.]
+
+  SideEffects [None]
+
+******************************************************************************/
+void
+Cudd_SetBackground(
+  DdManager * dd,
+  DdNode * bck)
+{
+    dd->background = bck;
+
+} /* end of Cudd_SetBackground */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the number of slots in the cache.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadCacheUsedSlots]
+
+******************************************************************************/
+unsigned int
+Cudd_ReadCacheSlots(
+  DdManager * dd)
+{
+    return(dd->cacheSlots);
+
+} /* end of Cudd_ReadCacheSlots */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the fraction of used slots in the cache.]
+
+  Description [Reads the fraction of used slots in the cache. The unused
+  slots are those in which no valid data is stored. Garbage collection,
+  variable reordering, and cache resizing may cause used slots to become
+  unused.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadCacheSlots]
+
+******************************************************************************/
+double
+Cudd_ReadCacheUsedSlots(
+  DdManager * dd)
+{
+    unsigned long used = 0;
+    int slots = dd->cacheSlots;
+    DdCache *cache = dd->cache;
+    int i;
+
+    for (i = 0; i < slots; i++) {
+       used += cache[i].h != 0;
+    }
+
+    return((double)used / (double) dd->cacheSlots);
+
+} /* end of Cudd_ReadCacheUsedSlots */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the number of cache look-ups.]
+
+  Description [Returns the number of cache look-ups.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadCacheHits]
+
+******************************************************************************/
+double
+Cudd_ReadCacheLookUps(
+  DdManager * dd)
+{
+    return(dd->cacheHits + dd->cacheMisses +
+          dd->totCachehits + dd->totCacheMisses);
+
+} /* end of Cudd_ReadCacheLookUps */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the number of cache hits.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadCacheLookUps]
+
+******************************************************************************/
+double
+Cudd_ReadCacheHits(
+  DdManager * dd)
+{
+    return(dd->cacheHits + dd->totCachehits);
+
+} /* end of Cudd_ReadCacheHits */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the number of recursive calls.]
+
+  Description [Returns the number of recursive calls if the package is
+  compiled with DD_COUNT defined.]
+
+  SideEffects [None]
+
+  SeeAlso     []
+
+******************************************************************************/
+double
+Cudd_ReadRecursiveCalls(
+  DdManager * dd)
+{
+#ifdef DD_COUNT
+    return(dd->recursiveCalls);
+#else
+    return(-1.0);
+#endif
+
+} /* end of Cudd_ReadRecursiveCalls */
+
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the hit rate that causes resizinig of the computed
+  table.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_SetMinHit]
+
+******************************************************************************/
+unsigned int
+Cudd_ReadMinHit(
+  DdManager * dd)
+{
+    /* Internally, the package manipulates the ratio of hits to
+    ** misses instead of the ratio of hits to accesses. */
+    return((unsigned int) (0.5 + 100 * dd->minHit / (1 + dd->minHit)));
+
+} /* end of Cudd_ReadMinHit */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the hit rate that causes resizinig of the computed
+  table.]
+
+  Description [Sets the minHit parameter of the manager. This
+  parameter controls the resizing of the computed table. If the hit
+  rate is larger than the specified value, and the cache is not
+  already too large, then its size is doubled.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadMinHit]
+
+******************************************************************************/
+void
+Cudd_SetMinHit(
+  DdManager * dd,
+  unsigned int hr)
+{
+    /* Internally, the package manipulates the ratio of hits to
+    ** misses instead of the ratio of hits to accesses. */
+    dd->minHit = (double) hr / (100.0 - (double) hr);
+
+} /* end of Cudd_SetMinHit */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the looseUpTo parameter of the manager.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_SetLooseUpTo Cudd_ReadMinHit Cudd_ReadMinDead]
+
+******************************************************************************/
+unsigned int
+Cudd_ReadLooseUpTo(
+  DdManager * dd)
+{
+    return(dd->looseUpTo);
+
+} /* end of Cudd_ReadLooseUpTo */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the looseUpTo parameter of the manager.]
+
+  Description [Sets the looseUpTo parameter of the manager. This
+  parameter of the manager controls the threshold beyond which no fast
+  growth of the unique table is allowed. The threshold is given as a
+  number of slots. If the value passed to this function is 0, the
+  function determines a suitable value based on the available memory.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadLooseUpTo Cudd_SetMinHit]
+
+******************************************************************************/
+void
+Cudd_SetLooseUpTo(
+  DdManager * dd,
+  unsigned int lut)
+{
+    if (lut == 0) {
+       unsigned long datalimit = getSoftDataLimit();
+       lut = (unsigned int) (datalimit / (sizeof(DdNode) *
+                                          DD_MAX_LOOSE_FRACTION));
+    }
+    dd->looseUpTo = lut;
+
+} /* end of Cudd_SetLooseUpTo */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the soft limit for the cache size.]
+
+  Description [Returns the soft limit for the cache size. The soft limit]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadMaxCache]
+
+******************************************************************************/
+unsigned int
+Cudd_ReadMaxCache(
+  DdManager * dd)
+{
+    return(2 * dd->cacheSlots + dd->cacheSlack);
+
+} /* end of Cudd_ReadMaxCache */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the maxCacheHard parameter of the manager.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_SetMaxCacheHard Cudd_ReadMaxCache]
+
+******************************************************************************/
+unsigned int
+Cudd_ReadMaxCacheHard(
+  DdManager * dd)
+{
+    return(dd->maxCacheHard);
+
+} /* end of Cudd_ReadMaxCache */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the maxCacheHard parameter of the manager.]
+
+  Description [Sets the maxCacheHard parameter of the manager. The
+  cache cannot grow larger than maxCacheHard entries. This parameter
+  allows an application to control the trade-off of memory versus
+  speed. If the value passed to this function is 0, the function
+  determines a suitable maximum cache size based on the available memory.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadMaxCacheHard Cudd_SetMaxCache]
+
+******************************************************************************/
+void
+Cudd_SetMaxCacheHard(
+  DdManager * dd,
+  unsigned int mc)
+{
+    if (mc == 0) {
+       unsigned long datalimit = getSoftDataLimit();
+       mc = (unsigned int) (datalimit / (sizeof(DdCache) *
+                                         DD_MAX_CACHE_FRACTION));
+    }
+    dd->maxCacheHard = mc;
+
+} /* end of Cudd_SetMaxCacheHard */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the number of BDD variables in existance.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadZddSize]
+
+******************************************************************************/
+int
+Cudd_ReadSize(
+  DdManager * dd)
+{
+    return(dd->size);
+
+} /* end of Cudd_ReadSize */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the number of ZDD variables in existance.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadSize]
+
+******************************************************************************/
+int
+Cudd_ReadZddSize(
+  DdManager * dd)
+{
+    return(dd->sizeZ);
+
+} /* end of Cudd_ReadZddSize */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the total number of slots of the unique table.]
+
+  Description [Returns the total number of slots of the unique table.
+  This number ismainly for diagnostic purposes.]
+
+  SideEffects [None]
+
+******************************************************************************/
+unsigned int
+Cudd_ReadSlots(
+  DdManager * dd)
+{
+    return(dd->slots);
+
+} /* end of Cudd_ReadSlots */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the fraction of used slots in the unique table.]
+
+  Description [Reads the fraction of used slots in the unique
+  table. The unused slots are those in which no valid data is
+  stored. Garbage collection, variable reordering, and subtable
+  resizing may cause used slots to become unused.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadSlots]
+
+******************************************************************************/
+double
+Cudd_ReadUsedSlots(
+  DdManager * dd)
+{
+    unsigned long used = 0;
+    int i, j;
+    int size = dd->size;
+    DdNodePtr *nodelist;
+    DdSubtable *subtable;
+    DdNode *node;
+    DdNode *sentinel = &(dd->sentinel);
+
+    /* Scan each BDD/ADD subtable. */
+    for (i = 0; i < size; i++) {
+       subtable = &(dd->subtables[i]);
+       nodelist = subtable->nodelist;
+       for (j = 0; (unsigned) j < subtable->slots; j++) {
+           node = nodelist[j];
+           if (node != sentinel) {
+               used++;
+           }
+       }
+    }
+
+    /* Scan the ZDD subtables. */
+    size = dd->sizeZ;
+
+    for (i = 0; i < size; i++) {
+       subtable = &(dd->subtableZ[i]);
+       nodelist = subtable->nodelist;
+       for (j = 0; (unsigned) j < subtable->slots; j++) {
+           node = nodelist[j];
+           if (node != NULL) {
+               used++;
+           }
+       }
+    }
+
+    /* Constant table. */
+    subtable = &(dd->constants);
+    nodelist = subtable->nodelist;
+    for (j = 0; (unsigned) j < subtable->slots; j++) {
+       node = nodelist[j];
+       if (node != NULL) {
+           used++;
+       }
+    }
+
+    return((double)used / (double) dd->slots);
+
+} /* end of Cudd_ReadUsedSlots */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Computes the expected fraction of used slots in the unique
+  table.]
+
+  Description [Computes the fraction of slots in the unique table that
+  should be in use. This expected value is based on the assumption
+  that the hash function distributes the keys randomly; it can be
+  compared with the result of Cudd_ReadUsedSlots to monitor the
+  performance of the unique table hash function.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadSlots Cudd_ReadUsedSlots]
+
+******************************************************************************/
+double
+Cudd_ExpectedUsedSlots(
+  DdManager * dd)
+{
+    int i;
+    int size = dd->size;
+    DdSubtable *subtable;
+    double empty = 0.0;
+
+    /* To each subtable we apply the corollary to Theorem 8.5 (occupancy
+    ** distribution) from Sedgewick and Flajolet's Analysis of Algorithms.
+    ** The corollary says that for a table with M buckets and a load ratio
+    ** of r, the expected number of empty buckets is asymptotically given
+    ** by M * exp(-r).
+    */
+
+    /* Scan each BDD/ADD subtable. */
+    for (i = 0; i < size; i++) {
+       subtable = &(dd->subtables[i]);
+       empty += (double) subtable->slots *
+           exp(-(double) subtable->keys / (double) subtable->slots);
+    }
+
+    /* Scan the ZDD subtables. */
+    size = dd->sizeZ;
+
+    for (i = 0; i < size; i++) {
+       subtable = &(dd->subtableZ[i]);
+       empty += (double) subtable->slots *
+           exp(-(double) subtable->keys / (double) subtable->slots);
+    }
+
+    /* Constant table. */
+    subtable = &(dd->constants);
+    empty += (double) subtable->slots *
+       exp(-(double) subtable->keys / (double) subtable->slots);
+
+    return(1.0 - empty / (double) dd->slots);
+
+} /* end of Cudd_ExpectedUsedSlots */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the number of nodes in the unique table.]
+
+  Description [Returns the total number of nodes currently in the unique
+  table, including the dead nodes.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadDead]
+
+******************************************************************************/
+unsigned int
+Cudd_ReadKeys(
+  DdManager * dd)
+{
+    return(dd->keys);
+
+} /* end of Cudd_ReadKeys */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the number of dead nodes in the unique table.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadKeys]
+
+******************************************************************************/
+unsigned int
+Cudd_ReadDead(
+  DdManager * dd)
+{
+    return(dd->dead);
+
+} /* end of Cudd_ReadDead */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the minDead parameter of the manager.]
+
+  Description [Reads the minDead parameter of the manager. The minDead
+  parameter is used by the package to decide whether to collect garbage
+  or resize a subtable of the unique table when the subtable becomes
+  too full. The application can indirectly control the value of minDead
+  by setting the looseUpTo parameter.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadDead Cudd_ReadLooseUpTo Cudd_SetLooseUpTo]
+
+******************************************************************************/
+unsigned int
+Cudd_ReadMinDead(
+  DdManager * dd)
+{
+    return(dd->minDead);
+
+} /* end of Cudd_ReadMinDead */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the number of times reordering has occurred.]
+
+  Description [Returns the number of times reordering has occurred in the
+  manager. The number includes both the calls to Cudd_ReduceHeap from
+  the application program and those automatically performed by the
+  package. However, calls that do not even initiate reordering are not
+  counted. A call may not initiate reordering if there are fewer than
+  minsize live nodes in the manager, or if CUDD_REORDER_NONE is specified
+  as reordering method. The calls to Cudd_ShuffleHeap are not counted.]
+
+  SideEffects [None]
+
+  SeeAlso [Cudd_ReduceHeap Cudd_ReadReorderingTime]
+
+******************************************************************************/
+int
+Cudd_ReadReorderings(
+  DdManager * dd)
+{
+    return(dd->reorderings);
+
+} /* end of Cudd_ReadReorderings */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the time spent in reordering.]
+
+  Description [Returns the number of milliseconds spent reordering
+  variables since the manager was initialized. The time spent in collecting
+  garbage before reordering is included.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadReorderings]
+
+******************************************************************************/
+long
+Cudd_ReadReorderingTime(
+  DdManager * dd)
+{
+    return(dd->reordTime);
+
+} /* end of Cudd_ReadReorderingTime */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the number of times garbage collection has occurred.]
+
+  Description [Returns the number of times garbage collection has
+  occurred in the manager. The number includes both the calls from
+  reordering procedures and those caused by requests to create new
+  nodes.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadGarbageCollectionTime]
+
+******************************************************************************/
+int
+Cudd_ReadGarbageCollections(
+  DdManager * dd)
+{
+    return(dd->garbageCollections);
+
+} /* end of Cudd_ReadGarbageCollections */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the time spent in garbage collection.]
+
+  Description [Returns the number of milliseconds spent doing garbage
+  collection since the manager was initialized.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadGarbageCollections]
+
+******************************************************************************/
+long
+Cudd_ReadGarbageCollectionTime(
+  DdManager * dd)
+{
+    return(dd->GCTime);
+
+} /* end of Cudd_ReadGarbageCollectionTime */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the number of nodes freed.]
+
+  Description [Returns the number of nodes returned to the free list if the
+  keeping of this statistic is enabled; -1 otherwise. This statistic is
+  enabled only if the package is compiled with DD_STATS defined.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadNodesDropped]
+
+******************************************************************************/
+double
+Cudd_ReadNodesFreed(
+  DdManager * dd)
+{
+#ifdef DD_STATS
+    return(dd->nodesFreed);
+#else
+    return(-1.0);
+#endif
+
+} /* end of Cudd_ReadNodesFreed */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the number of nodes dropped.]
+
+  Description [Returns the number of nodes killed by dereferencing if the
+  keeping of this statistic is enabled; -1 otherwise. This statistic is
+  enabled only if the package is compiled with DD_STATS defined.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadNodesFreed]
+
+******************************************************************************/
+double
+Cudd_ReadNodesDropped(
+  DdManager * dd)
+{
+#ifdef DD_STATS
+    return(dd->nodesDropped);
+#else
+    return(-1.0);
+#endif
+
+} /* end of Cudd_ReadNodesDropped */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the number of look-ups in the unique table.]
+
+  Description [Returns the number of look-ups in the unique table if the
+  keeping of this statistic is enabled; -1 otherwise. This statistic is
+  enabled only if the package is compiled with DD_UNIQUE_PROFILE defined.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadUniqueLinks]
+
+******************************************************************************/
+double
+Cudd_ReadUniqueLookUps(
+  DdManager * dd)
+{
+#ifdef DD_UNIQUE_PROFILE
+    return(dd->uniqueLookUps);
+#else
+    return(-1.0);
+#endif
+
+} /* end of Cudd_ReadUniqueLookUps */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the number of links followed in the unique table.]
+
+  Description [Returns the number of links followed during look-ups in the
+  unique table if the keeping of this statistic is enabled; -1 otherwise.
+  If an item is found in the first position of its collision list, the
+  number of links followed is taken to be 0. If it is in second position,
+  the number of links is 1, and so on. This statistic is enabled only if
+  the package is compiled with DD_UNIQUE_PROFILE defined.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadUniqueLookUps]
+
+******************************************************************************/
+double
+Cudd_ReadUniqueLinks(
+  DdManager * dd)
+{
+#ifdef DD_UNIQUE_PROFILE
+    return(dd->uniqueLinks);
+#else
+    return(-1.0);
+#endif
+
+} /* end of Cudd_ReadUniqueLinks */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the siftMaxVar parameter of the manager.]
+
+  Description [Reads the siftMaxVar parameter of the manager. This
+  parameter gives the maximum number of variables that will be sifted
+  for each invocation of sifting.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadSiftMaxSwap Cudd_SetSiftMaxVar]
+
+******************************************************************************/
+int
+Cudd_ReadSiftMaxVar(
+  DdManager * dd)
+{
+    return(dd->siftMaxVar);
+
+} /* end of Cudd_ReadSiftMaxVar */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the siftMaxVar parameter of the manager.]
+
+  Description [Sets the siftMaxVar parameter of the manager. This
+  parameter gives the maximum number of variables that will be sifted
+  for each invocation of sifting.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_SetSiftMaxSwap Cudd_ReadSiftMaxVar]
+
+******************************************************************************/
+void
+Cudd_SetSiftMaxVar(
+  DdManager * dd,
+  int  smv)
+{
+    dd->siftMaxVar = smv;
+
+} /* end of Cudd_SetSiftMaxVar */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the siftMaxSwap parameter of the manager.]
+
+  Description [Reads the siftMaxSwap parameter of the manager. This
+  parameter gives the maximum number of swaps that will be attempted
+  for each invocation of sifting. The real number of swaps may exceed
+  the set limit because the package will always complete the sifting
+  of the variable that causes the limit to be reached.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadSiftMaxVar Cudd_SetSiftMaxSwap]
+
+******************************************************************************/
+int
+Cudd_ReadSiftMaxSwap(
+  DdManager * dd)
+{
+    return(dd->siftMaxSwap);
+
+} /* end of Cudd_ReadSiftMaxSwap */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the siftMaxSwap parameter of the manager.]
+
+  Description [Sets the siftMaxSwap parameter of the manager. This
+  parameter gives the maximum number of swaps that will be attempted
+  for each invocation of sifting. The real number of swaps may exceed
+  the set limit because the package will always complete the sifting
+  of the variable that causes the limit to be reached.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_SetSiftMaxVar Cudd_ReadSiftMaxSwap]
+
+******************************************************************************/
+void
+Cudd_SetSiftMaxSwap(
+  DdManager * dd,
+  int  sms)
+{
+    dd->siftMaxSwap = sms;
+
+} /* end of Cudd_SetSiftMaxSwap */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the maxGrowth parameter of the manager.]
+
+  Description [Reads the maxGrowth parameter of the manager.  This
+  parameter determines how much the number of nodes can grow during
+  sifting of a variable.  Overall, sifting never increases the size of
+  the decision diagrams.  This parameter only refers to intermediate
+  results.  A lower value will speed up sifting, possibly at the
+  expense of quality.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_SetMaxGrowth Cudd_ReadMaxGrowthAlternate]
+
+******************************************************************************/
+double
+Cudd_ReadMaxGrowth(
+  DdManager * dd)
+{
+    return(dd->maxGrowth);
+
+} /* end of Cudd_ReadMaxGrowth */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the maxGrowth parameter of the manager.]
+
+  Description [Sets the maxGrowth parameter of the manager.  This
+  parameter determines how much the number of nodes can grow during
+  sifting of a variable.  Overall, sifting never increases the size of
+  the decision diagrams.  This parameter only refers to intermediate
+  results.  A lower value will speed up sifting, possibly at the
+  expense of quality.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadMaxGrowth Cudd_SetMaxGrowthAlternate]
+
+******************************************************************************/
+void
+Cudd_SetMaxGrowth(
+  DdManager * dd,
+  double mg)
+{
+    dd->maxGrowth = mg;
+
+} /* end of Cudd_SetMaxGrowth */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the maxGrowthAlt parameter of the manager.]
+
+  Description [Reads the maxGrowthAlt parameter of the manager.  This
+  parameter is analogous to the maxGrowth paramter, and is used every
+  given number of reorderings instead of maxGrowth.  The number of
+  reorderings is set with Cudd_SetReorderingCycle.  If the number of
+  reorderings is 0 (default) maxGrowthAlt is never used.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadMaxGrowth Cudd_SetMaxGrowthAlternate
+  Cudd_SetReorderingCycle Cudd_ReadReorderingCycle]
+
+******************************************************************************/
+double
+Cudd_ReadMaxGrowthAlternate(
+  DdManager * dd)
+{
+    return(dd->maxGrowthAlt);
+
+} /* end of Cudd_ReadMaxGrowthAlternate */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the maxGrowthAlt parameter of the manager.]
+
+  Description [Sets the maxGrowthAlt parameter of the manager.  This
+  parameter is analogous to the maxGrowth paramter, and is used every
+  given number of reorderings instead of maxGrowth.  The number of
+  reorderings is set with Cudd_SetReorderingCycle.  If the number of
+  reorderings is 0 (default) maxGrowthAlt is never used.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowth
+  Cudd_SetReorderingCycle Cudd_ReadReorderingCycle]
+
+******************************************************************************/
+void
+Cudd_SetMaxGrowthAlternate(
+  DdManager * dd,
+  double mg)
+{
+    dd->maxGrowthAlt = mg;
+
+} /* end of Cudd_SetMaxGrowthAlternate */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the reordCycle parameter of the manager.]
+
+  Description [Reads the reordCycle parameter of the manager.  This
+  parameter determines how often the alternate threshold on maximum
+  growth is used in reordering.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowthAlternate
+  Cudd_SetReorderingCycle]
+
+******************************************************************************/
+int
+Cudd_ReadReorderingCycle(
+  DdManager * dd)
+{
+    return(dd->reordCycle);
+
+} /* end of Cudd_ReadReorderingCycle */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the reordCycle parameter of the manager.]
+
+  Description [Sets the reordCycle parameter of the manager.  This
+  parameter determines how often the alternate threshold on maximum
+  growth is used in reordering.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowthAlternate
+  Cudd_ReadReorderingCycle]
+
+******************************************************************************/
+void
+Cudd_SetReorderingCycle(
+  DdManager * dd,
+  int cycle)
+{
+    dd->reordCycle = cycle;
+
+} /* end of Cudd_SetReorderingCycle */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the variable group tree of the manager.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_SetTree Cudd_FreeTree Cudd_ReadZddTree]
+
+******************************************************************************/
+MtrNode *
+Cudd_ReadTree(
+  DdManager * dd)
+{
+    return(dd->tree);
+
+} /* end of Cudd_ReadTree */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the variable group tree of the manager.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_FreeTree Cudd_ReadTree Cudd_SetZddTree]
+
+******************************************************************************/
+void
+Cudd_SetTree(
+  DdManager * dd,
+  MtrNode * tree)
+{
+    if (dd->tree != NULL) {
+       Mtr_FreeTree(dd->tree);
+    }
+    dd->tree = tree;
+    if (tree == NULL) return;
+
+    fixVarTree(tree, dd->perm, dd->size);
+    return;
+
+} /* end of Cudd_SetTree */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Frees the variable group tree of the manager.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_SetTree Cudd_ReadTree Cudd_FreeZddTree]
+
+******************************************************************************/
+void
+Cudd_FreeTree(
+  DdManager * dd)
+{
+    if (dd->tree != NULL) {
+       Mtr_FreeTree(dd->tree);
+       dd->tree = NULL;
+    }
+    return;
+
+} /* end of Cudd_FreeTree */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the variable group tree of the manager.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_SetZddTree Cudd_FreeZddTree Cudd_ReadTree]
+
+******************************************************************************/
+MtrNode *
+Cudd_ReadZddTree(
+  DdManager * dd)
+{
+    return(dd->treeZ);
+
+} /* end of Cudd_ReadZddTree */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the ZDD variable group tree of the manager.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_FreeZddTree Cudd_ReadZddTree Cudd_SetTree]
+
+******************************************************************************/
+void
+Cudd_SetZddTree(
+  DdManager * dd,
+  MtrNode * tree)
+{
+    if (dd->treeZ != NULL) {
+       Mtr_FreeTree(dd->treeZ);
+    }
+    dd->treeZ = tree;
+    if (tree == NULL) return;
+
+    fixVarTree(tree, dd->permZ, dd->sizeZ);
+    return;
+
+} /* end of Cudd_SetZddTree */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Frees the variable group tree of the manager.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_SetZddTree Cudd_ReadZddTree Cudd_FreeTree]
+
+******************************************************************************/
+void
+Cudd_FreeZddTree(
+  DdManager * dd)
+{
+    if (dd->treeZ != NULL) {
+       Mtr_FreeTree(dd->treeZ);
+       dd->treeZ = NULL;
+    }
+    return;
+
+} /* end of Cudd_FreeZddTree */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the index of the node.]
+
+  Description [Returns the index of the node. The node pointer can be
+  either regular or complemented.]
+
+  SideEffects [None]
+
+  SeeAlso [Cudd_ReadIndex]
+
+******************************************************************************/
+unsigned int
+Cudd_NodeReadIndex(
+  DdNode * node)
+{
+    return((unsigned int) Cudd_Regular(node)->index);
+
+} /* end of Cudd_NodeReadIndex */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the current position of the i-th variable in the
+  order.]
+
+  Description [Returns the current position of the i-th variable in
+  the order. If the index is CUDD_CONST_INDEX, returns
+  CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns
+  -1.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadInvPerm Cudd_ReadPermZdd]
+
+******************************************************************************/
+int
+Cudd_ReadPerm(
+  DdManager * dd,
+  int  i)
+{
+    if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX);
+    if (i < 0 || i >= dd->size) return(-1);
+    return(dd->perm[i]);
+
+} /* end of Cudd_ReadPerm */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the current position of the i-th ZDD variable in the
+  order.]
+
+  Description [Returns the current position of the i-th ZDD variable
+  in the order. If the index is CUDD_CONST_INDEX, returns
+  CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns
+  -1.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadInvPermZdd Cudd_ReadPerm]
+
+******************************************************************************/
+int
+Cudd_ReadPermZdd(
+  DdManager * dd,
+  int  i)
+{
+    if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX);
+    if (i < 0 || i >= dd->sizeZ) return(-1);
+    return(dd->permZ[i]);
+
+} /* end of Cudd_ReadPermZdd */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the index of the variable currently in the i-th
+  position of the order.]
+
+  Description [Returns the index of the variable currently in the i-th
+  position of the order. If the index is CUDD_CONST_INDEX, returns
+  CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns -1.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadPerm Cudd_ReadInvPermZdd]
+
+******************************************************************************/
+int
+Cudd_ReadInvPerm(
+  DdManager * dd,
+  int  i)
+{
+    if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX);
+    if (i < 0 || i >= dd->size) return(-1);
+    return(dd->invperm[i]);
+
+} /* end of Cudd_ReadInvPerm */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the index of the ZDD variable currently in the i-th
+  position of the order.]
+
+  Description [Returns the index of the ZDD variable currently in the
+  i-th position of the order. If the index is CUDD_CONST_INDEX, returns
+  CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns -1.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadPerm Cudd_ReadInvPermZdd]
+
+******************************************************************************/
+int
+Cudd_ReadInvPermZdd(
+  DdManager * dd,
+  int  i)
+{
+    if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX);
+    if (i < 0 || i >= dd->sizeZ) return(-1);
+    return(dd->invpermZ[i]);
+
+} /* end of Cudd_ReadInvPermZdd */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the i-th element of the vars array.]
+
+  Description [Returns the i-th element of the vars array if it falls
+  within the array bounds; NULL otherwise. If i is the index of an
+  existing variable, this function produces the same result as
+  Cudd_bddIthVar. However, if the i-th var does not exist yet,
+  Cudd_bddIthVar will create it, whereas Cudd_ReadVars will not.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_bddIthVar]
+
+******************************************************************************/
+DdNode *
+Cudd_ReadVars(
+  DdManager * dd,
+  int  i)
+{
+    if (i < 0 || i > dd->size) return(NULL);
+    return(dd->vars[i]);
+
+} /* end of Cudd_ReadVars */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the epsilon parameter of the manager.]
+
+  Description [Reads the epsilon parameter of the manager. The epsilon
+  parameter control the comparison between floating point numbers.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_SetEpsilon]
+
+******************************************************************************/
+CUDD_VALUE_TYPE
+Cudd_ReadEpsilon(
+  DdManager * dd)
+{
+    return(dd->epsilon);
+
+} /* end of Cudd_ReadEpsilon */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the epsilon parameter of the manager to ep.]
+
+  Description [Sets the epsilon parameter of the manager to ep. The epsilon
+  parameter control the comparison between floating point numbers.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadEpsilon]
+
+******************************************************************************/
+void
+Cudd_SetEpsilon(
+  DdManager * dd,
+  CUDD_VALUE_TYPE  ep)
+{
+    dd->epsilon = ep;
+
+} /* end of Cudd_SetEpsilon */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the groupcheck parameter of the manager.]
+
+  Description [Reads the groupcheck parameter of the manager. The
+  groupcheck parameter determines the aggregation criterion in group
+  sifting.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_SetGroupcheck]
+
+******************************************************************************/
+Cudd_AggregationType
+Cudd_ReadGroupcheck(
+  DdManager * dd)
+{
+    return(dd->groupcheck);
+
+} /* end of Cudd_ReadGroupCheck */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the parameter groupcheck of the manager to gc.]
+
+  Description [Sets the parameter groupcheck of the manager to gc. The
+  groupcheck parameter determines the aggregation criterion in group
+  sifting.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadGroupCheck]
+
+******************************************************************************/
+void
+Cudd_SetGroupcheck(
+  DdManager * dd,
+  Cudd_AggregationType gc)
+{
+    dd->groupcheck = gc;
+
+} /* end of Cudd_SetGroupcheck */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Tells whether garbage collection is enabled.]
+
+  Description [Returns 1 if garbage collection is enabled; 0 otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_EnableGarbageCollection Cudd_DisableGarbageCollection]
+
+******************************************************************************/
+int
+Cudd_GarbageCollectionEnabled(
+  DdManager * dd)
+{
+    return(dd->gcEnabled);
+
+} /* end of Cudd_GarbageCollectionEnabled */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Enables garbage collection.]
+
+  Description [Enables garbage collection. Garbage collection is
+  initially enabled. Therefore it is necessary to call this function
+  only if garbage collection has been explicitly disabled.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_DisableGarbageCollection Cudd_GarbageCollectionEnabled]
+
+******************************************************************************/
+void
+Cudd_EnableGarbageCollection(
+  DdManager * dd)
+{
+    dd->gcEnabled = 1;
+
+} /* end of Cudd_EnableGarbageCollection */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Disables garbage collection.]
+
+  Description [Disables garbage collection. Garbage collection is
+  initially enabled. This function may be called to disable it.
+  However, garbage collection will still occur when a new node must be
+  created and no memory is left, or when garbage collection is required
+  for correctness. (E.g., before reordering.)]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_EnableGarbageCollection Cudd_GarbageCollectionEnabled]
+
+******************************************************************************/
+void
+Cudd_DisableGarbageCollection(
+  DdManager * dd)
+{
+    dd->gcEnabled = 0;
+
+} /* end of Cudd_DisableGarbageCollection */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Tells whether dead nodes are counted towards triggering
+  reordering.]
+
+  Description [Tells whether dead nodes are counted towards triggering
+  reordering. Returns 1 if dead nodes are counted; 0 otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_TurnOnCountDead Cudd_TurnOffCountDead]
+
+******************************************************************************/
+int
+Cudd_DeadAreCounted(
+  DdManager * dd)
+{
+    return(dd->countDead == 0 ? 1 : 0);
+
+} /* end of Cudd_DeadAreCounted */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Causes the dead nodes to be counted towards triggering
+  reordering.]
+
+  Description [Causes the dead nodes to be counted towards triggering
+  reordering. This causes more frequent reorderings. By default dead
+  nodes are not counted.]
+
+  SideEffects [Changes the manager.]
+
+  SeeAlso     [Cudd_TurnOffCountDead Cudd_DeadAreCounted]
+
+******************************************************************************/
+void
+Cudd_TurnOnCountDead(
+  DdManager * dd)
+{
+    dd->countDead = 0;
+
+} /* end of Cudd_TurnOnCountDead */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Causes the dead nodes not to be counted towards triggering
+  reordering.]
+
+  Description [Causes the dead nodes not to be counted towards
+  triggering reordering. This causes less frequent reorderings. By
+  default dead nodes are not counted. Therefore there is no need to
+  call this function unless Cudd_TurnOnCountDead has been previously
+  called.]
+
+  SideEffects [Changes the manager.]
+
+  SeeAlso     [Cudd_TurnOnCountDead Cudd_DeadAreCounted]
+
+******************************************************************************/
+void
+Cudd_TurnOffCountDead(
+  DdManager * dd)
+{
+    dd->countDead = ~0;
+
+} /* end of Cudd_TurnOffCountDead */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the current value of the recombination parameter used
+  in group sifting.]
+
+  Description [Returns the current value of the recombination
+  parameter used in group sifting. A larger (positive) value makes the
+  aggregation of variables due to the second difference criterion more
+  likely. A smaller (negative) value makes aggregation less likely.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_SetRecomb]
+
+******************************************************************************/
+int
+Cudd_ReadRecomb(
+  DdManager * dd)
+{
+    return(dd->recomb);
+
+} /* end of Cudd_ReadRecomb */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the value of the recombination parameter used in group
+  sifting.]
+
+  Description [Sets the value of the recombination parameter used in
+  group sifting. A larger (positive) value makes the aggregation of
+  variables due to the second difference criterion more likely. A
+  smaller (negative) value makes aggregation less likely. The default
+  value is 0.]
+
+  SideEffects [Changes the manager.]
+
+  SeeAlso     [Cudd_ReadRecomb]
+
+******************************************************************************/
+void
+Cudd_SetRecomb(
+  DdManager * dd,
+  int  recomb)
+{
+    dd->recomb = recomb;
+
+} /* end of Cudd_SetRecomb */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the current value of the symmviolation parameter used
+  in group sifting.]
+
+  Description [Returns the current value of the symmviolation
+  parameter. This parameter is used in group sifting to decide how
+  many violations to the symmetry conditions <code>f10 = f01</code> or
+  <code>f11 = f00</code> are tolerable when checking for aggregation
+  due to extended symmetry. The value should be between 0 and 100. A
+  small value causes fewer variables to be aggregated. The default
+  value is 0.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_SetSymmviolation]
+
+******************************************************************************/
+int
+Cudd_ReadSymmviolation(
+  DdManager * dd)
+{
+    return(dd->symmviolation);
+
+} /* end of Cudd_ReadSymmviolation */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the value of the symmviolation parameter used
+  in group sifting.]
+
+  Description [Sets the value of the symmviolation
+  parameter. This parameter is used in group sifting to decide how
+  many violations to the symmetry conditions <code>f10 = f01</code> or
+  <code>f11 = f00</code> are tolerable when checking for aggregation
+  due to extended symmetry. The value should be between 0 and 100. A
+  small value causes fewer variables to be aggregated. The default
+  value is 0.]
+
+  SideEffects [Changes the manager.]
+
+  SeeAlso     [Cudd_ReadSymmviolation]
+
+******************************************************************************/
+void
+Cudd_SetSymmviolation(
+  DdManager * dd,
+  int  symmviolation)
+{
+    dd->symmviolation = symmviolation;
+
+} /* end of Cudd_SetSymmviolation */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the current value of the arcviolation parameter used
+  in group sifting.]
+
+  Description [Returns the current value of the arcviolation
+  parameter. This parameter is used in group sifting to decide how
+  many arcs into <code>y</code> not coming from <code>x</code> are
+  tolerable when checking for aggregation due to extended
+  symmetry. The value should be between 0 and 100. A small value
+  causes fewer variables to be aggregated. The default value is 0.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_SetArcviolation]
+
+******************************************************************************/
+int
+Cudd_ReadArcviolation(
+  DdManager * dd)
+{
+    return(dd->arcviolation);
+
+} /* end of Cudd_ReadArcviolation */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the value of the arcviolation parameter used
+  in group sifting.]
+
+  Description [Sets the value of the arcviolation
+  parameter. This parameter is used in group sifting to decide how
+  many arcs into <code>y</code> not coming from <code>x</code> are
+  tolerable when checking for aggregation due to extended
+  symmetry. The value should be between 0 and 100. A small value
+  causes fewer variables to be aggregated. The default value is 0.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadArcviolation]
+
+******************************************************************************/
+void
+Cudd_SetArcviolation(
+  DdManager * dd,
+  int  arcviolation)
+{
+    dd->arcviolation = arcviolation;
+
+} /* end of Cudd_SetArcviolation */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the current size of the population used by the
+  genetic algorithm for reordering.]
+
+  Description [Reads the current size of the population used by the
+  genetic algorithm for variable reordering. A larger population size will
+  cause the genetic algorithm to take more time, but will generally
+  produce better results. The default value is 0, in which case the
+  package uses three times the number of variables as population size,
+  with a maximum of 120.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_SetPopulationSize]
+
+******************************************************************************/
+int
+Cudd_ReadPopulationSize(
+  DdManager * dd)
+{
+    return(dd->populationSize);
+
+} /* end of Cudd_ReadPopulationSize */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the size of the population used by the
+  genetic algorithm for reordering.]
+
+  Description [Sets the size of the population used by the
+  genetic algorithm for variable reordering. A larger population size will
+  cause the genetic algorithm to take more time, but will generally
+  produce better results. The default value is 0, in which case the
+  package uses three times the number of variables as population size,
+  with a maximum of 120.]
+
+  SideEffects [Changes the manager.]
+
+  SeeAlso     [Cudd_ReadPopulationSize]
+
+******************************************************************************/
+void
+Cudd_SetPopulationSize(
+  DdManager * dd,
+  int  populationSize)
+{
+    dd->populationSize = populationSize;
+
+} /* end of Cudd_SetPopulationSize */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the current number of crossovers used by the
+  genetic algorithm for reordering.]
+
+  Description [Reads the current number of crossovers used by the
+  genetic algorithm for variable reordering. A larger number of crossovers will
+  cause the genetic algorithm to take more time, but will generally
+  produce better results. The default value is 0, in which case the
+  package uses three times the number of variables as number of crossovers,
+  with a maximum of 60.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_SetNumberXovers]
+
+******************************************************************************/
+int
+Cudd_ReadNumberXovers(
+  DdManager * dd)
+{
+    return(dd->numberXovers);
+
+} /* end of Cudd_ReadNumberXovers */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the number of crossovers used by the
+  genetic algorithm for reordering.]
+
+  Description [Sets the number of crossovers used by the genetic
+  algorithm for variable reordering. A larger number of crossovers
+  will cause the genetic algorithm to take more time, but will
+  generally produce better results. The default value is 0, in which
+  case the package uses three times the number of variables as number
+  of crossovers, with a maximum of 60.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadNumberXovers]
+
+******************************************************************************/
+void
+Cudd_SetNumberXovers(
+  DdManager * dd,
+  int  numberXovers)
+{
+    dd->numberXovers = numberXovers;
+
+} /* end of Cudd_SetNumberXovers */
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the memory in use by the manager measured in bytes.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     []
+
+******************************************************************************/
+unsigned long
+Cudd_ReadMemoryInUse(
+  DdManager * dd)
+{
+    return(dd->memused);
+
+} /* end of Cudd_ReadMemoryInUse */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Prints out statistics and settings for a CUDD manager.]
+
+  Description [Prints out statistics and settings for a CUDD manager.
+  Returns 1 if successful; 0 otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     []
+
+******************************************************************************/
+int
+Cudd_PrintInfo(
+  DdManager * dd,
+  FILE * fp)
+{
+    int retval;
+    Cudd_ReorderingType autoMethod, autoMethodZ;
+
+    /* Modifiable parameters. */
+    retval = fprintf(fp,"**** CUDD modifiable parameters ****\n");
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Hard limit for cache size: %u\n",
+                    Cudd_ReadMaxCacheHard(dd));
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Cache hit threshold for resizing: %u%%\n",
+                    Cudd_ReadMinHit(dd));
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Garbage collection enabled: %s\n",
+                    Cudd_GarbageCollectionEnabled(dd) ? "yes" : "no");
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Limit for fast unique table growth: %u\n",
+                    Cudd_ReadLooseUpTo(dd));
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,
+                    "Maximum number of variables sifted per reordering: %d\n",
+                    Cudd_ReadSiftMaxVar(dd));
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,
+                    "Maximum number of variable swaps per reordering: %d\n",
+                    Cudd_ReadSiftMaxSwap(dd));
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Maximum growth while sifting a variable: %g\n",
+                    Cudd_ReadMaxGrowth(dd));
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Dynamic reordering of BDDs enabled: %s\n",
+                    Cudd_ReorderingStatus(dd,&autoMethod) ? "yes" : "no");
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Default BDD reordering method: %d\n",
+                    (int) autoMethod);
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Dynamic reordering of ZDDs enabled: %s\n",
+                    Cudd_ReorderingStatusZdd(dd,&autoMethodZ) ? "yes" : "no");
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Default ZDD reordering method: %d\n",
+                    (int) autoMethodZ);
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Realignment of ZDDs to BDDs enabled: %s\n",
+                    Cudd_zddRealignmentEnabled(dd) ? "yes" : "no");
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Realignment of BDDs to ZDDs enabled: %s\n",
+                    Cudd_bddRealignmentEnabled(dd) ? "yes" : "no");
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Dead nodes counted in triggering reordering: %s\n",
+                    Cudd_DeadAreCounted(dd) ? "yes" : "no");
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Group checking criterion: %d\n",
+                    (int) Cudd_ReadGroupcheck(dd));
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Recombination threshold: %d\n", Cudd_ReadRecomb(dd));
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Symmetry violation threshold: %d\n",
+                    Cudd_ReadSymmviolation(dd));
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Arc violation threshold: %d\n",
+                    Cudd_ReadArcviolation(dd));
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"GA population size: %d\n",
+                    Cudd_ReadPopulationSize(dd));
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Number of crossovers for GA: %d\n",
+                    Cudd_ReadNumberXovers(dd));
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Next reordering threshold: %u\n",
+                    Cudd_ReadNextReordering(dd));
+    if (retval == EOF) return(0);
+
+    /* Non-modifiable parameters. */
+    retval = fprintf(fp,"**** CUDD non-modifiable parameters ****\n");
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Memory in use: %lu\n", Cudd_ReadMemoryInUse(dd));
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Peak number of nodes: %ld\n",
+                    Cudd_ReadPeakNodeCount(dd));
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Peak number of live nodes: %d\n",
+                    Cudd_ReadPeakLiveNodeCount(dd));
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Number of BDD variables: %d\n", dd->size);
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Number of ZDD variables: %d\n", dd->sizeZ);
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Number of cache entries: %u\n", dd->cacheSlots);
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Number of cache look-ups: %.0f\n",
+                    Cudd_ReadCacheLookUps(dd));
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Number of cache hits: %.0f\n",
+                    Cudd_ReadCacheHits(dd));
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Number of cache insertions: %.0f\n",
+                    dd->cacheinserts);
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Number of cache collisions: %.0f\n",
+                    dd->cachecollisions);
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Number of cache deletions: %.0f\n",
+                    dd->cachedeletions);
+    if (retval == EOF) return(0);
+    retval = cuddCacheProfile(dd,fp);
+    if (retval == 0) return(0);
+    retval = fprintf(fp,"Soft limit for cache size: %u\n",
+                    Cudd_ReadMaxCache(dd));
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Number of buckets in unique table: %u\n", dd->slots);
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Used buckets in unique table: %.2f%% (expected %.2f%%)\n",
+                    100.0 * Cudd_ReadUsedSlots(dd),
+                    100.0 * Cudd_ExpectedUsedSlots(dd));
+    if (retval == EOF) return(0);
+#ifdef DD_UNIQUE_PROFILE
+    retval = fprintf(fp,"Unique lookups: %.0f\n", dd->uniqueLookUps);
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Unique links: %.0f (%g per lookup)\n",
+           dd->uniqueLinks, dd->uniqueLinks / dd->uniqueLookUps);
+    if (retval == EOF) return(0);
+#endif
+    retval = fprintf(fp,"Number of BDD and ADD nodes: %u\n", dd->keys);
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Number of ZDD nodes: %u\n", dd->keysZ);
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Number of dead BDD and ADD nodes: %u\n", dd->dead);
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Number of dead ZDD nodes: %u\n", dd->deadZ);
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Total number of nodes allocated: %.0f\n",
+                    dd->allocated);
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Total number of nodes reclaimed: %.0f\n",
+                    dd->reclaimed);
+    if (retval == EOF) return(0);
+#ifdef DD_STATS
+    retval = fprintf(fp,"Nodes freed: %.0f\n", dd->nodesFreed);
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Nodes dropped: %.0f\n", dd->nodesDropped);
+    if (retval == EOF) return(0);
+#endif
+#ifdef DD_COUNT
+    retval = fprintf(fp,"Number of recursive calls: %.0f\n",
+                    Cudd_ReadRecursiveCalls(dd));
+    if (retval == EOF) return(0);
+#endif
+    retval = fprintf(fp,"Garbage collections so far: %d\n",
+                    Cudd_ReadGarbageCollections(dd));
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Time for garbage collection: %.2f sec\n",
+                    ((double)Cudd_ReadGarbageCollectionTime(dd)/1000.0));
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Reorderings so far: %d\n", dd->reorderings);
+    if (retval == EOF) return(0);
+    retval = fprintf(fp,"Time for reordering: %.2f sec\n",
+                    ((double)Cudd_ReadReorderingTime(dd)/1000.0));
+    if (retval == EOF) return(0);
+#ifdef DD_COUNT
+    retval = fprintf(fp,"Node swaps in reordering: %.0f\n",
+       Cudd_ReadSwapSteps(dd));
+    if (retval == EOF) return(0);
+#endif
+
+    return(1);
+
+} /* end of Cudd_PrintInfo */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reports the peak number of nodes.]
+
+  Description [Reports the peak number of nodes. This number includes
+  node on the free list. At the peak, the number of nodes on the free
+  list is guaranteed to be less than DD_MEM_CHUNK.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadNodeCount Cudd_PrintInfo]
+
+******************************************************************************/
+long
+Cudd_ReadPeakNodeCount(
+  DdManager * dd)
+{
+    long count = 0;
+    DdNodePtr *scan = dd->memoryList;
+
+    while (scan != NULL) {
+       count += DD_MEM_CHUNK;
+       scan = (DdNodePtr *) *scan;
+    }
+    return(count);
+
+} /* end of Cudd_ReadPeakNodeCount */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reports the peak number of live nodes.]
+
+  Description [Reports the peak number of live nodes. This count is kept
+  only if CUDD is compiled with DD_STATS defined. If DD_STATS is not
+  defined, this function returns -1.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadNodeCount Cudd_PrintInfo Cudd_ReadPeakNodeCount]
+
+******************************************************************************/
+int
+Cudd_ReadPeakLiveNodeCount(
+  DdManager * dd)
+{
+    unsigned int live = dd->keys - dd->dead;
+
+    if (live > dd->peakLiveNodes) {
+       dd->peakLiveNodes = live;
+    }
+    return((int)dd->peakLiveNodes);
+
+} /* end of Cudd_ReadPeakLiveNodeCount */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reports the number of nodes in BDDs and ADDs.]
+
+  Description [Reports the number of live nodes in BDDs and ADDs. This
+  number does not include the isolated projection functions and the
+  unused constants. These nodes that are not counted are not part of
+  the DDs manipulated by the application.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadPeakNodeCount Cudd_zddReadNodeCount]
+
+******************************************************************************/
+long
+Cudd_ReadNodeCount(
+  DdManager * dd)
+{
+    long count;
+    int i;
+
+#ifndef DD_NO_DEATH_ROW
+    cuddClearDeathRow(dd);
+#endif
+
+    count = (long) (dd->keys - dd->dead);
+
+    /* Count isolated projection functions. Their number is subtracted
+    ** from the node count because they are not part of the BDDs.
+    */
+    for (i=0; i < dd->size; i++) {
+       if (dd->vars[i]->ref == 1) count--;
+    }
+    /* Subtract from the count the unused constants. */
+    if (DD_ZERO(dd)->ref == 1) count--;
+    if (DD_PLUS_INFINITY(dd)->ref == 1) count--;
+    if (DD_MINUS_INFINITY(dd)->ref == 1) count--;
+
+    return(count);
+
+} /* end of Cudd_ReadNodeCount */
+
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reports the number of nodes in ZDDs.]
+
+  Description [Reports the number of nodes in ZDDs. This
+  number always includes the two constants 1 and 0.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadPeakNodeCount Cudd_ReadNodeCount]
+
+******************************************************************************/
+long
+Cudd_zddReadNodeCount(
+  DdManager * dd)
+{
+    return((long)(dd->keysZ - dd->deadZ + 2));
+
+} /* end of Cudd_zddReadNodeCount */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Adds a function to a hook.]
+
+  Description [Adds a function to a hook. A hook is a list of
+  application-provided functions called on certain occasions by the
+  package. Returns 1 if the function is successfully added; 2 if the
+  function was already in the list; 0 otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_RemoveHook]
+
+******************************************************************************/
+int
+Cudd_AddHook(
+  DdManager * dd,
+  DD_HFP f,
+  Cudd_HookType where)
+{
+    DdHook **hook, *nextHook, *newHook;
+
+    switch (where) {
+    case CUDD_PRE_GC_HOOK:
+       hook = &(dd->preGCHook);
+       break;
+    case CUDD_POST_GC_HOOK:
+       hook = &(dd->postGCHook);
+       break;
+    case CUDD_PRE_REORDERING_HOOK:
+       hook = &(dd->preReorderingHook);
+       break;
+    case CUDD_POST_REORDERING_HOOK:
+       hook = &(dd->postReorderingHook);
+       break;
+    default:
+       return(0);
+    }
+    /* Scan the list and find whether the function is already there.
+    ** If so, just return. */
+    nextHook = *hook;
+    while (nextHook != NULL) {
+       if (nextHook->f == f) {
+           return(2);
+       }
+       hook = &(nextHook->next);
+       nextHook = nextHook->next;
+    }
+    /* The function was not in the list. Create a new item and append it
+    ** to the end of the list. */
+    newHook = ALLOC(DdHook,1);
+    if (newHook == NULL) {
+       dd->errorCode = CUDD_MEMORY_OUT;
+       return(0);
+    }
+    newHook->next = NULL;
+    newHook->f = f;
+    *hook = newHook;
+    return(1);
+
+} /* end of Cudd_AddHook */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Removes a function from a hook.]
+
+  Description [Removes a function from a hook. A hook is a list of
+  application-provided functions called on certain occasions by the
+  package. Returns 1 if successful; 0 the function was not in the list.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_AddHook]
+
+******************************************************************************/
+int
+Cudd_RemoveHook(
+  DdManager * dd,
+  DD_HFP f,
+  Cudd_HookType where)
+{
+    DdHook **hook, *nextHook;
+
+    switch (where) {
+    case CUDD_PRE_GC_HOOK:
+       hook = &(dd->preGCHook);
+       break;
+    case CUDD_POST_GC_HOOK:
+       hook = &(dd->postGCHook);
+       break;
+    case CUDD_PRE_REORDERING_HOOK:
+       hook = &(dd->preReorderingHook);
+       break;
+    case CUDD_POST_REORDERING_HOOK:
+       hook = &(dd->postReorderingHook);
+       break;
+    default:
+       return(0);
+    }
+    nextHook = *hook;
+    while (nextHook != NULL) {
+       if (nextHook->f == f) {
+           *hook = nextHook->next;
+           FREE(nextHook);
+           return(1);
+       }
+       hook = &(nextHook->next);
+       nextHook = nextHook->next;
+    }
+
+    return(0);
+
+} /* end of Cudd_RemoveHook */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Checks whether a function is in a hook.]
+
+  Description [Checks whether a function is in a hook. A hook is a list of
+  application-provided functions called on certain occasions by the
+  package. Returns 1 if the function is found; 0 otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_AddHook Cudd_RemoveHook]
+
+******************************************************************************/
+int
+Cudd_IsInHook(
+  DdManager * dd,
+  DD_HFP f,
+  Cudd_HookType where)
+{
+    DdHook *hook;
+
+    switch (where) {
+    case CUDD_PRE_GC_HOOK:
+       hook = dd->preGCHook;
+       break;
+    case CUDD_POST_GC_HOOK:
+       hook = dd->postGCHook;
+       break;
+    case CUDD_PRE_REORDERING_HOOK:
+       hook = dd->preReorderingHook;
+       break;
+    case CUDD_POST_REORDERING_HOOK:
+       hook = dd->postReorderingHook;
+       break;
+    default:
+       return(0);
+    }
+    /* Scan the list and find whether the function is already there. */
+    while (hook != NULL) {
+       if (hook->f == f) {
+           return(1);
+       }
+       hook = hook->next;
+    }
+    return(0);
+
+} /* end of Cudd_IsInHook */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sample hook function to call before reordering.]
+
+  Description [Sample hook function to call before reordering.
+  Prints on the manager's stdout reordering method and initial size.
+  Returns 1 if successful; 0 otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_StdPostReordHook]
+
+******************************************************************************/
+int
+Cudd_StdPreReordHook(
+  DdManager *dd,
+  const char *str,
+  void *data)
+{
+    Cudd_ReorderingType method = (Cudd_ReorderingType) (ptruint) data;
+    int retval;
+
+    retval = fprintf(dd->out,"%s reordering with ", str);
+    if (retval == EOF) return(0);
+    switch (method) {
+    case CUDD_REORDER_SIFT_CONVERGE:
+    case CUDD_REORDER_SYMM_SIFT_CONV:
+    case CUDD_REORDER_GROUP_SIFT_CONV:
+    case CUDD_REORDER_WINDOW2_CONV:
+    case CUDD_REORDER_WINDOW3_CONV:
+    case CUDD_REORDER_WINDOW4_CONV:
+    case CUDD_REORDER_LINEAR_CONVERGE:
+       retval = fprintf(dd->out,"converging ");
+       if (retval == EOF) return(0);
+       break;
+    default:
+       break;
+    }
+    switch (method) {
+    case CUDD_REORDER_RANDOM:
+    case CUDD_REORDER_RANDOM_PIVOT:
+       retval = fprintf(dd->out,"random");
+       break;
+    case CUDD_REORDER_SIFT:
+    case CUDD_REORDER_SIFT_CONVERGE:
+       retval = fprintf(dd->out,"sifting");
+       break;
+    case CUDD_REORDER_SYMM_SIFT:
+    case CUDD_REORDER_SYMM_SIFT_CONV:
+       retval = fprintf(dd->out,"symmetric sifting");
+       break;
+    case CUDD_REORDER_LAZY_SIFT:
+       retval = fprintf(dd->out,"lazy sifting");
+       break;
+    case CUDD_REORDER_GROUP_SIFT:
+    case CUDD_REORDER_GROUP_SIFT_CONV:
+       retval = fprintf(dd->out,"group sifting");
+       break;
+    case CUDD_REORDER_WINDOW2:
+    case CUDD_REORDER_WINDOW3:
+    case CUDD_REORDER_WINDOW4:
+    case CUDD_REORDER_WINDOW2_CONV:
+    case CUDD_REORDER_WINDOW3_CONV:
+    case CUDD_REORDER_WINDOW4_CONV:
+       retval = fprintf(dd->out,"window");
+       break;
+    case CUDD_REORDER_ANNEALING:
+       retval = fprintf(dd->out,"annealing");
+       break;
+    case CUDD_REORDER_GENETIC:
+       retval = fprintf(dd->out,"genetic");
+       break;
+    case CUDD_REORDER_LINEAR:
+    case CUDD_REORDER_LINEAR_CONVERGE:
+       retval = fprintf(dd->out,"linear sifting");
+       break;
+    case CUDD_REORDER_EXACT:
+       retval = fprintf(dd->out,"exact");
+       break;
+    default:
+       return(0);
+    }
+    if (retval == EOF) return(0);
+
+    retval = fprintf(dd->out,": from %ld to ... ", strcmp(str, "BDD") == 0 ?
+                    Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd));
+    if (retval == EOF) return(0);
+    fflush(dd->out);
+    return(1);
+
+} /* end of Cudd_StdPreReordHook */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sample hook function to call after reordering.]
+
+  Description [Sample hook function to call after reordering.
+  Prints on the manager's stdout final size and reordering time.
+  Returns 1 if successful; 0 otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_StdPreReordHook]
+
+******************************************************************************/
+int
+Cudd_StdPostReordHook(
+  DdManager *dd,
+  const char *str,
+  void *data)
+{
+    long initialTime = (long) data;
+    int retval;
+    long finalTime = util_cpu_time();
+    double totalTimeSec = (double)(finalTime - initialTime) / 1000.0;
+
+    retval = fprintf(dd->out,"%ld nodes in %g sec\n", strcmp(str, "BDD") == 0 ?
+                    Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd),
+                    totalTimeSec);
+    if (retval == EOF) return(0);
+    retval = fflush(dd->out);
+    if (retval == EOF) return(0);
+    return(1);
+
+} /* end of Cudd_StdPostReordHook */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Enables reporting of reordering stats.]
+
+  Description [Enables reporting of reordering stats.
+  Returns 1 if successful; 0 otherwise.]
+
+  SideEffects [Installs functions in the pre-reordering and post-reordering
+  hooks.]
+
+  SeeAlso     [Cudd_DisableReorderingReporting Cudd_ReorderingReporting]
+
+******************************************************************************/
+int
+Cudd_EnableReorderingReporting(
+  DdManager *dd)
+{
+    if (!Cudd_AddHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) {
+       return(0);
+    }
+    if (!Cudd_AddHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) {
+       return(0);
+    }
+    return(1);
+
+} /* end of Cudd_EnableReorderingReporting */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Disables reporting of reordering stats.]
+
+  Description [Disables reporting of reordering stats.
+  Returns 1 if successful; 0 otherwise.]
+
+  SideEffects [Removes functions from the pre-reordering and post-reordering
+  hooks.]
+
+  SeeAlso     [Cudd_EnableReorderingReporting Cudd_ReorderingReporting]
+
+******************************************************************************/
+int
+Cudd_DisableReorderingReporting(
+  DdManager *dd)
+{
+    if (!Cudd_RemoveHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) {
+       return(0);
+    }
+    if (!Cudd_RemoveHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) {
+       return(0);
+    }
+    return(1);
+
+} /* end of Cudd_DisableReorderingReporting */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns 1 if reporting of reordering stats is enabled.]
+
+  Description [Returns 1 if reporting of reordering stats is enabled;
+  0 otherwise.]
+
+  SideEffects [none]
+
+  SeeAlso     [Cudd_EnableReorderingReporting Cudd_DisableReorderingReporting]
+
+******************************************************************************/
+int
+Cudd_ReorderingReporting(
+  DdManager *dd)
+{
+    return(Cudd_IsInHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK));
+
+} /* end of Cudd_ReorderingReporting */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the code of the last error.]
+
+  Description [Returns the code of the last error. The error codes are
+  defined in cudd.h.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ClearErrorCode]
+
+******************************************************************************/
+Cudd_ErrorType
+Cudd_ReadErrorCode(
+  DdManager *dd)
+{
+    return(dd->errorCode);
+
+} /* end of Cudd_ReadErrorCode */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Clear the error code of a manager.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadErrorCode]
+
+******************************************************************************/
+void
+Cudd_ClearErrorCode(
+  DdManager *dd)
+{
+    dd->errorCode = CUDD_NO_ERROR;
+
+} /* end of Cudd_ClearErrorCode */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the stdout of a manager.]
+
+  Description [Reads the stdout of a manager. This is the file pointer to
+  which messages normally going to stdout are written. It is initialized
+  to stdout. Cudd_SetStdout allows the application to redirect it.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_SetStdout Cudd_ReadStderr]
+
+******************************************************************************/
+FILE *
+Cudd_ReadStdout(
+  DdManager *dd)
+{
+    return(dd->out);
+
+} /* end of Cudd_ReadStdout */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the stdout of a manager.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadStdout Cudd_SetStderr]
+
+******************************************************************************/
+void
+Cudd_SetStdout(
+  DdManager *dd,
+  FILE *fp)
+{
+    dd->out = fp;
+
+} /* end of Cudd_SetStdout */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the stderr of a manager.]
+
+  Description [Reads the stderr of a manager. This is the file pointer to
+  which messages normally going to stderr are written. It is initialized
+  to stderr. Cudd_SetStderr allows the application to redirect it.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_SetStderr Cudd_ReadStdout]
+
+******************************************************************************/
+FILE *
+Cudd_ReadStderr(
+  DdManager *dd)
+{
+    return(dd->err);
+
+} /* end of Cudd_ReadStderr */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the stderr of a manager.]
+
+  Description []
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadStderr Cudd_SetStdout]
+
+******************************************************************************/
+void
+Cudd_SetStderr(
+  DdManager *dd,
+  FILE *fp)
+{
+    dd->err = fp;
+
+} /* end of Cudd_SetStderr */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns the threshold for the next dynamic reordering.]
+
+  Description [Returns the threshold for the next dynamic reordering.
+  The threshold is in terms of number of nodes and is in effect only
+  if reordering is enabled. The count does not include the dead nodes,
+  unless the countDead parameter of the manager has been changed from
+  its default setting.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_SetNextReordering]
+
+******************************************************************************/
+unsigned int
+Cudd_ReadNextReordering(
+  DdManager *dd)
+{
+    return(dd->nextDyn);
+
+} /* end of Cudd_ReadNextReordering */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the threshold for the next dynamic reordering.]
+
+  Description [Sets the threshold for the next dynamic reordering.
+  The threshold is in terms of number of nodes and is in effect only
+  if reordering is enabled. The count does not include the dead nodes,
+  unless the countDead parameter of the manager has been changed from
+  its default setting.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_ReadNextReordering]
+
+******************************************************************************/
+void
+Cudd_SetNextReordering(
+  DdManager *dd,
+  unsigned int next)
+{
+    dd->nextDyn = next;
+
+} /* end of Cudd_SetNextReordering */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the number of elementary reordering steps.]
+
+  Description []
+
+  SideEffects [none]
+
+  SeeAlso     []
+
+******************************************************************************/
+double
+Cudd_ReadSwapSteps(
+  DdManager *dd)
+{
+#ifdef DD_COUNT
+    return(dd->swapSteps);
+#else
+    return(-1);
+#endif
+
+} /* end of Cudd_ReadSwapSteps */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the maximum allowed number of live nodes.]
+
+  Description [Reads the maximum allowed number of live nodes. When this
+  number is exceeded, the package returns NULL.]
+
+  SideEffects [none]
+
+  SeeAlso     [Cudd_SetMaxLive]
+
+******************************************************************************/
+unsigned int
+Cudd_ReadMaxLive(
+  DdManager *dd)
+{
+    return(dd->maxLive);
+
+} /* end of Cudd_ReadMaxLive */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the maximum allowed number of live nodes.]
+
+  Description [Sets the maximum allowed number of live nodes. When this
+  number is exceeded, the package returns NULL.]
+
+  SideEffects [none]
+
+  SeeAlso     [Cudd_ReadMaxLive]
+
+******************************************************************************/
+void
+Cudd_SetMaxLive(
+  DdManager *dd,
+  unsigned int maxLive)
+{
+    dd->maxLive = maxLive;
+
+} /* end of Cudd_SetMaxLive */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads the maximum allowed memory.]
+
+  Description [Reads the maximum allowed memory. When this
+  number is exceeded, the package returns NULL.]
+
+  SideEffects [none]
+
+  SeeAlso     [Cudd_SetMaxMemory]
+
+******************************************************************************/
+unsigned long
+Cudd_ReadMaxMemory(
+  DdManager *dd)
+{
+    return(dd->maxmemhard);
+
+} /* end of Cudd_ReadMaxMemory */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets the maximum allowed memory.]
+
+  Description [Sets the maximum allowed memory. When this
+  number is exceeded, the package returns NULL.]
+
+  SideEffects [none]
+
+  SeeAlso     [Cudd_ReadMaxMemory]
+
+******************************************************************************/
+void
+Cudd_SetMaxMemory(
+  DdManager *dd,
+  unsigned long maxMemory)
+{
+    dd->maxmemhard = maxMemory;
+
+} /* end of Cudd_SetMaxMemory */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Prevents sifting of a variable.]
+
+  Description [This function sets a flag to prevent sifting of a
+  variable.  Returns 1 if successful; 0 otherwise (i.e., invalid
+  variable index).]
+
+  SideEffects [Changes the "bindVar" flag in DdSubtable.]
+
+  SeeAlso     [Cudd_bddUnbindVar]
+
+******************************************************************************/
+int
+Cudd_bddBindVar(
+  DdManager *dd /* manager */,
+  int index /* variable index */)
+{
+    if (index >= dd->size || index < 0) return(0);
+    dd->subtables[dd->perm[index]].bindVar = 1;
+    return(1);
+
+} /* end of Cudd_bddBindVar */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Allows the sifting of a variable.]
+
+  Description [This function resets the flag that prevents the sifting
+  of a variable. In successive variable reorderings, the variable will
+  NOT be skipped, that is, sifted.  Initially all variables can be
+  sifted. It is necessary to call this function only to re-enable
+  sifting after a call to Cudd_bddBindVar. Returns 1 if successful; 0
+  otherwise (i.e., invalid variable index).]
+
+  SideEffects [Changes the "bindVar" flag in DdSubtable.]
+
+  SeeAlso     [Cudd_bddBindVar]
+
+******************************************************************************/
+int
+Cudd_bddUnbindVar(
+  DdManager *dd /* manager */,
+  int index /* variable index */)
+{
+    if (index >= dd->size || index < 0) return(0);
+    dd->subtables[dd->perm[index]].bindVar = 0;
+    return(1);
+
+} /* end of Cudd_bddUnbindVar */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Tells whether a variable can be sifted.]
+
+  Description [This function returns 1 if a variable is enabled for
+  sifting.  Initially all variables can be sifted. This function returns
+  0 only if there has been a previous call to Cudd_bddBindVar for that
+  variable not followed by a call to Cudd_bddUnbindVar. The function returns
+  0 also in the case in which the index of the variable is out of bounds.]
+
+  SideEffects [none]
+
+  SeeAlso     [Cudd_bddBindVar Cudd_bddUnbindVar]
+
+******************************************************************************/
+int
+Cudd_bddVarIsBound(
+  DdManager *dd /* manager */,
+  int index /* variable index */)
+{
+    if (index >= dd->size || index < 0) return(0);
+    return(dd->subtables[dd->perm[index]].bindVar);
+
+} /* end of Cudd_bddVarIsBound */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets a variable type to primary input.]
+
+  Description [Sets a variable type to primary input.  The variable type is
+  used by lazy sifting.  Returns 1 if successful; 0 otherwise.]
+
+  SideEffects [modifies the manager]
+
+  SeeAlso     [Cudd_bddSetPsVar Cudd_bddSetNsVar Cudd_bddIsPiVar]
+
+******************************************************************************/
+int
+Cudd_bddSetPiVar(
+  DdManager *dd /* manager */,
+  int index /* variable index */)
+{
+    if (index >= dd->size || index < 0) return (0);
+    dd->subtables[dd->perm[index]].varType = CUDD_VAR_PRIMARY_INPUT;
+    return(1);
+
+} /* end of Cudd_bddSetPiVar */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets a variable type to present state.]
+
+  Description [Sets a variable type to present state.  The variable type is
+  used by lazy sifting.  Returns 1 if successful; 0 otherwise.]
+
+  SideEffects [modifies the manager]
+
+  SeeAlso     [Cudd_bddSetPiVar Cudd_bddSetNsVar Cudd_bddIsPsVar]
+
+******************************************************************************/
+int
+Cudd_bddSetPsVar(
+  DdManager *dd /* manager */,
+  int index /* variable index */)
+{
+    if (index >= dd->size || index < 0) return (0);
+    dd->subtables[dd->perm[index]].varType = CUDD_VAR_PRESENT_STATE;
+    return(1);
+
+} /* end of Cudd_bddSetPsVar */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets a variable type to next state.]
+
+  Description [Sets a variable type to next state.  The variable type is
+  used by lazy sifting.  Returns 1 if successful; 0 otherwise.]
+
+  SideEffects [modifies the manager]
+
+  SeeAlso     [Cudd_bddSetPiVar Cudd_bddSetPsVar Cudd_bddIsNsVar]
+
+******************************************************************************/
+int
+Cudd_bddSetNsVar(
+  DdManager *dd /* manager */,
+  int index /* variable index */)
+{
+    if (index >= dd->size || index < 0) return (0);
+    dd->subtables[dd->perm[index]].varType = CUDD_VAR_NEXT_STATE;
+    return(1);
+
+} /* end of Cudd_bddSetNsVar */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Checks whether a variable is primary input.]
+
+  Description [Checks whether a variable is primary input.  Returns 1 if
+  the variable's type is primary input; 0 if the variable exists but is
+  not a primary input; -1 if the variable does not exist.]
+
+  SideEffects [none]
+
+  SeeAlso     [Cudd_bddSetPiVar Cudd_bddIsPsVar Cudd_bddIsNsVar]
+
+******************************************************************************/
+int
+Cudd_bddIsPiVar(
+  DdManager *dd /* manager */,
+  int index /* variable index */)
+{
+    if (index >= dd->size || index < 0) return -1;
+    return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_PRIMARY_INPUT);
+
+} /* end of Cudd_bddIsPiVar */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Checks whether a variable is present state.]
+
+  Description [Checks whether a variable is present state.  Returns 1 if
+  the variable's type is present state; 0 if the variable exists but is
+  not a present state; -1 if the variable does not exist.]
+
+  SideEffects [none]
+
+  SeeAlso     [Cudd_bddSetPsVar Cudd_bddIsPiVar Cudd_bddIsNsVar]
+
+******************************************************************************/
+int
+Cudd_bddIsPsVar(
+  DdManager *dd,
+  int index)
+{
+    if (index >= dd->size || index < 0) return -1;
+    return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_PRESENT_STATE);
+
+} /* end of Cudd_bddIsPsVar */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Checks whether a variable is next state.]
+
+  Description [Checks whether a variable is next state.  Returns 1 if
+  the variable's type is present state; 0 if the variable exists but is
+  not a present state; -1 if the variable does not exist.]
+
+  SideEffects [none]
+
+  SeeAlso     [Cudd_bddSetNsVar Cudd_bddIsPiVar Cudd_bddIsPsVar]
+
+******************************************************************************/
+int
+Cudd_bddIsNsVar(
+  DdManager *dd,
+  int index)
+{
+    if (index >= dd->size || index < 0) return -1;
+    return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_NEXT_STATE);
+
+} /* end of Cudd_bddIsNsVar */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets a corresponding pair index for a given index.]
+
+  Description [Sets a corresponding pair index for a given index.
+  These pair indices are present and next state variable.  Returns 1 if
+  successful; 0 otherwise.]
+
+  SideEffects [modifies the manager]
+
+  SeeAlso     [Cudd_bddReadPairIndex]
+
+******************************************************************************/
+int
+Cudd_bddSetPairIndex(
+  DdManager *dd /* manager */,
+  int index /* variable index */,
+  int pairIndex /* corresponding variable index */)
+{
+    if (index >= dd->size || index < 0) return(0);
+    dd->subtables[dd->perm[index]].pairIndex = pairIndex;
+    return(1);
+
+} /* end of Cudd_bddSetPairIndex */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Reads a corresponding pair index for a given index.]
+
+  Description [Reads a corresponding pair index for a given index.
+  These pair indices are present and next state variable.  Returns the
+  corresponding variable index if the variable exists; -1 otherwise.]
+
+  SideEffects [modifies the manager]
+
+  SeeAlso     [Cudd_bddSetPairIndex]
+
+******************************************************************************/
+int
+Cudd_bddReadPairIndex(
+  DdManager *dd,
+  int index)
+{
+    if (index >= dd->size || index < 0) return -1;
+    return dd->subtables[dd->perm[index]].pairIndex;
+
+} /* end of Cudd_bddReadPairIndex */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets a variable to be grouped.]
+
+  Description [Sets a variable to be grouped. This function is used for
+  lazy sifting.  Returns 1 if successful; 0 otherwise.]
+
+  SideEffects [modifies the manager]
+
+  SeeAlso     [Cudd_bddSetVarHardGroup Cudd_bddResetVarToBeGrouped]
+
+******************************************************************************/
+int
+Cudd_bddSetVarToBeGrouped(
+  DdManager *dd,
+  int index)
+{
+    if (index >= dd->size || index < 0) return(0);
+    if (dd->subtables[dd->perm[index]].varToBeGrouped <= CUDD_LAZY_SOFT_GROUP) {
+       dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_SOFT_GROUP;
+    }
+    return(1);
+
+} /* end of Cudd_bddSetVarToBeGrouped */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets a variable to be a hard group.]
+
+  Description [Sets a variable to be a hard group.  This function is used
+  for lazy sifting.  Returns 1 if successful; 0 otherwise.]
+
+  SideEffects [modifies the manager]
+
+  SeeAlso     [Cudd_bddSetVarToBeGrouped Cudd_bddResetVarToBeGrouped
+  Cudd_bddIsVarHardGroup]
+
+******************************************************************************/
+int
+Cudd_bddSetVarHardGroup(
+  DdManager *dd,
+  int index)
+{
+    if (index >= dd->size || index < 0) return(0);
+    dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_HARD_GROUP;
+    return(1);
+
+} /* end of Cudd_bddSetVarHardGrouped */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Resets a variable not to be grouped.]
+
+  Description [Resets a variable not to be grouped.  This function is
+  used for lazy sifting.  Returns 1 if successful; 0 otherwise.]
+
+  SideEffects [modifies the manager]
+
+  SeeAlso     [Cudd_bddSetVarToBeGrouped Cudd_bddSetVarHardGroup]
+
+******************************************************************************/
+int
+Cudd_bddResetVarToBeGrouped(
+  DdManager *dd,
+  int index)
+{
+    if (index >= dd->size || index < 0) return(0);
+    if (dd->subtables[dd->perm[index]].varToBeGrouped <=
+       CUDD_LAZY_SOFT_GROUP) {
+       dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_NONE;
+    }
+    return(1);
+
+} /* end of Cudd_bddResetVarToBeGrouped */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Checks whether a variable is set to be grouped.]
+
+  Description [Checks whether a variable is set to be grouped. This
+  function is used for lazy sifting.]
+
+  SideEffects [none]
+
+  SeeAlso     []
+
+******************************************************************************/
+int
+Cudd_bddIsVarToBeGrouped(
+  DdManager *dd,
+  int index)
+{
+    if (index >= dd->size || index < 0) return(-1);
+    if (dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_UNGROUP)
+       return(0);
+    else
+       return(dd->subtables[dd->perm[index]].varToBeGrouped);
+
+} /* end of Cudd_bddIsVarToBeGrouped */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Sets a variable to be ungrouped.]
+
+  Description [Sets a variable to be ungrouped. This function is used
+  for lazy sifting.  Returns 1 if successful; 0 otherwise.]
+
+  SideEffects [modifies the manager]
+
+  SeeAlso     [Cudd_bddIsVarToBeUngrouped]
+
+******************************************************************************/
+int
+Cudd_bddSetVarToBeUngrouped(
+  DdManager *dd,
+  int index)
+{
+    if (index >= dd->size || index < 0) return(0);
+    dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_UNGROUP;
+    return(1);
+
+} /* end of Cudd_bddSetVarToBeGrouped */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Checks whether a variable is set to be ungrouped.]
+
+  Description [Checks whether a variable is set to be ungrouped. This
+  function is used for lazy sifting.  Returns 1 if the variable is marked
+  to be ungrouped; 0 if the variable exists, but it is not marked to be
+  ungrouped; -1 if the variable does not exist.]
+
+  SideEffects [none]
+
+  SeeAlso     [Cudd_bddSetVarToBeUngrouped]
+
+******************************************************************************/
+int
+Cudd_bddIsVarToBeUngrouped(
+  DdManager *dd,
+  int index)
+{
+    if (index >= dd->size || index < 0) return(-1);
+    return dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_UNGROUP;
+
+} /* end of Cudd_bddIsVarToBeGrouped */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Checks whether a variable is set to be in a hard group.]
+
+  Description [Checks whether a variable is set to be in a hard group.  This
+  function is used for lazy sifting.  Returns 1 if the variable is marked
+  to be in a hard group; 0 if the variable exists, but it is not marked to be
+  in a hard group; -1 if the variable does not exist.]
+
+  SideEffects [none]
+
+  SeeAlso     [Cudd_bddSetVarHardGroup]
+
+******************************************************************************/
+int
+Cudd_bddIsVarHardGroup(
+  DdManager *dd,
+  int index)
+{
+    if (index >= dd->size || index < 0) return(-1);
+    if (dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_HARD_GROUP)
+       return(1);
+    return(0);
+
+} /* end of Cudd_bddIsVarToBeGrouped */
+
+
+/*---------------------------------------------------------------------------*/
+/* Definition of internal functions                                          */
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/* Definition of static functions                                            */
+/*---------------------------------------------------------------------------*/
+
+
+/**Function********************************************************************
+
+  Synopsis    [Fixes a variable group tree.]
+
+  Description []
+
+  SideEffects [Changes the variable group tree.]
+
+  SeeAlso     []
+
+******************************************************************************/
+static void
+fixVarTree(
+  MtrNode * treenode,
+  int * perm,
+  int  size)
+{
+    treenode->index = treenode->low;
+    treenode->low = ((int) treenode->index < size) ?
+       perm[treenode->index] : treenode->index;
+    if (treenode->child != NULL)
+       fixVarTree(treenode->child, perm, size);
+    if (treenode->younger != NULL)
+       fixVarTree(treenode->younger, perm, size);
+    return;
+
+} /* end of fixVarTree */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Adds multiplicity groups to a ZDD variable group tree.]
+
+  Description [Adds multiplicity groups to a ZDD variable group tree.
+  Returns 1 if successful; 0 otherwise. This function creates the groups
+  for set of ZDD variables (whose cardinality is given by parameter
+  multiplicity) that are created for each BDD variable in
+  Cudd_zddVarsFromBddVars. The crux of the matter is to determine the index
+  each new group. (The index of the first variable in the group.)
+  We first build all the groups for the children of a node, and then deal
+  with the ZDD variables that are directly attached to the node. The problem
+  for these is that the tree itself does not provide information on their
+  position inside the group. While we deal with the children of the node,
+  therefore, we keep track of all the positions they occupy. The remaining
+  positions in the tree can be freely used. Also, we keep track of all the
+  variables placed in the children. All the remaining variables are directly
+  attached to the group. We can then place any pair of variables not yet
+  grouped in any pair of available positions in the node.]
+
+  SideEffects [Changes the variable group tree.]
+
+  SeeAlso     [Cudd_zddVarsFromBddVars]
+
+******************************************************************************/
+static int
+addMultiplicityGroups(
+  DdManager *dd /* manager */,
+  MtrNode *treenode /* current tree node */,
+  int multiplicity /* how many ZDD vars per BDD var */,
+  char *vmask /* variable pairs for which a group has been already built */,
+  char *lmask /* levels for which a group has already been built*/)
+{
+    int startV, stopV, startL;
+    int i, j;
+    MtrNode *auxnode = treenode;
+
+    while (auxnode != NULL) {
+       if (auxnode->child != NULL) {
+           addMultiplicityGroups(dd,auxnode->child,multiplicity,vmask,lmask);
+       }
+       /* Build remaining groups. */
+       startV = dd->permZ[auxnode->index] / multiplicity;
+       startL = auxnode->low / multiplicity;
+       stopV = startV + auxnode->size / multiplicity;
+       /* Walk down vmask starting at startV and build missing groups. */
+       for (i = startV, j = startL; i < stopV; i++) {
+           if (vmask[i] == 0) {
+               MtrNode *node;
+               while (lmask[j] == 1) j++;
+               node = Mtr_MakeGroup(auxnode, j * multiplicity, multiplicity,
+                                    MTR_FIXED);
+               if (node == NULL) {
+                   return(0);
+               }
+               node->index = dd->invpermZ[i * multiplicity];
+               vmask[i] = 1;
+               lmask[j] = 1;
+           }
+       }
+       auxnode = auxnode->younger;
+    }
+    return(1);
+
+} /* end of addMultiplicityGroups */
diff --git a/distr/cudd/cuddAddAbs.c b/distr/cudd/cuddAddAbs.c
new file mode 100644 (file)
index 0000000..4e9012e
--- /dev/null
@@ -0,0 +1,579 @@
+/**CFile***********************************************************************
+
+  FileName    [cuddAddAbs.c]
+
+  PackageName [cudd]
+
+  Synopsis    [Quantification functions for ADDs.]
+
+  Description [External procedures included in this module:
+               <ul>
+               <li> Cudd_addExistAbstract()
+               <li> Cudd_addUnivAbstract()
+               <li> Cudd_addOrAbstract()
+               </ul>
+       Internal procedures included in this module:
+               <ul>
+               <li> cuddAddExistAbstractRecur()
+               <li> cuddAddUnivAbstractRecur()
+               <li> cuddAddOrAbstractRecur()
+               </ul>
+       Static procedures included in this module:
+               <ul>
+               <li> addCheckPositiveCube()
+               </ul>]
+
+  Author      [Fabio Somenzi]
+
+  Copyright   [Copyright (c) 1995-2004, Regents of the University of Colorado
+
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+  Redistributions of source code must retain the above copyright
+  notice, this list of conditions and the following disclaimer.
+
+  Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in the
+  documentation and/or other materials provided with the distribution.
+
+  Neither the name of the University of Colorado nor the names of its
+  contributors may be used to endorse or promote products derived from
+  this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.]
+
+******************************************************************************/
+
+#include "util.h"
+#include "cuddInt.h"
+
+/*---------------------------------------------------------------------------*/
+/* Constant declarations                                                     */
+/*---------------------------------------------------------------------------*/
+
+
+/*---------------------------------------------------------------------------*/
+/* Stucture declarations                                                     */
+/*---------------------------------------------------------------------------*/
+
+
+/*---------------------------------------------------------------------------*/
+/* Type declarations                                                         */
+/*---------------------------------------------------------------------------*/
+
+
+/*---------------------------------------------------------------------------*/
+/* Variable declarations                                                     */
+/*---------------------------------------------------------------------------*/
+
+#ifndef lint
+static char rcsid[] DD_UNUSED = "$Id: cuddAddAbs.c,v 1.15 2004/08/13 18:04:45 fabio Exp $";
+#endif
+
+static DdNode  *two;
+
+/*---------------------------------------------------------------------------*/
+/* Macro declarations                                                        */
+/*---------------------------------------------------------------------------*/
+
+
+/**AutomaticStart*************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* Static function prototypes                                                */
+/*---------------------------------------------------------------------------*/
+
+static int addCheckPositiveCube (DdManager *manager, DdNode *cube);
+
+/**AutomaticEnd***************************************************************/
+
+
+/*---------------------------------------------------------------------------*/
+/* Definition of exported functions                                          */
+/*---------------------------------------------------------------------------*/
+
+/**Function********************************************************************
+
+  Synopsis    [Existentially Abstracts all the variables in cube from f.]
+
+  Description [Abstracts all the variables in cube from f by summing
+  over all possible values taken by the variables. Returns the
+  abstracted ADD.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addUnivAbstract Cudd_bddExistAbstract
+  Cudd_addOrAbstract]
+
+******************************************************************************/
+DdNode *
+Cudd_addExistAbstract(
+  DdManager * manager,
+  DdNode * f,
+  DdNode * cube)
+{
+    DdNode *res;
+
+    two = cuddUniqueConst(manager,(CUDD_VALUE_TYPE) 2);
+    if (two == NULL) return(NULL);
+    cuddRef(two);
+
+    if (addCheckPositiveCube(manager, cube) == 0) {
+        (void) fprintf(manager->err,"Error: Can only abstract cubes");
+        return(NULL);
+    }
+
+    do {
+       manager->reordered = 0;
+       res = cuddAddExistAbstractRecur(manager, f, cube);
+    } while (manager->reordered == 1);
+
+    if (res == NULL) {
+       Cudd_RecursiveDeref(manager,two);
+       return(NULL);
+    }
+    cuddRef(res);
+    Cudd_RecursiveDeref(manager,two);
+    cuddDeref(res);
+
+    return(res);
+
+} /* end of Cudd_addExistAbstract */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Universally Abstracts all the variables in cube from f.]
+
+  Description [Abstracts all the variables in cube from f by taking
+  the product over all possible values taken by the variable. Returns
+  the abstracted ADD if successful; NULL otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addExistAbstract Cudd_bddUnivAbstract
+  Cudd_addOrAbstract]
+
+******************************************************************************/
+DdNode *
+Cudd_addUnivAbstract(
+  DdManager * manager,
+  DdNode * f,
+  DdNode * cube)
+{
+    DdNode             *res;
+
+    if (addCheckPositiveCube(manager, cube) == 0) {
+       (void) fprintf(manager->err,"Error:  Can only abstract cubes");
+       return(NULL);
+    }
+
+    do {
+       manager->reordered = 0;
+       res = cuddAddUnivAbstractRecur(manager, f, cube);
+    } while (manager->reordered == 1);
+
+    return(res);
+
+} /* end of Cudd_addUnivAbstract */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Disjunctively abstracts all the variables in cube from the
+  0-1 ADD f.]
+
+  Description [Abstracts all the variables in cube from the 0-1 ADD f
+  by taking the disjunction over all possible values taken by the
+  variables.  Returns the abstracted ADD if successful; NULL
+  otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addUnivAbstract Cudd_addExistAbstract]
+
+******************************************************************************/
+DdNode *
+Cudd_addOrAbstract(
+  DdManager * manager,
+  DdNode * f,
+  DdNode * cube)
+{
+    DdNode *res;
+
+    if (addCheckPositiveCube(manager, cube) == 0) {
+        (void) fprintf(manager->err,"Error: Can only abstract cubes");
+        return(NULL);
+    }
+
+    do {
+       manager->reordered = 0;
+       res = cuddAddOrAbstractRecur(manager, f, cube);
+    } while (manager->reordered == 1);
+    return(res);
+
+} /* end of Cudd_addOrAbstract */
+
+
+/*---------------------------------------------------------------------------*/
+/* Definition of internal functions                                          */
+/*---------------------------------------------------------------------------*/
+
+
+/**Function********************************************************************
+
+  Synopsis    [Performs the recursive step of Cudd_addExistAbstract.]
+
+  Description [Performs the recursive step of Cudd_addExistAbstract.
+  Returns the ADD obtained by abstracting the variables of cube from f,
+  if successful; NULL otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     []
+
+******************************************************************************/
+DdNode *
+cuddAddExistAbstractRecur(
+  DdManager * manager,
+  DdNode * f,
+  DdNode * cube)
+{
+    DdNode     *T, *E, *res, *res1, *res2, *zero;
+
+    statLine(manager);
+    zero = DD_ZERO(manager);
+
+    /* Cube is guaranteed to be a cube at this point. */       
+    if (f == zero || cuddIsConstant(cube)) {  
+        return(f);
+    }
+
+    /* Abstract a variable that does not appear in f => multiply by 2. */
+    if (cuddI(manager,f->index) > cuddI(manager,cube->index)) {
+       res1 = cuddAddExistAbstractRecur(manager, f, cuddT(cube));
+       if (res1 == NULL) return(NULL);
+       cuddRef(res1);
+       /* Use the "internal" procedure to be alerted in case of
+       ** dynamic reordering. If dynamic reordering occurs, we
+       ** have to abort the entire abstraction.
+       */
+       res = cuddAddApplyRecur(manager,Cudd_addTimes,res1,two);
+       if (res == NULL) {
+           Cudd_RecursiveDeref(manager,res1);
+           return(NULL);
+       }
+       cuddRef(res);
+       Cudd_RecursiveDeref(manager,res1);
+       cuddDeref(res);
+        return(res);
+    }
+
+    if ((res = cuddCacheLookup2(manager, Cudd_addExistAbstract, f, cube)) != NULL) {
+       return(res);
+    }
+
+    T = cuddT(f);
+    E = cuddE(f);
+
+    /* If the two indices are the same, so are their levels. */
+    if (f->index == cube->index) {
+       res1 = cuddAddExistAbstractRecur(manager, T, cuddT(cube));
+       if (res1 == NULL) return(NULL);
+        cuddRef(res1);
+       res2 = cuddAddExistAbstractRecur(manager, E, cuddT(cube));
+       if (res2 == NULL) {
+           Cudd_RecursiveDeref(manager,res1);
+           return(NULL);
+       }
+        cuddRef(res2);
+       res = cuddAddApplyRecur(manager, Cudd_addPlus, res1, res2);
+       if (res == NULL) {
+           Cudd_RecursiveDeref(manager,res1);
+           Cudd_RecursiveDeref(manager,res2);
+           return(NULL);
+       }
+       cuddRef(res);
+       Cudd_RecursiveDeref(manager,res1);
+       Cudd_RecursiveDeref(manager,res2);
+       cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res);
+       cuddDeref(res);
+        return(res);
+    } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */
+       res1 = cuddAddExistAbstractRecur(manager, T, cube);
+       if (res1 == NULL) return(NULL);
+        cuddRef(res1);
+       res2 = cuddAddExistAbstractRecur(manager, E, cube);
+       if (res2 == NULL) {
+           Cudd_RecursiveDeref(manager,res1);
+           return(NULL);
+       }
+        cuddRef(res2);
+       res = (res1 == res2) ? res1 :
+           cuddUniqueInter(manager, (int) f->index, res1, res2);
+       if (res == NULL) {
+           Cudd_RecursiveDeref(manager,res1);
+           Cudd_RecursiveDeref(manager,res2);
+           return(NULL);
+       }
+       cuddDeref(res1);
+       cuddDeref(res2);
+       cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res);
+        return(res);
+    }      
+
+} /* end of cuddAddExistAbstractRecur */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Performs the recursive step of Cudd_addUnivAbstract.]
+
+  Description [Performs the recursive step of Cudd_addUnivAbstract.
+  Returns the ADD obtained by abstracting the variables of cube from f,
+  if successful; NULL otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     []
+
+******************************************************************************/
+DdNode *
+cuddAddUnivAbstractRecur(
+  DdManager * manager,
+  DdNode * f,
+  DdNode * cube)
+{
+    DdNode     *T, *E, *res, *res1, *res2, *one, *zero;
+
+    statLine(manager);
+    one = DD_ONE(manager);
+    zero = DD_ZERO(manager);
+
+    /* Cube is guaranteed to be a cube at this point.
+    ** zero and one are the only constatnts c such that c*c=c.
+    */
+    if (f == zero || f == one || cube == one) {  
+       return(f);
+    }
+
+    /* Abstract a variable that does not appear in f. */
+    if (cuddI(manager,f->index) > cuddI(manager,cube->index)) {
+       res1 = cuddAddUnivAbstractRecur(manager, f, cuddT(cube));
+       if (res1 == NULL) return(NULL);
+       cuddRef(res1);
+       /* Use the "internal" procedure to be alerted in case of
+       ** dynamic reordering. If dynamic reordering occurs, we
+       ** have to abort the entire abstraction.
+       */
+       res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res1);
+       if (res == NULL) {
+           Cudd_RecursiveDeref(manager,res1);
+           return(NULL);
+       }
+       cuddRef(res);
+       Cudd_RecursiveDeref(manager,res1);
+       cuddDeref(res);
+       return(res);
+    }
+
+    if ((res = cuddCacheLookup2(manager, Cudd_addUnivAbstract, f, cube)) != NULL) {
+       return(res);
+    }
+
+    T = cuddT(f);
+    E = cuddE(f);
+
+    /* If the two indices are the same, so are their levels. */
+    if (f->index == cube->index) {
+       res1 = cuddAddUnivAbstractRecur(manager, T, cuddT(cube));
+       if (res1 == NULL) return(NULL);
+        cuddRef(res1);
+       res2 = cuddAddUnivAbstractRecur(manager, E, cuddT(cube));
+       if (res2 == NULL) {
+           Cudd_RecursiveDeref(manager,res1);
+           return(NULL);
+       }
+        cuddRef(res2);
+       res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res2);
+       if (res == NULL) {
+           Cudd_RecursiveDeref(manager,res1);
+           Cudd_RecursiveDeref(manager,res2);
+           return(NULL);
+       }
+       cuddRef(res);
+       Cudd_RecursiveDeref(manager,res1);
+       Cudd_RecursiveDeref(manager,res2);
+       cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res);
+       cuddDeref(res);
+        return(res);
+    } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */
+       res1 = cuddAddUnivAbstractRecur(manager, T, cube);
+       if (res1 == NULL) return(NULL);
+        cuddRef(res1);
+       res2 = cuddAddUnivAbstractRecur(manager, E, cube);
+       if (res2 == NULL) {
+           Cudd_RecursiveDeref(manager,res1);
+           return(NULL);
+       }
+        cuddRef(res2);
+       res = (res1 == res2) ? res1 :
+           cuddUniqueInter(manager, (int) f->index, res1, res2);
+       if (res == NULL) {
+           Cudd_RecursiveDeref(manager,res1);
+           Cudd_RecursiveDeref(manager,res2);
+           return(NULL);
+       }
+       cuddDeref(res1);
+       cuddDeref(res2);
+       cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res);
+        return(res);
+    }
+
+} /* end of cuddAddUnivAbstractRecur */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Performs the recursive step of Cudd_addOrAbstract.]
+
+  Description [Performs the recursive step of Cudd_addOrAbstract.
+  Returns the ADD obtained by abstracting the variables of cube from f,
+  if successful; NULL otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     []
+
+******************************************************************************/
+DdNode *
+cuddAddOrAbstractRecur(
+  DdManager * manager,
+  DdNode * f,
+  DdNode * cube)
+{
+    DdNode     *T, *E, *res, *res1, *res2, *one;
+
+    statLine(manager);
+    one = DD_ONE(manager);
+
+    /* Cube is guaranteed to be a cube at this point. */
+    if (cuddIsConstant(f) || cube == one) {  
+       return(f);
+    }
+
+    /* Abstract a variable that does not appear in f. */
+    if (cuddI(manager,f->index) > cuddI(manager,cube->index)) {
+       res = cuddAddOrAbstractRecur(manager, f, cuddT(cube));
+       return(res);
+    }
+
+    if ((res = cuddCacheLookup2(manager, Cudd_addOrAbstract, f, cube)) != NULL) {
+       return(res);
+    }
+
+    T = cuddT(f);
+    E = cuddE(f);
+
+    /* If the two indices are the same, so are their levels. */
+    if (f->index == cube->index) {
+       res1 = cuddAddOrAbstractRecur(manager, T, cuddT(cube));
+       if (res1 == NULL) return(NULL);
+        cuddRef(res1);
+       if (res1 != one) {
+           res2 = cuddAddOrAbstractRecur(manager, E, cuddT(cube));
+           if (res2 == NULL) {
+               Cudd_RecursiveDeref(manager,res1);
+               return(NULL);
+           }
+           cuddRef(res2);
+           res = cuddAddApplyRecur(manager, Cudd_addOr, res1, res2);
+           if (res == NULL) {
+               Cudd_RecursiveDeref(manager,res1);
+               Cudd_RecursiveDeref(manager,res2);
+               return(NULL);
+           }
+           cuddRef(res);
+           Cudd_RecursiveDeref(manager,res1);
+           Cudd_RecursiveDeref(manager,res2);
+       } else {
+           res = res1;
+       }
+       cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res);
+       cuddDeref(res);
+        return(res);
+    } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */
+       res1 = cuddAddOrAbstractRecur(manager, T, cube);
+       if (res1 == NULL) return(NULL);
+        cuddRef(res1);
+       res2 = cuddAddOrAbstractRecur(manager, E, cube);
+       if (res2 == NULL) {
+           Cudd_RecursiveDeref(manager,res1);
+           return(NULL);
+       }
+        cuddRef(res2);
+       res = (res1 == res2) ? res1 :
+           cuddUniqueInter(manager, (int) f->index, res1, res2);
+       if (res == NULL) {
+           Cudd_RecursiveDeref(manager,res1);
+           Cudd_RecursiveDeref(manager,res2);
+           return(NULL);
+       }
+       cuddDeref(res1);
+       cuddDeref(res2);
+       cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res);
+        return(res);
+    }
+
+} /* end of cuddAddOrAbstractRecur */
+
+
+
+/*---------------------------------------------------------------------------*/
+/* Definition of static functions                                            */
+/*---------------------------------------------------------------------------*/
+
+
+/**Function********************************************************************
+
+  Synopsis    [Checks whether cube is an ADD representing the product
+  of positive literals.]
+
+  Description [Checks whether cube is an ADD representing the product of
+  positive literals. Returns 1 in case of success; 0 otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     []
+
+******************************************************************************/
+static int
+addCheckPositiveCube(
+  DdManager * manager,
+  DdNode * cube)
+{
+    if (Cudd_IsComplement(cube)) return(0);
+    if (cube == DD_ONE(manager)) return(1);
+    if (cuddIsConstant(cube)) return(0);
+    if (cuddE(cube) == DD_ZERO(manager)) {
+        return(addCheckPositiveCube(manager, cuddT(cube)));
+    }
+    return(0);
+
+} /* end of addCheckPositiveCube */
+
diff --git a/distr/cudd/cuddAddApply.c b/distr/cudd/cuddAddApply.c
new file mode 100644 (file)
index 0000000..944d7a4
--- /dev/null
@@ -0,0 +1,941 @@
+/**CFile***********************************************************************
+
+  FileName    [cuddAddApply.c]
+
+  PackageName [cudd]
+
+  Synopsis    [Apply functions for ADDs and their operators.]
+
+  Description [External procedures included in this module:
+               <ul>
+               <li> Cudd_addApply()
+               <li> Cudd_addMonadicApply()
+               <li> Cudd_addPlus()
+               <li> Cudd_addTimes()
+               <li> Cudd_addThreshold()
+               <li> Cudd_addSetNZ()
+               <li> Cudd_addDivide()
+               <li> Cudd_addMinus()
+               <li> Cudd_addMinimum()
+               <li> Cudd_addMaximum()
+               <li> Cudd_addOneZeroMaximum()
+               <li> Cudd_addDiff()
+               <li> Cudd_addAgreement()
+               <li> Cudd_addOr()
+               <li> Cudd_addNand()
+               <li> Cudd_addNor()
+               <li> Cudd_addXor()
+               <li> Cudd_addXnor()
+               </ul>
+           Internal procedures included in this module:
+               <ul>
+               <li> cuddAddApplyRecur()
+               <li> cuddAddMonadicApplyRecur()
+               </ul>]
+
+  Author      [Fabio Somenzi]
+
+  Copyright   [Copyright (c) 1995-2004, Regents of the University of Colorado
+
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+  Redistributions of source code must retain the above copyright
+  notice, this list of conditions and the following disclaimer.
+
+  Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in the
+  documentation and/or other materials provided with the distribution.
+
+  Neither the name of the University of Colorado nor the names of its
+  contributors may be used to endorse or promote products derived from
+  this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.]
+
+******************************************************************************/
+
+#include "util.h"
+#include "cuddInt.h"
+
+/*---------------------------------------------------------------------------*/
+/* Constant declarations                                                     */
+/*---------------------------------------------------------------------------*/
+
+
+/*---------------------------------------------------------------------------*/
+/* Stucture declarations                                                     */
+/*---------------------------------------------------------------------------*/
+
+
+/*---------------------------------------------------------------------------*/
+/* Type declarations                                                         */
+/*---------------------------------------------------------------------------*/
+
+
+/*---------------------------------------------------------------------------*/
+/* Variable declarations                                                     */
+/*---------------------------------------------------------------------------*/
+
+#ifndef lint
+static char rcsid[] DD_UNUSED = "$Id: cuddAddApply.c,v 1.18 2009/02/19 16:15:26 fabio Exp $";
+#endif
+
+
+/*---------------------------------------------------------------------------*/
+/* Macro declarations                                                        */
+/*---------------------------------------------------------------------------*/
+
+
+/**AutomaticStart*************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* Static function prototypes                                                */
+/*---------------------------------------------------------------------------*/
+
+
+/**AutomaticEnd***************************************************************/
+
+
+/*---------------------------------------------------------------------------*/
+/* Definition of exported functions                                          */
+/*---------------------------------------------------------------------------*/
+
+/**Function********************************************************************
+
+  Synopsis    [Applies op to the corresponding discriminants of f and g.]
+
+  Description [Applies op to the corresponding discriminants of f and g.
+  Returns a pointer to the result if succssful; NULL otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addMonadicApply Cudd_addPlus Cudd_addTimes
+  Cudd_addThreshold Cudd_addSetNZ Cudd_addDivide Cudd_addMinus Cudd_addMinimum
+  Cudd_addMaximum Cudd_addOneZeroMaximum Cudd_addDiff Cudd_addAgreement
+  Cudd_addOr Cudd_addNand Cudd_addNor Cudd_addXor Cudd_addXnor]
+
+******************************************************************************/
+DdNode *
+Cudd_addApply(
+  DdManager * dd,
+  DD_AOP op,
+  DdNode * f,
+  DdNode * g)
+{
+    DdNode *res;
+
+    do {
+       dd->reordered = 0;
+       res = cuddAddApplyRecur(dd,op,f,g);
+    } while (dd->reordered == 1);
+    return(res);
+
+} /* end of Cudd_addApply */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Integer and floating point addition.]
+
+  Description [Integer and floating point addition. Returns NULL if not
+  a terminal case; f+g otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addApply]
+
+******************************************************************************/
+DdNode *
+Cudd_addPlus(
+  DdManager * dd,
+  DdNode ** f,
+  DdNode ** g)
+{
+    DdNode *res;
+    DdNode *F, *G;
+    CUDD_VALUE_TYPE value;
+
+    F = *f; G = *g;
+    if (F == DD_ZERO(dd)) return(G);
+    if (G == DD_ZERO(dd)) return(F);
+    if (cuddIsConstant(F) && cuddIsConstant(G)) {
+       value = cuddV(F)+cuddV(G);
+       res = cuddUniqueConst(dd,value);
+       return(res);
+    }
+    if (F > G) { /* swap f and g */
+       *f = G;
+       *g = F;
+    }
+    return(NULL);
+
+} /* end of Cudd_addPlus */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Integer and floating point multiplication.]
+
+  Description [Integer and floating point multiplication. Returns NULL
+  if not a terminal case; f * g otherwise.  This function can be used also
+  to take the AND of two 0-1 ADDs.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addApply]
+
+******************************************************************************/
+DdNode *
+Cudd_addTimes(
+  DdManager * dd,
+  DdNode ** f,
+  DdNode ** g)
+{
+    DdNode *res;
+    DdNode *F, *G;
+    CUDD_VALUE_TYPE value;
+
+    F = *f; G = *g;
+    if (F == DD_ZERO(dd) || G == DD_ZERO(dd)) return(DD_ZERO(dd));
+    if (F == DD_ONE(dd)) return(G);
+    if (G == DD_ONE(dd)) return(F);
+    if (cuddIsConstant(F) && cuddIsConstant(G)) {
+       value = cuddV(F)*cuddV(G);
+       res = cuddUniqueConst(dd,value);
+       return(res);
+    }
+    if (F > G) { /* swap f and g */
+       *f = G;
+       *g = F;
+    }
+    return(NULL);
+
+} /* end of Cudd_addTimes */
+
+
+/**Function********************************************************************
+
+  Synopsis    [f if f&gt;=g; 0 if f&lt;g.]
+
+  Description [Threshold operator for Apply (f if f &gt;=g; 0 if f&lt;g).
+  Returns NULL if not a terminal case; f op g otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addApply]
+
+******************************************************************************/
+DdNode *
+Cudd_addThreshold(
+  DdManager * dd,
+  DdNode ** f,
+  DdNode ** g)
+{
+    DdNode *F, *G;
+
+    F = *f; G = *g;
+    if (F == G || F == DD_PLUS_INFINITY(dd)) return(F);
+    if (cuddIsConstant(F) && cuddIsConstant(G)) {
+       if (cuddV(F) >= cuddV(G)) {
+           return(F);
+       } else {
+           return(DD_ZERO(dd));
+       }
+    }
+    return(NULL);
+
+} /* end of Cudd_addThreshold */
+
+
+/**Function********************************************************************
+
+  Synopsis    [This operator sets f to the value of g wherever g != 0.]
+
+  Description [This operator sets f to the value of g wherever g != 0.
+  Returns NULL if not a terminal case; f op g otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addApply]
+
+******************************************************************************/
+DdNode *
+Cudd_addSetNZ(
+  DdManager * dd,
+  DdNode ** f,
+  DdNode ** g)
+{
+    DdNode *F, *G;
+
+    F = *f; G = *g;
+    if (F == G) return(F);
+    if (F == DD_ZERO(dd)) return(G);
+    if (G == DD_ZERO(dd)) return(F);
+    if (cuddIsConstant(G)) return(G);
+    return(NULL);
+
+} /* end of Cudd_addSetNZ */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Integer and floating point division.]
+
+  Description [Integer and floating point division. Returns NULL if not
+  a terminal case; f / g otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addApply]
+
+******************************************************************************/
+DdNode *
+Cudd_addDivide(
+  DdManager * dd,
+  DdNode ** f,
+  DdNode ** g)
+{
+    DdNode *res;
+    DdNode *F, *G;
+    CUDD_VALUE_TYPE value;
+
+    F = *f; G = *g;
+    /* We would like to use F == G -> F/G == 1, but F and G may
+    ** contain zeroes. */
+    if (F == DD_ZERO(dd)) return(DD_ZERO(dd));
+    if (G == DD_ONE(dd)) return(F);
+    if (cuddIsConstant(F) && cuddIsConstant(G)) {
+       value = cuddV(F)/cuddV(G);
+       res = cuddUniqueConst(dd,value);
+       return(res);
+    }
+    return(NULL);
+
+} /* end of Cudd_addDivide */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Integer and floating point subtraction.]
+
+  Description [Integer and floating point subtraction. Returns NULL if
+  not a terminal case; f - g otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addApply]
+
+******************************************************************************/
+DdNode *
+Cudd_addMinus(
+  DdManager * dd,
+  DdNode ** f,
+  DdNode ** g)
+{
+    DdNode *res;
+    DdNode *F, *G;
+    CUDD_VALUE_TYPE value;
+
+    F = *f; G = *g;
+    if (F == G) return(DD_ZERO(dd));
+    if (F == DD_ZERO(dd)) return(cuddAddNegateRecur(dd,G));
+    if (G == DD_ZERO(dd)) return(F);
+    if (cuddIsConstant(F) && cuddIsConstant(G)) {
+       value = cuddV(F)-cuddV(G);
+       res = cuddUniqueConst(dd,value);
+       return(res);
+    }
+    return(NULL);
+
+} /* end of Cudd_addMinus */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Integer and floating point min.]
+
+  Description [Integer and floating point min for Cudd_addApply.
+  Returns NULL if not a terminal case; min(f,g) otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addApply]
+
+******************************************************************************/
+DdNode *
+Cudd_addMinimum(
+  DdManager * dd,
+  DdNode ** f,
+  DdNode ** g)
+{
+    DdNode *F, *G;
+
+    F = *f; G = *g;
+    if (F == DD_PLUS_INFINITY(dd)) return(G);
+    if (G == DD_PLUS_INFINITY(dd)) return(F);
+    if (F == G) return(F);
+#if 0
+    /* These special cases probably do not pay off. */
+    if (F == DD_MINUS_INFINITY(dd)) return(F);
+    if (G == DD_MINUS_INFINITY(dd)) return(G);
+#endif
+    if (cuddIsConstant(F) && cuddIsConstant(G)) {
+       if (cuddV(F) <= cuddV(G)) {
+           return(F);
+       } else {
+           return(G);
+       }
+    }
+    if (F > G) { /* swap f and g */
+       *f = G;
+       *g = F;
+    }
+    return(NULL);
+
+} /* end of Cudd_addMinimum */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Integer and floating point max.]
+
+  Description [Integer and floating point max for Cudd_addApply.
+  Returns NULL if not a terminal case; max(f,g) otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addApply]
+
+******************************************************************************/
+DdNode *
+Cudd_addMaximum(
+  DdManager * dd,
+  DdNode ** f,
+  DdNode ** g)
+{
+    DdNode *F, *G;
+
+    F = *f; G = *g;
+    if (F == G) return(F);
+    if (F == DD_MINUS_INFINITY(dd)) return(G);
+    if (G == DD_MINUS_INFINITY(dd)) return(F);
+#if 0
+    /* These special cases probably do not pay off. */
+    if (F == DD_PLUS_INFINITY(dd)) return(F);
+    if (G == DD_PLUS_INFINITY(dd)) return(G);
+#endif
+    if (cuddIsConstant(F) && cuddIsConstant(G)) {
+       if (cuddV(F) >= cuddV(G)) {
+           return(F);
+       } else {
+           return(G);
+       }
+    }
+    if (F > G) { /* swap f and g */
+       *f = G;
+       *g = F;
+    }
+    return(NULL);
+
+} /* end of Cudd_addMaximum */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns 1 if f &gt; g and 0 otherwise.]
+
+  Description [Returns 1 if f &gt; g and 0 otherwise. Used in
+  conjunction with Cudd_addApply. Returns NULL if not a terminal
+  case.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addApply]
+
+******************************************************************************/
+DdNode *
+Cudd_addOneZeroMaximum(
+  DdManager * dd,
+  DdNode ** f,
+  DdNode ** g)
+{
+
+    if (*f == *g) return(DD_ZERO(dd));
+    if (*g == DD_PLUS_INFINITY(dd))
+       return DD_ZERO(dd);
+    if (cuddIsConstant(*f) && cuddIsConstant(*g)) {
+       if (cuddV(*f) > cuddV(*g)) {
+           return(DD_ONE(dd));
+       } else {
+           return(DD_ZERO(dd));
+       }
+    }
+
+    return(NULL);
+
+} /* end of Cudd_addOneZeroMaximum */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Returns plusinfinity if f=g; returns min(f,g) if f!=g.]
+
+  Description [Returns NULL if not a terminal case; f op g otherwise,
+  where f op g is plusinfinity if f=g; min(f,g) if f!=g.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addApply]
+
+******************************************************************************/
+DdNode *
+Cudd_addDiff(
+  DdManager * dd,
+  DdNode ** f,
+  DdNode ** g)
+{
+    DdNode *F, *G;
+
+    F = *f; G = *g;
+    if (F == G) return(DD_PLUS_INFINITY(dd));
+    if (F == DD_PLUS_INFINITY(dd)) return(G);
+    if (G == DD_PLUS_INFINITY(dd)) return(F);
+    if (cuddIsConstant(F) && cuddIsConstant(G)) {
+       if (cuddV(F) != cuddV(G)) {
+           if (cuddV(F) < cuddV(G)) {
+               return(F);
+           } else {
+               return(G);
+           }
+       } else {
+           return(DD_PLUS_INFINITY(dd));
+       }
+    }
+    return(NULL);
+
+} /* end of Cudd_addDiff */
+
+
+/**Function********************************************************************
+
+  Synopsis    [f if f==g; background if f!=g.]
+
+  Description [Returns NULL if not a terminal case; f op g otherwise,
+  where f op g is f if f==g; background if f!=g.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addApply]
+
+******************************************************************************/
+DdNode *
+Cudd_addAgreement(
+  DdManager * dd,
+  DdNode ** f,
+  DdNode ** g)
+{
+    DdNode *F, *G;
+
+    F = *f; G = *g;
+    if (F == G) return(F);
+    if (F == dd->background) return(F);
+    if (G == dd->background) return(G);
+    if (cuddIsConstant(F) && cuddIsConstant(G)) return(dd->background);
+    return(NULL);
+
+} /* end of Cudd_addAgreement */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Disjunction of two 0-1 ADDs.]
+
+  Description [Disjunction of two 0-1 ADDs. Returns NULL
+  if not a terminal case; f OR g otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addApply]
+
+******************************************************************************/
+DdNode *
+Cudd_addOr(
+  DdManager * dd,
+  DdNode ** f,
+  DdNode ** g)
+{
+    DdNode *F, *G;
+
+    F = *f; G = *g;
+    if (F == DD_ONE(dd) || G == DD_ONE(dd)) return(DD_ONE(dd));
+    if (cuddIsConstant(F)) return(G);
+    if (cuddIsConstant(G)) return(F);
+    if (F == G) return(F);
+    if (F > G) { /* swap f and g */
+       *f = G;
+       *g = F;
+    }
+    return(NULL);
+
+} /* end of Cudd_addOr */
+
+
+/**Function********************************************************************
+
+  Synopsis    [NAND of two 0-1 ADDs.]
+
+  Description [NAND of two 0-1 ADDs. Returns NULL
+  if not a terminal case; f NAND g otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addApply]
+
+******************************************************************************/
+DdNode *
+Cudd_addNand(
+  DdManager * dd,
+  DdNode ** f,
+  DdNode ** g)
+{
+    DdNode *F, *G;
+
+    F = *f; G = *g;
+    if (F == DD_ZERO(dd) || G == DD_ZERO(dd)) return(DD_ONE(dd));
+    if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd));
+    if (F > G) { /* swap f and g */
+       *f = G;
+       *g = F;
+    }
+    return(NULL);
+
+} /* end of Cudd_addNand */
+
+
+/**Function********************************************************************
+
+  Synopsis    [NOR of two 0-1 ADDs.]
+
+  Description [NOR of two 0-1 ADDs. Returns NULL
+  if not a terminal case; f NOR g otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addApply]
+
+******************************************************************************/
+DdNode *
+Cudd_addNor(
+  DdManager * dd,
+  DdNode ** f,
+  DdNode ** g)
+{
+    DdNode *F, *G;
+
+    F = *f; G = *g;
+    if (F == DD_ONE(dd) || G == DD_ONE(dd)) return(DD_ZERO(dd));
+    if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ONE(dd));
+    if (F > G) { /* swap f and g */
+       *f = G;
+       *g = F;
+    }
+    return(NULL);
+
+} /* end of Cudd_addNor */
+
+
+/**Function********************************************************************
+
+  Synopsis    [XOR of two 0-1 ADDs.]
+
+  Description [XOR of two 0-1 ADDs. Returns NULL
+  if not a terminal case; f XOR g otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addApply]
+
+******************************************************************************/
+DdNode *
+Cudd_addXor(
+  DdManager * dd,
+  DdNode ** f,
+  DdNode ** g)
+{
+    DdNode *F, *G;
+
+    F = *f; G = *g;
+    if (F == G) return(DD_ZERO(dd));
+    if (F == DD_ONE(dd) && G == DD_ZERO(dd)) return(DD_ONE(dd));
+    if (G == DD_ONE(dd) && F == DD_ZERO(dd)) return(DD_ONE(dd));
+    if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd));
+    if (F > G) { /* swap f and g */
+       *f = G;
+       *g = F;
+    }
+    return(NULL);
+
+} /* end of Cudd_addXor */
+
+
+/**Function********************************************************************
+
+  Synopsis    [XNOR of two 0-1 ADDs.]
+
+  Description [XNOR of two 0-1 ADDs. Returns NULL
+  if not a terminal case; f XNOR g otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addApply]
+
+******************************************************************************/
+DdNode *
+Cudd_addXnor(
+  DdManager * dd,
+  DdNode ** f,
+  DdNode ** g)
+{
+    DdNode *F, *G;
+
+    F = *f; G = *g;
+    if (F == G) return(DD_ONE(dd));
+    if (F == DD_ONE(dd) && G == DD_ONE(dd)) return(DD_ONE(dd));
+    if (G == DD_ZERO(dd) && F == DD_ZERO(dd)) return(DD_ONE(dd));
+    if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd));
+    if (F > G) { /* swap f and g */
+       *f = G;
+       *g = F;
+    }
+    return(NULL);
+
+} /* end of Cudd_addXnor */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Applies op to the discriminants of f.]
+
+  Description [Applies op to the discriminants of f.
+  Returns a pointer to the result if succssful; NULL otherwise.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addApply Cudd_addLog]
+
+******************************************************************************/
+DdNode *
+Cudd_addMonadicApply(
+  DdManager * dd,
+  DD_MAOP op,
+  DdNode * f)
+{
+    DdNode *res;
+
+    do {
+       dd->reordered = 0;
+       res = cuddAddMonadicApplyRecur(dd,op,f);
+    } while (dd->reordered == 1);
+    return(res);
+
+} /* end of Cudd_addMonadicApply */
+
+
+/**Function********************************************************************
+
+  Synopsis    [Natural logarithm of an ADD.]
+
+  Description [Natural logarithm of an ADDs. Returns NULL
+  if not a terminal case; log(f) otherwise.  The discriminants of f must
+  be positive double's.]
+
+  SideEffects [None]
+
+  SeeAlso     [Cudd_addMonadicApply]
+
+******************************************************************************/
+DdNode *
+Cudd_addLog(
+  DdManager * dd,
+  DdNode * f)
+{
+    if (cuddIsConstant(f)) {
+       CUDD_VALUE_TYPE value = log(cuddV(f));
+       DdNode *res = cuddUniqueConst(dd,value);
+       return(res);
+    }
+    return(NULL);
+
+} /* end of Cudd_addLog */
+
+
+/*---------------------------------------------------------------------------*/
+/* Definition of internal functions                                          */
+/*---------------------------------------------------------------------------*/
+
+
+/**Function********************************************************************
+
+  Synopsis    [Performs the recursive step of Cudd_addApply.]
+
+  Description [Performs the recursive step of Cudd_addApply. Returns a
+  pointer to the result if successful; NULL otherwise.]
+
+  SideEffects [None]