From 69a9825c8b8698665590160cfc714c74cc4af353 Mon Sep 17 00:00:00 2001 From: Artur Meski Date: Sat, 18 Nov 2017 20:30:18 +0000 Subject: [PATCH] APM: RSMC version 1.0 (not 1.0a) from ipisvn --- Makefile | 41 + bdd_macro.hh | 8 + cudd.hh | 1 + cudd_local/LICENSE | 31 + cudd_local/Makefile | 318 + cudd_local/README | 177 + cudd_local/RELEASE.NOTES | 131 + cudd_local/cudd/Makefile | 124 + cudd_local/cudd/cudd.h | 1070 ++ cudd_local/cudd/cuddAPI.c | 4893 +++++ cudd_local/cudd/cuddAddAbs.c | 579 + cudd_local/cudd/cuddAddApply.c | 941 + cudd_local/cudd/cuddAddFind.c | 316 + cudd_local/cudd/cuddAddInv.c | 201 + cudd_local/cudd/cuddAddIte.c | 639 + cudd_local/cudd/cuddAddNeg.c | 290 + cudd_local/cudd/cuddAddWalsh.c | 391 + cudd_local/cudd/cuddAndAbs.c | 373 + cudd_local/cudd/cuddAnneal.c | 814 + cudd_local/cudd/cuddApa.c | 979 + cudd_local/cudd/cuddApprox.c | 2204 +++ cudd_local/cudd/cuddBddAbs.c | 760 + cudd_local/cudd/cuddBddCorr.c | 515 + cudd_local/cudd/cuddBddIte.c | 1430 ++ cudd_local/cudd/cuddBridge.c | 1016 + cudd_local/cudd/cuddCache.c | 1053 ++ cudd_local/cudd/cuddCheck.c | 885 + cudd_local/cudd/cuddClip.c | 558 + cudd_local/cudd/cuddCof.c | 327 + cudd_local/cudd/cuddCompose.c | 1749 ++ cudd_local/cudd/cuddDecomp.c | 2177 +++ cudd_local/cudd/cuddEssent.c | 1467 ++ cudd_local/cudd/cuddExact.c | 1020 + cudd_local/cudd/cuddExport.c | 1389 ++ cudd_local/cudd/cuddGenCof.c | 2178 +++ cudd_local/cudd/cuddGenetic.c | 960 + cudd_local/cudd/cuddGroup.c | 2188 +++ cudd_local/cudd/cuddHarwell.c | 568 + cudd_local/cudd/cuddInit.c | 308 + cudd_local/cudd/cuddInt.h | 1188 ++ cudd_local/cudd/cuddInteract.c | 432 + cudd_local/cudd/cuddLCache.c | 1557 ++ cudd_local/cudd/cuddLevelQ.c | 583 + cudd_local/cudd/cuddLinear.c | 1365 ++ cudd_local/cudd/cuddLiteral.c | 264 + cudd_local/cudd/cuddMatMult.c | 707 + cudd_local/cudd/cuddPriority.c | 2027 ++ cudd_local/cudd/cuddRead.c | 517 + cudd_local/cudd/cuddRef.c | 808 + cudd_local/cudd/cuddReorder.c | 2137 +++ cudd_local/cudd/cuddSat.c | 1774 ++ cudd_local/cudd/cuddSign.c | 318 + cudd_local/cudd/cuddSolve.c | 366 + cudd_local/cudd/cuddSplit.c | 686 + cudd_local/cudd/cuddSubsetHB.c | 1331 ++ cudd_local/cudd/cuddSubsetSP.c | 1660 ++ cudd_local/cudd/cuddSymmetry.c | 1707 ++ cudd_local/cudd/cuddTable.c | 3213 ++++ cudd_local/cudd/cuddUtil.c | 4032 ++++ cudd_local/cudd/cuddWindow.c | 1023 + cudd_local/cudd/cuddZddCount.c | 357 + cudd_local/cudd/cuddZddFuncs.c | 1630 ++ cudd_local/cudd/cuddZddGroup.c | 1340 ++ cudd_local/cudd/cuddZddIsop.c | 912 + cudd_local/cudd/cuddZddLin.c | 971 + cudd_local/cudd/cuddZddMisc.c | 278 + cudd_local/cudd/cuddZddPort.c | 381 + cudd_local/cudd/cuddZddReord.c | 1664 ++ cudd_local/cudd/cuddZddSetop.c | 1166 ++ cudd_local/cudd/cuddZddSymm.c | 1711 ++ cudd_local/cudd/cuddZddUtil.c | 1205 ++ cudd_local/cudd/doc/cudd.doc | 6776 +++++++ cudd_local/cudd/doc/cudd.ps | 5036 +++++ cudd_local/cudd/doc/cuddAllAbs.html | 3114 +++ cudd_local/cudd/doc/cuddAllByFile.html | 13 + cudd_local/cudd/doc/cuddAllByFunc.html | 13 + cudd_local/cudd/doc/cuddAllDet.html | 15754 ++++++++++++++++ cudd_local/cudd/doc/cuddAllFile.html | 4876 +++++ cudd_local/cudd/doc/cuddDesc.html | 33 + cudd_local/cudd/doc/cuddExt.html | 14 + cudd_local/cudd/doc/cuddExtAbs.html | 1415 ++ cudd_local/cudd/doc/cuddExtDet.html | 4450 +++++ cudd_local/cudd/doc/cuddIntro.css | 30 + cudd_local/cudd/doc/cuddIntro.html | 219 + cudd_local/cudd/doc/cuddTitle.html | 18 + cudd_local/cudd/doc/footnode.html | 109 + cudd_local/cudd/doc/icons/blueball.png | Bin 0 -> 333 bytes cudd_local/cudd/doc/icons/ch_beg_r.png | Bin 0 -> 165 bytes cudd_local/cudd/doc/icons/ch_begin.png | Bin 0 -> 174 bytes cudd_local/cudd/doc/icons/ch_del_r.png | Bin 0 -> 288 bytes cudd_local/cudd/doc/icons/ch_delet.png | Bin 0 -> 288 bytes cudd_local/cudd/doc/icons/ch_end.png | Bin 0 -> 171 bytes cudd_local/cudd/doc/icons/ch_end_r.png | Bin 0 -> 155 bytes cudd_local/cudd/doc/icons/contents.png | Bin 0 -> 278 bytes cudd_local/cudd/doc/icons/crossref.png | Bin 0 -> 147 bytes cudd_local/cudd/doc/icons/footnote.png | Bin 0 -> 190 bytes cudd_local/cudd/doc/icons/greenball.png | Bin 0 -> 333 bytes cudd_local/cudd/doc/icons/image.png | Bin 0 -> 244 bytes cudd_local/cudd/doc/icons/index.png | Bin 0 -> 246 bytes cudd_local/cudd/doc/icons/next.png | Bin 0 -> 245 bytes cudd_local/cudd/doc/icons/next_g.png | Bin 0 -> 272 bytes cudd_local/cudd/doc/icons/nx_grp.png | Bin 0 -> 314 bytes cudd_local/cudd/doc/icons/nx_grp_g.png | Bin 0 -> 386 bytes cudd_local/cudd/doc/icons/orangeball.png | Bin 0 -> 333 bytes cudd_local/cudd/doc/icons/pinkball.png | Bin 0 -> 332 bytes cudd_local/cudd/doc/icons/prev.png | Bin 0 -> 279 bytes cudd_local/cudd/doc/icons/prev_g.png | Bin 0 -> 327 bytes cudd_local/cudd/doc/icons/purpleball.png | Bin 0 -> 332 bytes cudd_local/cudd/doc/icons/pv_grp.png | Bin 0 -> 352 bytes cudd_local/cudd/doc/icons/pv_grp_g.png | Bin 0 -> 430 bytes cudd_local/cudd/doc/icons/redball.png | Bin 0 -> 332 bytes cudd_local/cudd/doc/icons/up.png | Bin 0 -> 211 bytes cudd_local/cudd/doc/icons/up_g.png | Bin 0 -> 231 bytes cudd_local/cudd/doc/icons/whiteball.png | Bin 0 -> 229 bytes cudd_local/cudd/doc/icons/yellowball.png | Bin 0 -> 333 bytes cudd_local/cudd/doc/img1.png | Bin 0 -> 201 bytes cudd_local/cudd/doc/img10.png | Bin 0 -> 211 bytes cudd_local/cudd/doc/img11.png | Bin 0 -> 476 bytes cudd_local/cudd/doc/img12.png | Bin 0 -> 555 bytes cudd_local/cudd/doc/img13.png | Bin 0 -> 560 bytes cudd_local/cudd/doc/img14.png | Bin 0 -> 675 bytes cudd_local/cudd/doc/img15.png | Bin 0 -> 200 bytes cudd_local/cudd/doc/img16.png | Bin 0 -> 223 bytes cudd_local/cudd/doc/img17.png | Bin 0 -> 246 bytes cudd_local/cudd/doc/img18.png | Bin 0 -> 298 bytes cudd_local/cudd/doc/img19.png | Bin 0 -> 409 bytes cudd_local/cudd/doc/img2.png | Bin 0 -> 197 bytes cudd_local/cudd/doc/img20.png | Bin 0 -> 238 bytes cudd_local/cudd/doc/img21.png | Bin 0 -> 614 bytes cudd_local/cudd/doc/img22.png | Bin 0 -> 12605 bytes cudd_local/cudd/doc/img3.png | Bin 0 -> 401 bytes cudd_local/cudd/doc/img4.png | Bin 0 -> 204 bytes cudd_local/cudd/doc/img5.png | Bin 0 -> 315 bytes cudd_local/cudd/doc/img6.png | Bin 0 -> 185 bytes cudd_local/cudd/doc/img7.png | Bin 0 -> 262 bytes cudd_local/cudd/doc/img8.png | Bin 0 -> 220 bytes cudd_local/cudd/doc/img9.png | Bin 0 -> 215 bytes cudd_local/cudd/doc/index.html | 219 + cudd_local/cudd/doc/node1.html | 174 + cudd_local/cudd/doc/node2.html | 175 + cudd_local/cudd/doc/node3.html | 1637 ++ cudd_local/cudd/doc/node4.html | 1165 ++ cudd_local/cudd/doc/node5.html | 130 + cudd_local/cudd/doc/node6.html | 132 + cudd_local/cudd/doc/node7.html | 195 + cudd_local/cudd/doc/node8.html | 848 + cudd_local/cudd/libcudd.a | Bin 0 -> 2011840 bytes cudd_local/cudd/r7x8.1.mat | 53 + cudd_local/cudd/r7x8.1.out | 396 + cudd_local/cudd/testcudd.c | 1178 ++ cudd_local/dddmp/Makefile | 243 + cudd_local/dddmp/README.dddmp | 64 + cudd_local/dddmp/README.testdddmp | 79 + cudd_local/dddmp/RELEASE_NOTES | 60 + cudd_local/dddmp/dddmp.h | 330 + cudd_local/dddmp/dddmpBinary.c | 343 + cudd_local/dddmp/dddmpConvert.c | 180 + cudd_local/dddmp/dddmpDbg.c | 166 + cudd_local/dddmp/dddmpDdNodeBdd.c | 455 + cudd_local/dddmp/dddmpDdNodeCnf.c | 944 + cudd_local/dddmp/dddmpInt.h | 216 + cudd_local/dddmp/dddmpLoad.c | 1486 ++ cudd_local/dddmp/dddmpLoadCnf.c | 1072 ++ cudd_local/dddmp/dddmpNodeAdd.c | 451 + cudd_local/dddmp/dddmpNodeBdd.c | 452 + cudd_local/dddmp/dddmpNodeCnf.c | 932 + cudd_local/dddmp/dddmpStoreAdd.c | 957 + cudd_local/dddmp/dddmpStoreBdd.c | 1114 ++ cudd_local/dddmp/dddmpStoreCnf.c | 1583 ++ cudd_local/dddmp/dddmpStoreMisc.c | 1641 ++ cudd_local/dddmp/dddmpUtil.c | 436 + cudd_local/dddmp/doc/cmdIndex.html | 9 + cudd_local/dddmp/doc/commands.html | 12 + cudd_local/dddmp/doc/credit.html | 15 + cudd_local/dddmp/doc/dddmp-2.0-A4.ps | 1261 ++ cudd_local/dddmp/doc/dddmp-2.0-Letter.ps | 1260 ++ cudd_local/dddmp/doc/dddmpAllAbs.html | 483 + cudd_local/dddmp/doc/dddmpAllByFile.html | 13 + cudd_local/dddmp/doc/dddmpAllByFunc.html | 13 + cudd_local/dddmp/doc/dddmpAllDet.html | 3704 ++++ cudd_local/dddmp/doc/dddmpAllFile.html | 679 + cudd_local/dddmp/doc/dddmpDesc.html | 28 + cudd_local/dddmp/doc/dddmpDoc.txt | Bin 0 -> 32768 bytes cudd_local/dddmp/doc/dddmpExt.html | 13 + cudd_local/dddmp/doc/dddmpExtAbs.html | 91 + cudd_local/dddmp/doc/dddmpExtDet.html | 693 + cudd_local/dddmp/doc/dddmpTitle.html | 17 + cudd_local/dddmp/doc/packages.html | 12 + cudd_local/dddmp/doc/pkgIndex.html | 13 + cudd_local/dddmp/exp/0.add | 21 + cudd_local/dddmp/exp/0.bdd | 19 + cudd_local/dddmp/exp/0or1.bdd | 119 + cudd_local/dddmp/exp/1.add | 28 + cudd_local/dddmp/exp/1.bdd | 110 + cudd_local/dddmp/exp/2.bdd | 118 + cudd_local/dddmp/exp/2and3.bdd | 76 + cudd_local/dddmp/exp/3.bdd | 304 + cudd_local/dddmp/exp/4.bdd | 50 + cudd_local/dddmp/exp/4.bdd.bis1 | 50 + cudd_local/dddmp/exp/4.bdd.bis2 | 50 + cudd_local/dddmp/exp/4.bdd.bis3 | 50 + cudd_local/dddmp/exp/4.bdd.bis4 | 50 + cudd_local/dddmp/exp/4.cnf | 130 + cudd_local/dddmp/exp/4.cnf.bis | 130 + cudd_local/dddmp/exp/4.max1 | 125 + cudd_local/dddmp/exp/4.max2 | 125 + cudd_local/dddmp/exp/4bis.bdd | 47 + cudd_local/dddmp/exp/4xor5.bdd | 120 + cudd_local/dddmp/exp/5.bdd | 31 + cudd_local/dddmp/exp/composeids.txt | 20 + cudd_local/dddmp/exp/one.bdd | 13 + cudd_local/dddmp/exp/runAllTest.out | 269 + cudd_local/dddmp/exp/runAllTest.script | 11 + cudd_local/dddmp/exp/s27RP1.bdd | 18 + cudd_local/dddmp/exp/s27deltaDddmp1.bdd | 31 + cudd_local/dddmp/exp/s27deltaDddmp1.bdd.bis | 31 + cudd_local/dddmp/exp/s27deltaDddmp2.bdd | 32 + cudd_local/dddmp/exp/test1.out | 44 + cudd_local/dddmp/exp/test1.script | 26 + cudd_local/dddmp/exp/test2.out | 23 + cudd_local/dddmp/exp/test2.script | 30 + cudd_local/dddmp/exp/test3.out | 18 + cudd_local/dddmp/exp/test3.script | 69 + cudd_local/dddmp/exp/test4.out | 24 + cudd_local/dddmp/exp/test4.script | 56 + cudd_local/dddmp/exp/test5.out | 28 + cudd_local/dddmp/exp/test5.script | 42 + cudd_local/dddmp/exp/test6.out | 31 + cudd_local/dddmp/exp/test6.script | 50 + cudd_local/dddmp/exp/test7.out | 102 + cudd_local/dddmp/exp/test7.script | 150 + cudd_local/dddmp/exp/varauxids.ord | 50 + cudd_local/dddmp/exp/varnames.ord | 50 + cudd_local/dddmp/exp/zero.bdd | 13 + cudd_local/dddmp/libdddmp.a | Bin 0 -> 329040 bytes cudd_local/dddmp/testdddmp.c | 2279 +++ cudd_local/epd/Makefile | 64 + cudd_local/epd/epd.c | 1344 ++ cudd_local/epd/epd.h | 200 + cudd_local/epd/libepd.a | Bin 0 -> 63984 bytes cudd_local/include/cudd.h | 1070 ++ cudd_local/include/cudd/cudd.h | 1070 ++ cudd_local/include/cudd/cuddInt.h | 1188 ++ cudd_local/include/cudd/cuddObj.hh | 762 + cudd_local/include/cudd/dddmp.h | 330 + cudd_local/include/cudd/epd.h | 200 + cudd_local/include/cudd/mnemosyne.h | 73 + cudd_local/include/cudd/mtr.h | 187 + cudd_local/include/cudd/st.h | 232 + cudd_local/include/cudd/util.h | 204 + cudd_local/include/cuddInt.h | 1188 ++ cudd_local/include/cuddObj.hh | 762 + cudd_local/include/dddmp.h | 330 + cudd_local/include/epd.h | 200 + cudd_local/include/mnemosyne.h | 73 + cudd_local/include/mtr.h | 187 + cudd_local/include/st.h | 232 + cudd_local/include/util.h | 204 + cudd_local/mnemosyne/Makefile | 53 + cudd_local/mnemosyne/README | 39 + cudd_local/mnemosyne/mnemalyse.c | 197 + cudd_local/mnemosyne/mnemconf.h | 89 + cudd_local/mnemosyne/mnemosyne.c | 670 + cudd_local/mnemosyne/mnemosyne.h | 73 + cudd_local/mnemosyne/mtest.c | 38 + cudd_local/mtr/Makefile | 96 + cudd_local/mtr/Makefile.sis | 83 + cudd_local/mtr/doc/mtr.doc | 252 + cudd_local/mtr/doc/mtrAllAbs.html | 72 + cudd_local/mtr/doc/mtrAllDet.html | 317 + cudd_local/mtr/doc/mtrExtAbs.html | 72 + cudd_local/mtr/doc/mtrExtDet.html | 324 + cudd_local/mtr/libmtr.a | Bin 0 -> 27176 bytes cudd_local/mtr/mtr.h | 187 + cudd_local/mtr/mtrBasic.c | 450 + cudd_local/mtr/mtrGroup.c | 877 + cudd_local/mtr/mtrInt.h | 92 + cudd_local/mtr/test.groups | 5 + cudd_local/mtr/testmtr.c | 270 + cudd_local/nanotrav/C17.blif | 16 + cudd_local/nanotrav/C17.out | 101 + cudd_local/nanotrav/C880.blif | 770 + cudd_local/nanotrav/C880.out | 101 + cudd_local/nanotrav/Makefile | 98 + cudd_local/nanotrav/README | 47 + cudd_local/nanotrav/bnet.c | 2252 +++ cudd_local/nanotrav/bnet.h | 187 + cudd_local/nanotrav/chkMterm.c | 235 + cudd_local/nanotrav/doc/bnetAllAbs.html | 45 + cudd_local/nanotrav/doc/bnetAllDet.html | 173 + cudd_local/nanotrav/doc/bnetExtAbs.html | 45 + cudd_local/nanotrav/doc/bnetExtDet.html | 173 + cudd_local/nanotrav/doc/ntrAllAbs.html | 114 + cudd_local/nanotrav/doc/ntrAllDet.html | 513 + cudd_local/nanotrav/doc/ntrExtAbs.html | 111 + cudd_local/nanotrav/doc/ntrExtDet.html | 500 + cudd_local/nanotrav/main.c | 1394 ++ cudd_local/nanotrav/mult32a.blif | 745 + cudd_local/nanotrav/mult32a.out | 258 + cudd_local/nanotrav/nanotrav.1 | 379 + cudd_local/nanotrav/ntr.c | 2988 +++ cudd_local/nanotrav/ntr.h | 283 + cudd_local/nanotrav/ntrBddTest.c | 2315 +++ cudd_local/nanotrav/ntrHeap.c | 390 + cudd_local/nanotrav/ntrMflow.c | 1581 ++ cudd_local/nanotrav/ntrShort.c | 578 + cudd_local/nanotrav/ntrZddTest.c | 468 + cudd_local/nanotrav/rcn25.blif | 335 + cudd_local/nanotrav/rcn25.out | 521 + cudd_local/nanotrav/s27.blif | 30 + cudd_local/nanotrav/s27.out | 95 + cudd_local/nanotrav/tst.sh | 9 + cudd_local/nanotrav/ucbqsort.c | 228 + cudd_local/obj/Makefile | 110 + cudd_local/obj/cuddObj.cc | 5699 ++++++ cudd_local/obj/cuddObj.hh | 762 + cudd_local/obj/libobj.a | Bin 0 -> 623312 bytes cudd_local/obj/test.out | 516 + cudd_local/obj/testobj.cc | 607 + cudd_local/setup.sh | 18 + cudd_local/shutdown.sh | 2 + cudd_local/sis/Makefile.sis | 97 + cudd_local/sis/cuddBdd.h | 382 + cudd_local/sis/cuddBddPort.c | 1954 ++ cudd_local/sis/cuddPwPt.c | 147 + cudd_local/sis/st.c | 554 + cudd_local/sis/st.h | 97 + cudd_local/st/Makefile | 64 + cudd_local/st/doc/stAllAbs.html | 96 + cudd_local/st/doc/stAllDet.html | 462 + cudd_local/st/doc/stExtAbs.html | 96 + cudd_local/st/doc/stExtDet.html | 463 + cudd_local/st/libst.a | Bin 0 -> 24656 bytes cudd_local/st/st.c | 1065 ++ cudd_local/st/st.h | 232 + cudd_local/util/Makefile | 64 + cudd_local/util/cpu_stats.c | 89 + cudd_local/util/cpu_time.c | 76 + cudd_local/util/datalimit.c | 50 + cudd_local/util/libutil.a | Bin 0 -> 44208 bytes cudd_local/util/pathsearch.c | 94 + cudd_local/util/pipefork.c | 93 + cudd_local/util/prtime.c | 21 + cudd_local/util/ptime.c | 9 + cudd_local/util/restart.c | 137 + cudd_local/util/safe_mem.c | 97 + cudd_local/util/saveimage.c | 229 + cudd_local/util/state.c | 82 + cudd_local/util/strsav.c | 14 + cudd_local/util/stub.c | 82 + cudd_local/util/test-res.c | 57 + cudd_local/util/test-sav.c | 39 + cudd_local/util/texpand.c | 57 + cudd_local/util/util.h | 204 + cudd_local_enable.sh | 8 + formrsctl.cc | 323 + formrsctl.hh | 332 + in/bench_bc.sh | 67 + in/bench_mutex.sh | 67 + in/bench_pipe.sh | 67 + in/benchmark.sh | 16 + in/benchmark_abs1.sh | 16 + in/benchmark_abs1_PT.sh | 16 + in/benchmark_bc.sh | 16 + in/benchmark_mutex.sh | 16 + in/benchmark_mutex_PT.sh | 16 + in/gen_abstract1.py | 47 + in/gen_bc.py | 118 + in/gen_mutex.py | 76 + in/get_results.sh | 14 + in/hsr.rs | 44 + in/old_syntax/bc32.rs | 1226 ++ in/old_syntax/bc8.rs | 123 + in/old_syntax/coffee.rs | 33 + in/old_syntax/expr.rs | 31 + in/old_syntax/f1.dat | 23 + in/old_syntax/gen_bc.py | 48 + in/old_syntax/simple_I1.rs | 19 + in/old_syntax/test.rs | 20 + in/old_syntax/u1.rs | 24 + in/old_syntax/u2.rs | 24 + in/results/2014-09-01/bc_MT_f1_n1.out | 10 + in/results/2014-09-01/bc_MT_f1_n10.out | 10 + in/results/2014-09-01/bc_MT_f1_n11.out | 10 + in/results/2014-09-01/bc_MT_f1_n12.out | 10 + in/results/2014-09-01/bc_MT_f1_n13.out | 10 + in/results/2014-09-01/bc_MT_f1_n14.out | 10 + in/results/2014-09-01/bc_MT_f1_n15.out | 10 + in/results/2014-09-01/bc_MT_f1_n16.out | 10 + in/results/2014-09-01/bc_MT_f1_n17.out | 10 + in/results/2014-09-01/bc_MT_f1_n18.out | 10 + in/results/2014-09-01/bc_MT_f1_n19.out | 10 + in/results/2014-09-01/bc_MT_f1_n2.out | 10 + in/results/2014-09-01/bc_MT_f1_n20.out | 10 + in/results/2014-09-01/bc_MT_f1_n21.out | 10 + in/results/2014-09-01/bc_MT_f1_n22.out | 10 + in/results/2014-09-01/bc_MT_f1_n23.out | 10 + in/results/2014-09-01/bc_MT_f1_n24.out | 10 + in/results/2014-09-01/bc_MT_f1_n25.out | 2 + in/results/2014-09-01/bc_MT_f1_n3.out | 10 + in/results/2014-09-01/bc_MT_f1_n4.out | 10 + in/results/2014-09-01/bc_MT_f1_n5.out | 10 + in/results/2014-09-01/bc_MT_f1_n6.out | 10 + in/results/2014-09-01/bc_MT_f1_n7.out | 10 + in/results/2014-09-01/bc_MT_f1_n8.out | 10 + in/results/2014-09-01/bc_MT_f1_n9.out | 10 + in/results/2014-09-01/bc_MT_f2_n1.out | 10 + in/results/2014-09-01/bc_MT_f2_n10.out | 10 + in/results/2014-09-01/bc_MT_f2_n11.out | 10 + in/results/2014-09-01/bc_MT_f2_n12.out | 10 + in/results/2014-09-01/bc_MT_f2_n13.out | 10 + in/results/2014-09-01/bc_MT_f2_n14.out | 10 + in/results/2014-09-01/bc_MT_f2_n15.out | 10 + in/results/2014-09-01/bc_MT_f2_n16.out | 10 + in/results/2014-09-01/bc_MT_f2_n17.out | 10 + in/results/2014-09-01/bc_MT_f2_n18.out | 10 + in/results/2014-09-01/bc_MT_f2_n19.out | 10 + in/results/2014-09-01/bc_MT_f2_n2.out | 10 + in/results/2014-09-01/bc_MT_f2_n20.out | 10 + in/results/2014-09-01/bc_MT_f2_n21.out | 10 + in/results/2014-09-01/bc_MT_f2_n22.out | 10 + in/results/2014-09-01/bc_MT_f2_n23.out | 10 + in/results/2014-09-01/bc_MT_f2_n24.out | 10 + in/results/2014-09-01/bc_MT_f2_n25.out | 10 + in/results/2014-09-01/bc_MT_f2_n3.out | 10 + in/results/2014-09-01/bc_MT_f2_n4.out | 10 + in/results/2014-09-01/bc_MT_f2_n5.out | 10 + in/results/2014-09-01/bc_MT_f2_n6.out | 10 + in/results/2014-09-01/bc_MT_f2_n7.out | 10 + in/results/2014-09-01/bc_MT_f2_n8.out | 10 + in/results/2014-09-01/bc_MT_f2_n9.out | 10 + in/results/2014-09-01/bc_MT_f3_n10.out | 10 + in/results/2014-09-01/bc_MT_f3_n11.out | 10 + in/results/2014-09-01/bc_MT_f3_n12.out | 10 + in/results/2014-09-01/bc_MT_f3_n13.out | 10 + in/results/2014-09-01/bc_MT_f3_n14.out | 10 + in/results/2014-09-01/bc_MT_f3_n15.out | 10 + in/results/2014-09-01/bc_MT_f3_n16.out | 10 + in/results/2014-09-01/bc_MT_f3_n17.out | 10 + in/results/2014-09-01/bc_MT_f3_n18.out | 10 + in/results/2014-09-01/bc_MT_f3_n19.out | 10 + in/results/2014-09-01/bc_MT_f3_n20.out | 10 + in/results/2014-09-01/bc_MT_f3_n21.out | 10 + in/results/2014-09-01/bc_MT_f3_n22.out | 10 + in/results/2014-09-01/bc_MT_f3_n23.out | 10 + in/results/2014-09-01/bc_MT_f3_n24.out | 10 + in/results/2014-09-01/bc_MT_f3_n25.out | 10 + in/results/2014-09-01/bc_MT_f4_n1.out | 10 + in/results/2014-09-01/bc_MT_f4_n10.out | 10 + in/results/2014-09-01/bc_MT_f4_n11.out | 10 + in/results/2014-09-01/bc_MT_f4_n12.out | 10 + in/results/2014-09-01/bc_MT_f4_n13.out | 10 + in/results/2014-09-01/bc_MT_f4_n14.out | 10 + in/results/2014-09-01/bc_MT_f4_n15.out | 10 + in/results/2014-09-01/bc_MT_f4_n16.out | 10 + in/results/2014-09-01/bc_MT_f4_n17.out | 10 + in/results/2014-09-01/bc_MT_f4_n18.out | 10 + in/results/2014-09-01/bc_MT_f4_n19.out | 10 + in/results/2014-09-01/bc_MT_f4_n2.out | 10 + in/results/2014-09-01/bc_MT_f4_n20.out | 10 + in/results/2014-09-01/bc_MT_f4_n21.out | 10 + in/results/2014-09-01/bc_MT_f4_n22.out | 10 + in/results/2014-09-01/bc_MT_f4_n23.out | 10 + in/results/2014-09-01/bc_MT_f4_n24.out | 10 + in/results/2014-09-01/bc_MT_f4_n25.out | 10 + in/results/2014-09-01/bc_MT_f4_n3.out | 10 + in/results/2014-09-01/bc_MT_f4_n4.out | 10 + in/results/2014-09-01/bc_MT_f4_n5.out | 10 + in/results/2014-09-01/bc_MT_f4_n6.out | 10 + in/results/2014-09-01/bc_MT_f4_n7.out | 10 + in/results/2014-09-01/bc_MT_f4_n8.out | 10 + in/results/2014-09-01/bc_MT_f4_n9.out | 10 + in/results/2014-09-01/bc_PT_f1_n1.out | 10 + in/results/2014-09-01/bc_PT_f1_n10.out | 10 + in/results/2014-09-01/bc_PT_f1_n11.out | 10 + in/results/2014-09-01/bc_PT_f1_n12.out | 10 + in/results/2014-09-01/bc_PT_f1_n13.out | 10 + in/results/2014-09-01/bc_PT_f1_n14.out | 10 + in/results/2014-09-01/bc_PT_f1_n15.out | 10 + in/results/2014-09-01/bc_PT_f1_n16.out | 10 + in/results/2014-09-01/bc_PT_f1_n17.out | 10 + in/results/2014-09-01/bc_PT_f1_n18.out | 10 + in/results/2014-09-01/bc_PT_f1_n19.out | 10 + in/results/2014-09-01/bc_PT_f1_n2.out | 10 + in/results/2014-09-01/bc_PT_f1_n20.out | 10 + in/results/2014-09-01/bc_PT_f1_n21.out | 10 + in/results/2014-09-01/bc_PT_f1_n22.out | 2 + in/results/2014-09-01/bc_PT_f1_n23.out | 2 + in/results/2014-09-01/bc_PT_f1_n24.out | 2 + in/results/2014-09-01/bc_PT_f1_n25.out | 2 + in/results/2014-09-01/bc_PT_f1_n3.out | 10 + in/results/2014-09-01/bc_PT_f1_n4.out | 10 + in/results/2014-09-01/bc_PT_f1_n5.out | 10 + in/results/2014-09-01/bc_PT_f1_n6.out | 10 + in/results/2014-09-01/bc_PT_f1_n7.out | 10 + in/results/2014-09-01/bc_PT_f1_n8.out | 10 + in/results/2014-09-01/bc_PT_f1_n9.out | 10 + in/results/2014-09-01/bc_PT_f2_n1.out | 10 + in/results/2014-09-01/bc_PT_f2_n10.out | 10 + in/results/2014-09-01/bc_PT_f2_n11.out | 10 + in/results/2014-09-01/bc_PT_f2_n12.out | 10 + in/results/2014-09-01/bc_PT_f2_n13.out | 10 + in/results/2014-09-01/bc_PT_f2_n14.out | 10 + in/results/2014-09-01/bc_PT_f2_n15.out | 10 + in/results/2014-09-01/bc_PT_f2_n16.out | 10 + in/results/2014-09-01/bc_PT_f2_n17.out | 10 + in/results/2014-09-01/bc_PT_f2_n18.out | 10 + in/results/2014-09-01/bc_PT_f2_n19.out | 10 + in/results/2014-09-01/bc_PT_f2_n2.out | 10 + in/results/2014-09-01/bc_PT_f2_n20.out | 10 + in/results/2014-09-01/bc_PT_f2_n21.out | 10 + in/results/2014-09-01/bc_PT_f2_n22.out | 10 + in/results/2014-09-01/bc_PT_f2_n23.out | 2 + in/results/2014-09-01/bc_PT_f2_n24.out | 2 + in/results/2014-09-01/bc_PT_f2_n25.out | 2 + in/results/2014-09-01/bc_PT_f2_n3.out | 10 + in/results/2014-09-01/bc_PT_f2_n4.out | 10 + in/results/2014-09-01/bc_PT_f2_n5.out | 10 + in/results/2014-09-01/bc_PT_f2_n6.out | 10 + in/results/2014-09-01/bc_PT_f2_n7.out | 10 + in/results/2014-09-01/bc_PT_f2_n8.out | 10 + in/results/2014-09-01/bc_PT_f2_n9.out | 10 + in/results/2014-09-01/bc_PT_f3_n10.out | 10 + in/results/2014-09-01/bc_PT_f3_n11.out | 10 + in/results/2014-09-01/bc_PT_f3_n12.out | 10 + in/results/2014-09-01/bc_PT_f3_n13.out | 10 + in/results/2014-09-01/bc_PT_f3_n14.out | 10 + in/results/2014-09-01/bc_PT_f3_n15.out | 10 + in/results/2014-09-01/bc_PT_f3_n16.out | 10 + in/results/2014-09-01/bc_PT_f3_n17.out | 10 + in/results/2014-09-01/bc_PT_f3_n18.out | 10 + in/results/2014-09-01/bc_PT_f3_n19.out | 10 + in/results/2014-09-01/bc_PT_f3_n20.out | 10 + in/results/2014-09-01/bc_PT_f3_n21.out | 10 + in/results/2014-09-01/bc_PT_f3_n22.out | 10 + in/results/2014-09-01/bc_PT_f3_n23.out | 10 + in/results/2014-09-01/bc_PT_f3_n24.out | 10 + in/results/2014-09-01/bc_PT_f3_n25.out | 10 + in/results/2014-09-01/bc_PT_f4_n1.out | 10 + in/results/2014-09-01/bc_PT_f4_n10.out | 10 + in/results/2014-09-01/bc_PT_f4_n11.out | 10 + in/results/2014-09-01/bc_PT_f4_n12.out | 10 + in/results/2014-09-01/bc_PT_f4_n13.out | 10 + in/results/2014-09-01/bc_PT_f4_n14.out | 10 + in/results/2014-09-01/bc_PT_f4_n15.out | 10 + in/results/2014-09-01/bc_PT_f4_n16.out | 10 + in/results/2014-09-01/bc_PT_f4_n17.out | 10 + in/results/2014-09-01/bc_PT_f4_n18.out | 10 + in/results/2014-09-01/bc_PT_f4_n19.out | 10 + in/results/2014-09-01/bc_PT_f4_n2.out | 10 + in/results/2014-09-01/bc_PT_f4_n20.out | 10 + in/results/2014-09-01/bc_PT_f4_n21.out | 10 + in/results/2014-09-01/bc_PT_f4_n22.out | 10 + in/results/2014-09-01/bc_PT_f4_n23.out | 2 + in/results/2014-09-01/bc_PT_f4_n24.out | 2 + in/results/2014-09-01/bc_PT_f4_n25.out | 2 + in/results/2014-09-01/bc_PT_f4_n3.out | 10 + in/results/2014-09-01/bc_PT_f4_n4.out | 10 + in/results/2014-09-01/bc_PT_f4_n5.out | 10 + in/results/2014-09-01/bc_PT_f4_n6.out | 10 + in/results/2014-09-01/bc_PT_f4_n7.out | 10 + in/results/2014-09-01/bc_PT_f4_n8.out | 10 + in/results/2014-09-01/bc_PT_f4_n9.out | 10 + in/results/2014-09-01/bc_f1.dat | 24 + in/results/2014-09-01/bc_f1_pt.dat | 21 + in/results/2014-09-01/bc_f2.dat | 25 + in/results/2014-09-01/bc_f2_pt.dat | 22 + in/results/2014-09-01/bc_f3.dat | 16 + in/results/2014-09-01/bc_f3_pt.dat | 16 + in/results/2014-09-01/bc_f4.dat | 25 + in/results/2014-09-01/bc_f4_pt.dat | 22 + in/results/2014-09-01/summary_bc_MT_f1 | 24 + in/results/2014-09-01/summary_bc_MT_f2 | 25 + in/results/2014-09-01/summary_bc_MT_f3 | 16 + in/results/2014-09-01/summary_bc_MT_f4 | 25 + in/results/2014-09-01/summary_bc_PT_f1 | 21 + in/results/2014-09-01/summary_bc_PT_f2 | 22 + in/results/2014-09-01/summary_bc_PT_f3 | 16 + in/results/2014-09-01/summary_bc_PT_f4 | 22 + in/results/2014-09-16/bc_MT_f1_n1.out | 10 + in/results/2014-09-16/bc_MT_f1_n10.out | 10 + in/results/2014-09-16/bc_MT_f1_n11.out | 10 + in/results/2014-09-16/bc_MT_f1_n12.out | 10 + in/results/2014-09-16/bc_MT_f1_n13.out | 10 + in/results/2014-09-16/bc_MT_f1_n14.out | 10 + in/results/2014-09-16/bc_MT_f1_n15.out | 10 + in/results/2014-09-16/bc_MT_f1_n16.out | 10 + in/results/2014-09-16/bc_MT_f1_n17.out | 10 + in/results/2014-09-16/bc_MT_f1_n18.out | 10 + in/results/2014-09-16/bc_MT_f1_n19.out | 10 + in/results/2014-09-16/bc_MT_f1_n2.out | 10 + in/results/2014-09-16/bc_MT_f1_n20.out | 10 + in/results/2014-09-16/bc_MT_f1_n21.out | 10 + in/results/2014-09-16/bc_MT_f1_n22.out | 10 + in/results/2014-09-16/bc_MT_f1_n23.out | 10 + in/results/2014-09-16/bc_MT_f1_n24.out | 10 + in/results/2014-09-16/bc_MT_f1_n25.out | 2 + in/results/2014-09-16/bc_MT_f1_n3.out | 10 + in/results/2014-09-16/bc_MT_f1_n4.out | 10 + in/results/2014-09-16/bc_MT_f1_n5.out | 10 + in/results/2014-09-16/bc_MT_f1_n6.out | 10 + in/results/2014-09-16/bc_MT_f1_n7.out | 10 + in/results/2014-09-16/bc_MT_f1_n8.out | 10 + in/results/2014-09-16/bc_MT_f1_n9.out | 10 + in/results/2014-09-16/bc_MT_f2_n1.out | 10 + in/results/2014-09-16/bc_MT_f2_n10.out | 10 + in/results/2014-09-16/bc_MT_f2_n11.out | 10 + in/results/2014-09-16/bc_MT_f2_n12.out | 10 + in/results/2014-09-16/bc_MT_f2_n13.out | 10 + in/results/2014-09-16/bc_MT_f2_n14.out | 10 + in/results/2014-09-16/bc_MT_f2_n15.out | 10 + in/results/2014-09-16/bc_MT_f2_n16.out | 10 + in/results/2014-09-16/bc_MT_f2_n17.out | 10 + in/results/2014-09-16/bc_MT_f2_n18.out | 10 + in/results/2014-09-16/bc_MT_f2_n19.out | 10 + in/results/2014-09-16/bc_MT_f2_n2.out | 10 + in/results/2014-09-16/bc_MT_f2_n20.out | 10 + in/results/2014-09-16/bc_MT_f2_n21.out | 10 + in/results/2014-09-16/bc_MT_f2_n22.out | 10 + in/results/2014-09-16/bc_MT_f2_n23.out | 10 + in/results/2014-09-16/bc_MT_f2_n24.out | 10 + in/results/2014-09-16/bc_MT_f2_n25.out | 10 + in/results/2014-09-16/bc_MT_f2_n3.out | 10 + in/results/2014-09-16/bc_MT_f2_n4.out | 10 + in/results/2014-09-16/bc_MT_f2_n5.out | 10 + in/results/2014-09-16/bc_MT_f2_n6.out | 10 + in/results/2014-09-16/bc_MT_f2_n7.out | 10 + in/results/2014-09-16/bc_MT_f2_n8.out | 10 + in/results/2014-09-16/bc_MT_f2_n9.out | 10 + in/results/2014-09-16/bc_MT_f3_n10.out | 10 + in/results/2014-09-16/bc_MT_f3_n11.out | 10 + in/results/2014-09-16/bc_MT_f3_n12.out | 10 + in/results/2014-09-16/bc_MT_f3_n13.out | 10 + in/results/2014-09-16/bc_MT_f3_n14.out | 10 + in/results/2014-09-16/bc_MT_f3_n15.out | 10 + in/results/2014-09-16/bc_MT_f3_n16.out | 10 + in/results/2014-09-16/bc_MT_f3_n17.out | 10 + in/results/2014-09-16/bc_MT_f3_n18.out | 10 + in/results/2014-09-16/bc_MT_f3_n19.out | 10 + in/results/2014-09-16/bc_MT_f3_n20.out | 10 + in/results/2014-09-16/bc_MT_f3_n21.out | 10 + in/results/2014-09-16/bc_MT_f3_n22.out | 10 + in/results/2014-09-16/bc_MT_f3_n23.out | 10 + in/results/2014-09-16/bc_MT_f3_n24.out | 10 + in/results/2014-09-16/bc_MT_f3_n25.out | 10 + in/results/2014-09-16/bc_MT_f4_n1.out | 10 + in/results/2014-09-16/bc_MT_f4_n10.out | 10 + in/results/2014-09-16/bc_MT_f4_n11.out | 10 + in/results/2014-09-16/bc_MT_f4_n12.out | 10 + in/results/2014-09-16/bc_MT_f4_n13.out | 10 + in/results/2014-09-16/bc_MT_f4_n14.out | 10 + in/results/2014-09-16/bc_MT_f4_n15.out | 10 + in/results/2014-09-16/bc_MT_f4_n16.out | 10 + in/results/2014-09-16/bc_MT_f4_n17.out | 10 + in/results/2014-09-16/bc_MT_f4_n18.out | 10 + in/results/2014-09-16/bc_MT_f4_n19.out | 10 + in/results/2014-09-16/bc_MT_f4_n2.out | 10 + in/results/2014-09-16/bc_MT_f4_n20.out | 10 + in/results/2014-09-16/bc_MT_f4_n21.out | 10 + in/results/2014-09-16/bc_MT_f4_n22.out | 10 + in/results/2014-09-16/bc_MT_f4_n23.out | 10 + in/results/2014-09-16/bc_MT_f4_n24.out | 10 + in/results/2014-09-16/bc_MT_f4_n25.out | 10 + in/results/2014-09-16/bc_MT_f4_n3.out | 10 + in/results/2014-09-16/bc_MT_f4_n4.out | 10 + in/results/2014-09-16/bc_MT_f4_n5.out | 10 + in/results/2014-09-16/bc_MT_f4_n6.out | 10 + in/results/2014-09-16/bc_MT_f4_n7.out | 10 + in/results/2014-09-16/bc_MT_f4_n8.out | 10 + in/results/2014-09-16/bc_MT_f4_n9.out | 10 + in/results/2014-09-16/bc_PT_f1_n1.out | 10 + in/results/2014-09-16/bc_PT_f1_n10.out | 10 + in/results/2014-09-16/bc_PT_f1_n11.out | 10 + in/results/2014-09-16/bc_PT_f1_n12.out | 10 + in/results/2014-09-16/bc_PT_f1_n13.out | 10 + in/results/2014-09-16/bc_PT_f1_n14.out | 10 + in/results/2014-09-16/bc_PT_f1_n15.out | 10 + in/results/2014-09-16/bc_PT_f1_n16.out | 10 + in/results/2014-09-16/bc_PT_f1_n17.out | 10 + in/results/2014-09-16/bc_PT_f1_n18.out | 10 + in/results/2014-09-16/bc_PT_f1_n19.out | 10 + in/results/2014-09-16/bc_PT_f1_n2.out | 10 + in/results/2014-09-16/bc_PT_f1_n20.out | 10 + in/results/2014-09-16/bc_PT_f1_n21.out | 10 + in/results/2014-09-16/bc_PT_f1_n22.out | 2 + in/results/2014-09-16/bc_PT_f1_n23.out | 2 + in/results/2014-09-16/bc_PT_f1_n24.out | 2 + in/results/2014-09-16/bc_PT_f1_n25.out | 2 + in/results/2014-09-16/bc_PT_f1_n3.out | 10 + in/results/2014-09-16/bc_PT_f1_n4.out | 10 + in/results/2014-09-16/bc_PT_f1_n5.out | 10 + in/results/2014-09-16/bc_PT_f1_n6.out | 10 + in/results/2014-09-16/bc_PT_f1_n7.out | 10 + in/results/2014-09-16/bc_PT_f1_n8.out | 10 + in/results/2014-09-16/bc_PT_f1_n9.out | 10 + in/results/2014-09-16/bc_PT_f2_n1.out | 10 + in/results/2014-09-16/bc_PT_f2_n10.out | 10 + in/results/2014-09-16/bc_PT_f2_n11.out | 10 + in/results/2014-09-16/bc_PT_f2_n12.out | 10 + in/results/2014-09-16/bc_PT_f2_n13.out | 10 + in/results/2014-09-16/bc_PT_f2_n14.out | 10 + in/results/2014-09-16/bc_PT_f2_n15.out | 10 + in/results/2014-09-16/bc_PT_f2_n16.out | 10 + in/results/2014-09-16/bc_PT_f2_n17.out | 10 + in/results/2014-09-16/bc_PT_f2_n18.out | 10 + in/results/2014-09-16/bc_PT_f2_n19.out | 10 + in/results/2014-09-16/bc_PT_f2_n2.out | 10 + in/results/2014-09-16/bc_PT_f2_n20.out | 10 + in/results/2014-09-16/bc_PT_f2_n21.out | 10 + in/results/2014-09-16/bc_PT_f2_n22.out | 10 + in/results/2014-09-16/bc_PT_f2_n23.out | 2 + in/results/2014-09-16/bc_PT_f2_n24.out | 2 + in/results/2014-09-16/bc_PT_f2_n25.out | 2 + in/results/2014-09-16/bc_PT_f2_n3.out | 10 + in/results/2014-09-16/bc_PT_f2_n4.out | 10 + in/results/2014-09-16/bc_PT_f2_n5.out | 10 + in/results/2014-09-16/bc_PT_f2_n6.out | 10 + in/results/2014-09-16/bc_PT_f2_n7.out | 10 + in/results/2014-09-16/bc_PT_f2_n8.out | 10 + in/results/2014-09-16/bc_PT_f2_n9.out | 10 + in/results/2014-09-16/bc_PT_f3_n10.out | 10 + in/results/2014-09-16/bc_PT_f3_n11.out | 10 + in/results/2014-09-16/bc_PT_f3_n12.out | 10 + in/results/2014-09-16/bc_PT_f3_n13.out | 10 + in/results/2014-09-16/bc_PT_f3_n14.out | 10 + in/results/2014-09-16/bc_PT_f3_n15.out | 10 + in/results/2014-09-16/bc_PT_f3_n16.out | 10 + in/results/2014-09-16/bc_PT_f3_n17.out | 10 + in/results/2014-09-16/bc_PT_f3_n18.out | 10 + in/results/2014-09-16/bc_PT_f3_n19.out | 10 + in/results/2014-09-16/bc_PT_f3_n20.out | 10 + in/results/2014-09-16/bc_PT_f3_n21.out | 10 + in/results/2014-09-16/bc_PT_f3_n22.out | 10 + in/results/2014-09-16/bc_PT_f3_n23.out | 10 + in/results/2014-09-16/bc_PT_f3_n24.out | 10 + in/results/2014-09-16/bc_PT_f3_n25.out | 10 + in/results/2014-09-16/bc_PT_f4_n1.out | 10 + in/results/2014-09-16/bc_PT_f4_n10.out | 10 + in/results/2014-09-16/bc_PT_f4_n11.out | 10 + in/results/2014-09-16/bc_PT_f4_n12.out | 10 + in/results/2014-09-16/bc_PT_f4_n13.out | 10 + in/results/2014-09-16/bc_PT_f4_n14.out | 10 + in/results/2014-09-16/bc_PT_f4_n15.out | 10 + in/results/2014-09-16/bc_PT_f4_n16.out | 10 + in/results/2014-09-16/bc_PT_f4_n17.out | 10 + in/results/2014-09-16/bc_PT_f4_n18.out | 10 + in/results/2014-09-16/bc_PT_f4_n19.out | 10 + in/results/2014-09-16/bc_PT_f4_n2.out | 10 + in/results/2014-09-16/bc_PT_f4_n20.out | 10 + in/results/2014-09-16/bc_PT_f4_n21.out | 10 + in/results/2014-09-16/bc_PT_f4_n22.out | 10 + in/results/2014-09-16/bc_PT_f4_n23.out | 2 + in/results/2014-09-16/bc_PT_f4_n24.out | 2 + in/results/2014-09-16/bc_PT_f4_n25.out | 2 + in/results/2014-09-16/bc_PT_f4_n3.out | 10 + in/results/2014-09-16/bc_PT_f4_n4.out | 10 + in/results/2014-09-16/bc_PT_f4_n5.out | 10 + in/results/2014-09-16/bc_PT_f4_n6.out | 10 + in/results/2014-09-16/bc_PT_f4_n7.out | 10 + in/results/2014-09-16/bc_PT_f4_n8.out | 10 + in/results/2014-09-16/bc_PT_f4_n9.out | 10 + in/results/2014-09-16/bc_f1.dat | 24 + in/results/2014-09-16/bc_f1_pt.dat | 21 + in/results/2014-09-16/bc_f2.dat | 25 + in/results/2014-09-16/bc_f2_pt.dat | 22 + in/results/2014-09-16/bc_f3.dat | 16 + in/results/2014-09-16/bc_f3_pt.dat | 16 + in/results/2014-09-16/bc_f4.dat | 25 + in/results/2014-09-16/bc_f4_pt.dat | 22 + in/results/2014-09-16/mutex_MT_f1_n10.out | 10 + in/results/2014-09-16/mutex_MT_f1_n11.out | 10 + in/results/2014-09-16/mutex_MT_f1_n12.out | 10 + in/results/2014-09-16/mutex_MT_f1_n13.out | 10 + in/results/2014-09-16/mutex_MT_f1_n14.out | 10 + in/results/2014-09-16/mutex_MT_f1_n15.out | 10 + in/results/2014-09-16/mutex_MT_f1_n16.out | 10 + in/results/2014-09-16/mutex_MT_f1_n17.out | 10 + in/results/2014-09-16/mutex_MT_f1_n18.out | 10 + in/results/2014-09-16/mutex_MT_f1_n19.out | 10 + in/results/2014-09-16/mutex_MT_f1_n2.out | 10 + in/results/2014-09-16/mutex_MT_f1_n20.out | 10 + in/results/2014-09-16/mutex_MT_f1_n21.out | 10 + in/results/2014-09-16/mutex_MT_f1_n22.out | 10 + in/results/2014-09-16/mutex_MT_f1_n23.out | 2 + in/results/2014-09-16/mutex_MT_f1_n24.out | 2 + in/results/2014-09-16/mutex_MT_f1_n25.out | 2 + in/results/2014-09-16/mutex_MT_f1_n26.out | 2 + in/results/2014-09-16/mutex_MT_f1_n27.out | 2 + in/results/2014-09-16/mutex_MT_f1_n28.out | 2 + in/results/2014-09-16/mutex_MT_f1_n29.out | 2 + in/results/2014-09-16/mutex_MT_f1_n3.out | 10 + in/results/2014-09-16/mutex_MT_f1_n30.out | 2 + in/results/2014-09-16/mutex_MT_f1_n31.out | 2 + in/results/2014-09-16/mutex_MT_f1_n32.out | 2 + in/results/2014-09-16/mutex_MT_f1_n33.out | 2 + in/results/2014-09-16/mutex_MT_f1_n34.out | 2 + in/results/2014-09-16/mutex_MT_f1_n35.out | 2 + in/results/2014-09-16/mutex_MT_f1_n36.out | 2 + in/results/2014-09-16/mutex_MT_f1_n37.out | 2 + in/results/2014-09-16/mutex_MT_f1_n38.out | 2 + in/results/2014-09-16/mutex_MT_f1_n39.out | 2 + in/results/2014-09-16/mutex_MT_f1_n4.out | 10 + in/results/2014-09-16/mutex_MT_f1_n40.out | 2 + in/results/2014-09-16/mutex_MT_f1_n5.out | 10 + in/results/2014-09-16/mutex_MT_f1_n6.out | 10 + in/results/2014-09-16/mutex_MT_f1_n7.out | 10 + in/results/2014-09-16/mutex_MT_f1_n8.out | 10 + in/results/2014-09-16/mutex_MT_f1_n9.out | 10 + in/results/2014-09-16/mutex_MT_f2_n10.out | 10 + in/results/2014-09-16/mutex_MT_f2_n11.out | 10 + in/results/2014-09-16/mutex_MT_f2_n12.out | 10 + in/results/2014-09-16/mutex_MT_f2_n13.out | 10 + in/results/2014-09-16/mutex_MT_f2_n14.out | 10 + in/results/2014-09-16/mutex_MT_f2_n15.out | 10 + in/results/2014-09-16/mutex_MT_f2_n16.out | 10 + in/results/2014-09-16/mutex_MT_f2_n17.out | 10 + in/results/2014-09-16/mutex_MT_f2_n18.out | 10 + in/results/2014-09-16/mutex_MT_f2_n19.out | 10 + in/results/2014-09-16/mutex_MT_f2_n2.out | 10 + in/results/2014-09-16/mutex_MT_f2_n20.out | 10 + in/results/2014-09-16/mutex_MT_f2_n21.out | 10 + in/results/2014-09-16/mutex_MT_f2_n22.out | 10 + in/results/2014-09-16/mutex_MT_f2_n23.out | 2 + in/results/2014-09-16/mutex_MT_f2_n24.out | 2 + in/results/2014-09-16/mutex_MT_f2_n25.out | 2 + in/results/2014-09-16/mutex_MT_f2_n26.out | 2 + in/results/2014-09-16/mutex_MT_f2_n27.out | 2 + in/results/2014-09-16/mutex_MT_f2_n28.out | 2 + in/results/2014-09-16/mutex_MT_f2_n29.out | 2 + in/results/2014-09-16/mutex_MT_f2_n3.out | 10 + in/results/2014-09-16/mutex_MT_f2_n30.out | 2 + in/results/2014-09-16/mutex_MT_f2_n31.out | 2 + in/results/2014-09-16/mutex_MT_f2_n32.out | 2 + in/results/2014-09-16/mutex_MT_f2_n33.out | 2 + in/results/2014-09-16/mutex_MT_f2_n34.out | 2 + in/results/2014-09-16/mutex_MT_f2_n35.out | 2 + in/results/2014-09-16/mutex_MT_f2_n36.out | 2 + in/results/2014-09-16/mutex_MT_f2_n37.out | 2 + in/results/2014-09-16/mutex_MT_f2_n38.out | 2 + in/results/2014-09-16/mutex_MT_f2_n39.out | 2 + in/results/2014-09-16/mutex_MT_f2_n4.out | 10 + in/results/2014-09-16/mutex_MT_f2_n40.out | 2 + in/results/2014-09-16/mutex_MT_f2_n5.out | 10 + in/results/2014-09-16/mutex_MT_f2_n6.out | 10 + in/results/2014-09-16/mutex_MT_f2_n7.out | 10 + in/results/2014-09-16/mutex_MT_f2_n8.out | 10 + in/results/2014-09-16/mutex_MT_f2_n9.out | 10 + in/results/2014-09-16/mutex_MT_f3_n10.out | 10 + in/results/2014-09-16/mutex_MT_f3_n11.out | 10 + in/results/2014-09-16/mutex_MT_f3_n12.out | 10 + in/results/2014-09-16/mutex_MT_f3_n13.out | 10 + in/results/2014-09-16/mutex_MT_f3_n14.out | 10 + in/results/2014-09-16/mutex_MT_f3_n15.out | 10 + in/results/2014-09-16/mutex_MT_f3_n16.out | 10 + in/results/2014-09-16/mutex_MT_f3_n17.out | 10 + in/results/2014-09-16/mutex_MT_f3_n18.out | 10 + in/results/2014-09-16/mutex_MT_f3_n19.out | 10 + in/results/2014-09-16/mutex_MT_f3_n2.out | 10 + in/results/2014-09-16/mutex_MT_f3_n20.out | 10 + in/results/2014-09-16/mutex_MT_f3_n21.out | 10 + in/results/2014-09-16/mutex_MT_f3_n22.out | 10 + in/results/2014-09-16/mutex_MT_f3_n23.out | 2 + in/results/2014-09-16/mutex_MT_f3_n24.out | 2 + in/results/2014-09-16/mutex_MT_f3_n25.out | 2 + in/results/2014-09-16/mutex_MT_f3_n26.out | 2 + in/results/2014-09-16/mutex_MT_f3_n27.out | 2 + in/results/2014-09-16/mutex_MT_f3_n28.out | 2 + in/results/2014-09-16/mutex_MT_f3_n29.out | 2 + in/results/2014-09-16/mutex_MT_f3_n3.out | 10 + in/results/2014-09-16/mutex_MT_f3_n30.out | 2 + in/results/2014-09-16/mutex_MT_f3_n31.out | 2 + in/results/2014-09-16/mutex_MT_f3_n32.out | 2 + in/results/2014-09-16/mutex_MT_f3_n33.out | 2 + in/results/2014-09-16/mutex_MT_f3_n34.out | 2 + in/results/2014-09-16/mutex_MT_f3_n35.out | 2 + in/results/2014-09-16/mutex_MT_f3_n36.out | 2 + in/results/2014-09-16/mutex_MT_f3_n37.out | 2 + in/results/2014-09-16/mutex_MT_f3_n38.out | 2 + in/results/2014-09-16/mutex_MT_f3_n39.out | 2 + in/results/2014-09-16/mutex_MT_f3_n4.out | 10 + in/results/2014-09-16/mutex_MT_f3_n40.out | 2 + in/results/2014-09-16/mutex_MT_f3_n5.out | 10 + in/results/2014-09-16/mutex_MT_f3_n6.out | 10 + in/results/2014-09-16/mutex_MT_f3_n7.out | 10 + in/results/2014-09-16/mutex_MT_f3_n8.out | 10 + in/results/2014-09-16/mutex_MT_f3_n9.out | 10 + in/results/2014-09-16/mutex_PT_f1_n10.out | 10 + in/results/2014-09-16/mutex_PT_f1_n11.out | 2 + in/results/2014-09-16/mutex_PT_f1_n12.out | 2 + in/results/2014-09-16/mutex_PT_f1_n13.out | 2 + in/results/2014-09-16/mutex_PT_f1_n14.out | 2 + in/results/2014-09-16/mutex_PT_f1_n15.out | 2 + in/results/2014-09-16/mutex_PT_f1_n16.out | 2 + in/results/2014-09-16/mutex_PT_f1_n17.out | 2 + in/results/2014-09-16/mutex_PT_f1_n18.out | 2 + in/results/2014-09-16/mutex_PT_f1_n19.out | 2 + in/results/2014-09-16/mutex_PT_f1_n2.out | 10 + in/results/2014-09-16/mutex_PT_f1_n20.out | 2 + in/results/2014-09-16/mutex_PT_f1_n21.out | 2 + in/results/2014-09-16/mutex_PT_f1_n22.out | 2 + in/results/2014-09-16/mutex_PT_f1_n23.out | 2 + in/results/2014-09-16/mutex_PT_f1_n24.out | 2 + in/results/2014-09-16/mutex_PT_f1_n25.out | 2 + in/results/2014-09-16/mutex_PT_f1_n26.out | 2 + in/results/2014-09-16/mutex_PT_f1_n27.out | 2 + in/results/2014-09-16/mutex_PT_f1_n28.out | 2 + in/results/2014-09-16/mutex_PT_f1_n29.out | 2 + in/results/2014-09-16/mutex_PT_f1_n3.out | 10 + in/results/2014-09-16/mutex_PT_f1_n30.out | 2 + in/results/2014-09-16/mutex_PT_f1_n31.out | 2 + in/results/2014-09-16/mutex_PT_f1_n32.out | 2 + in/results/2014-09-16/mutex_PT_f1_n33.out | 2 + in/results/2014-09-16/mutex_PT_f1_n34.out | 2 + in/results/2014-09-16/mutex_PT_f1_n35.out | 2 + in/results/2014-09-16/mutex_PT_f1_n36.out | 2 + in/results/2014-09-16/mutex_PT_f1_n37.out | 2 + in/results/2014-09-16/mutex_PT_f1_n38.out | 2 + in/results/2014-09-16/mutex_PT_f1_n39.out | 2 + in/results/2014-09-16/mutex_PT_f1_n4.out | 10 + in/results/2014-09-16/mutex_PT_f1_n40.out | 2 + in/results/2014-09-16/mutex_PT_f1_n5.out | 10 + in/results/2014-09-16/mutex_PT_f1_n6.out | 10 + in/results/2014-09-16/mutex_PT_f1_n7.out | 10 + in/results/2014-09-16/mutex_PT_f1_n8.out | 10 + in/results/2014-09-16/mutex_PT_f1_n9.out | 10 + in/results/2014-09-16/mutex_PT_f2_n10.out | 10 + in/results/2014-09-16/mutex_PT_f2_n11.out | 10 + in/results/2014-09-16/mutex_PT_f2_n12.out | 10 + in/results/2014-09-16/mutex_PT_f2_n13.out | 10 + in/results/2014-09-16/mutex_PT_f2_n14.out | 10 + in/results/2014-09-16/mutex_PT_f2_n15.out | 2 + in/results/2014-09-16/mutex_PT_f2_n16.out | 2 + in/results/2014-09-16/mutex_PT_f2_n17.out | 2 + in/results/2014-09-16/mutex_PT_f2_n18.out | 2 + in/results/2014-09-16/mutex_PT_f2_n19.out | 2 + in/results/2014-09-16/mutex_PT_f2_n2.out | 10 + in/results/2014-09-16/mutex_PT_f2_n20.out | 2 + in/results/2014-09-16/mutex_PT_f2_n21.out | 2 + in/results/2014-09-16/mutex_PT_f2_n22.out | 2 + in/results/2014-09-16/mutex_PT_f2_n23.out | 2 + in/results/2014-09-16/mutex_PT_f2_n24.out | 2 + in/results/2014-09-16/mutex_PT_f2_n25.out | 2 + in/results/2014-09-16/mutex_PT_f2_n26.out | 2 + in/results/2014-09-16/mutex_PT_f2_n27.out | 2 + in/results/2014-09-16/mutex_PT_f2_n28.out | 2 + in/results/2014-09-16/mutex_PT_f2_n29.out | 2 + in/results/2014-09-16/mutex_PT_f2_n3.out | 10 + in/results/2014-09-16/mutex_PT_f2_n30.out | 2 + in/results/2014-09-16/mutex_PT_f2_n31.out | 2 + in/results/2014-09-16/mutex_PT_f2_n32.out | 2 + in/results/2014-09-16/mutex_PT_f2_n33.out | 2 + in/results/2014-09-16/mutex_PT_f2_n34.out | 2 + in/results/2014-09-16/mutex_PT_f2_n35.out | 2 + in/results/2014-09-16/mutex_PT_f2_n36.out | 2 + in/results/2014-09-16/mutex_PT_f2_n37.out | 2 + in/results/2014-09-16/mutex_PT_f2_n38.out | 2 + in/results/2014-09-16/mutex_PT_f2_n39.out | 2 + in/results/2014-09-16/mutex_PT_f2_n4.out | 10 + in/results/2014-09-16/mutex_PT_f2_n40.out | 2 + in/results/2014-09-16/mutex_PT_f2_n5.out | 10 + in/results/2014-09-16/mutex_PT_f2_n6.out | 10 + in/results/2014-09-16/mutex_PT_f2_n7.out | 10 + in/results/2014-09-16/mutex_PT_f2_n8.out | 10 + in/results/2014-09-16/mutex_PT_f2_n9.out | 10 + in/results/2014-09-16/mutex_PT_f3_n10.out | 10 + in/results/2014-09-16/mutex_PT_f3_n11.out | 2 + in/results/2014-09-16/mutex_PT_f3_n12.out | 2 + in/results/2014-09-16/mutex_PT_f3_n13.out | 2 + in/results/2014-09-16/mutex_PT_f3_n14.out | 2 + in/results/2014-09-16/mutex_PT_f3_n15.out | 2 + in/results/2014-09-16/mutex_PT_f3_n16.out | 2 + in/results/2014-09-16/mutex_PT_f3_n17.out | 2 + in/results/2014-09-16/mutex_PT_f3_n18.out | 2 + in/results/2014-09-16/mutex_PT_f3_n19.out | 2 + in/results/2014-09-16/mutex_PT_f3_n2.out | 10 + in/results/2014-09-16/mutex_PT_f3_n20.out | 2 + in/results/2014-09-16/mutex_PT_f3_n21.out | 2 + in/results/2014-09-16/mutex_PT_f3_n22.out | 2 + in/results/2014-09-16/mutex_PT_f3_n23.out | 2 + in/results/2014-09-16/mutex_PT_f3_n24.out | 2 + in/results/2014-09-16/mutex_PT_f3_n25.out | 2 + in/results/2014-09-16/mutex_PT_f3_n26.out | 2 + in/results/2014-09-16/mutex_PT_f3_n27.out | 2 + in/results/2014-09-16/mutex_PT_f3_n28.out | 2 + in/results/2014-09-16/mutex_PT_f3_n29.out | 2 + in/results/2014-09-16/mutex_PT_f3_n3.out | 10 + in/results/2014-09-16/mutex_PT_f3_n30.out | 2 + in/results/2014-09-16/mutex_PT_f3_n31.out | 2 + in/results/2014-09-16/mutex_PT_f3_n32.out | 2 + in/results/2014-09-16/mutex_PT_f3_n33.out | 2 + in/results/2014-09-16/mutex_PT_f3_n34.out | 2 + in/results/2014-09-16/mutex_PT_f3_n35.out | 2 + in/results/2014-09-16/mutex_PT_f3_n36.out | 2 + in/results/2014-09-16/mutex_PT_f3_n37.out | 2 + in/results/2014-09-16/mutex_PT_f3_n38.out | 2 + in/results/2014-09-16/mutex_PT_f3_n39.out | 2 + in/results/2014-09-16/mutex_PT_f3_n4.out | 10 + in/results/2014-09-16/mutex_PT_f3_n40.out | 2 + in/results/2014-09-16/mutex_PT_f3_n5.out | 10 + in/results/2014-09-16/mutex_PT_f3_n6.out | 10 + in/results/2014-09-16/mutex_PT_f3_n7.out | 10 + in/results/2014-09-16/mutex_PT_f3_n8.out | 10 + in/results/2014-09-16/mutex_PT_f3_n9.out | 10 + in/results/2014-09-16/mutex_f1.dat | 21 + in/results/2014-09-16/mutex_f1_pt.dat | 9 + in/results/2014-09-16/mutex_f2.dat | 21 + in/results/2014-09-16/mutex_f2_pt.dat | 13 + in/results/2014-09-16/mutex_f3.dat | 21 + in/results/2014-09-16/mutex_f3_pt.dat | 9 + .../2014-09-16/pipe_abs_MT_v1_f0_n10.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n11.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n12.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n13.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n14.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n15.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n16.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n17.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n18.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n19.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n2.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n20.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n21.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n22.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n23.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n24.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n25.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n26.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n27.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n28.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n29.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n3.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n30.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n31.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n32.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n33.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n34.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n35.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n36.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n37.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n38.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n39.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n4.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n40.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n5.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n6.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n7.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n8.out | 10 + .../2014-09-16/pipe_abs_MT_v1_f0_n9.out | 10 + .../2014-09-16/pipe_abs_MT_v2_f0_n10.out | 10 + .../2014-09-16/pipe_abs_MT_v2_f0_n11.out | 10 + .../2014-09-16/pipe_abs_MT_v2_f0_n12.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n13.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n14.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n15.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n16.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n17.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n18.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n19.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n2.out | 10 + .../2014-09-16/pipe_abs_MT_v2_f0_n20.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n21.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n22.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n23.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n24.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n25.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n26.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n27.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n28.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n29.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n3.out | 10 + .../2014-09-16/pipe_abs_MT_v2_f0_n30.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n31.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n32.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n33.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n34.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n35.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n36.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n37.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n38.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n39.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n4.out | 10 + .../2014-09-16/pipe_abs_MT_v2_f0_n40.out | 2 + .../2014-09-16/pipe_abs_MT_v2_f0_n5.out | 10 + .../2014-09-16/pipe_abs_MT_v2_f0_n6.out | 10 + .../2014-09-16/pipe_abs_MT_v2_f0_n7.out | 10 + .../2014-09-16/pipe_abs_MT_v2_f0_n8.out | 10 + .../2014-09-16/pipe_abs_MT_v2_f0_n9.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n10.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n11.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n12.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n13.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n14.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n15.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n16.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n17.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n18.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n19.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n2.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n20.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n21.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n22.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n23.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n24.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n25.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n26.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n27.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n28.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n29.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n3.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n30.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n31.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n32.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n33.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n34.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n35.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n36.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n37.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n38.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n39.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n4.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n40.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n5.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n6.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n7.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n8.out | 10 + .../2014-09-16/pipe_abs_PT_v1_f0_n9.out | 10 + .../2014-09-16/pipe_abs_PT_v2_f0_n10.out | 10 + .../2014-09-16/pipe_abs_PT_v2_f0_n11.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n12.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n13.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n14.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n15.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n16.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n17.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n18.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n19.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n2.out | 10 + .../2014-09-16/pipe_abs_PT_v2_f0_n20.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n21.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n22.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n23.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n24.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n25.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n26.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n27.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n28.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n29.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n3.out | 10 + .../2014-09-16/pipe_abs_PT_v2_f0_n30.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n31.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n32.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n33.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n34.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n35.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n36.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n37.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n38.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n39.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n4.out | 10 + .../2014-09-16/pipe_abs_PT_v2_f0_n40.out | 2 + .../2014-09-16/pipe_abs_PT_v2_f0_n5.out | 10 + .../2014-09-16/pipe_abs_PT_v2_f0_n6.out | 10 + .../2014-09-16/pipe_abs_PT_v2_f0_n7.out | 10 + .../2014-09-16/pipe_abs_PT_v2_f0_n8.out | 10 + .../2014-09-16/pipe_abs_PT_v2_f0_n9.out | 10 + in/results/2014-09-16/pipe_abs_v1_f0.dat | 39 + in/results/2014-09-16/pipe_abs_v1_f0_pt.dat | 39 + in/results/2014-09-16/pipe_abs_v2_f0.dat | 10 + in/results/2014-09-16/pipe_abs_v2_f0_pt.dat | 9 + in/results/2014-09-16/summary_bc_MT_f1 | 24 + in/results/2014-09-16/summary_bc_MT_f2 | 25 + in/results/2014-09-16/summary_bc_MT_f3 | 16 + in/results/2014-09-16/summary_bc_MT_f4 | 25 + in/results/2014-09-16/summary_bc_PT_f1 | 21 + in/results/2014-09-16/summary_bc_PT_f2 | 22 + in/results/2014-09-16/summary_bc_PT_f3 | 16 + in/results/2014-09-16/summary_bc_PT_f4 | 22 + in/results/2014-09-16/summary_mutex_MT_f1 | 21 + in/results/2014-09-16/summary_mutex_MT_f2 | 21 + in/results/2014-09-16/summary_mutex_MT_f3 | 21 + in/results/2014-09-16/summary_mutex_PT_f1 | 9 + in/results/2014-09-16/summary_mutex_PT_f2 | 13 + in/results/2014-09-16/summary_mutex_PT_f3 | 9 + .../2014-09-16/summary_pipe_abs_MT_v1_f0 | 39 + .../2014-09-16/summary_pipe_abs_MT_v2_f0 | 10 + .../2014-09-16/summary_pipe_abs_PT_v1_f0 | 39 + .../2014-09-16/summary_pipe_abs_PT_v2_f0 | 9 + .../2014-09-25_noreorder/bc_MT_f1_n1.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n10.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n11.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n12.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n13.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n14.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n15.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n16.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n17.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n18.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n19.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n2.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n20.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n21.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n22.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n23.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n24.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n25.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n3.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n4.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n5.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n6.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n7.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n8.out | 10 + .../2014-09-25_noreorder/bc_MT_f1_n9.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n1.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n10.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n11.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n12.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n13.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n14.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n15.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n16.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n17.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n18.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n19.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n2.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n20.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n21.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n22.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n23.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n24.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n25.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n3.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n4.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n5.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n6.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n7.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n8.out | 10 + .../2014-09-25_noreorder/bc_MT_f2_n9.out | 10 + .../2014-09-25_noreorder/bc_MT_f3_n10.out | 10 + .../2014-09-25_noreorder/bc_MT_f3_n11.out | 10 + .../2014-09-25_noreorder/bc_MT_f3_n12.out | 10 + .../2014-09-25_noreorder/bc_MT_f3_n13.out | 10 + .../2014-09-25_noreorder/bc_MT_f3_n14.out | 10 + .../2014-09-25_noreorder/bc_MT_f3_n15.out | 10 + .../2014-09-25_noreorder/bc_MT_f3_n16.out | 10 + .../2014-09-25_noreorder/bc_MT_f3_n17.out | 10 + .../2014-09-25_noreorder/bc_MT_f3_n18.out | 10 + .../2014-09-25_noreorder/bc_MT_f3_n19.out | 10 + .../2014-09-25_noreorder/bc_MT_f3_n20.out | 10 + .../2014-09-25_noreorder/bc_MT_f3_n21.out | 10 + .../2014-09-25_noreorder/bc_MT_f3_n22.out | 10 + .../2014-09-25_noreorder/bc_MT_f3_n23.out | 10 + .../2014-09-25_noreorder/bc_MT_f3_n24.out | 10 + .../2014-09-25_noreorder/bc_MT_f3_n25.out | 10 + .../2014-09-25_noreorder/bc_MT_f3_n9.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n1.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n10.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n11.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n12.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n13.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n14.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n15.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n16.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n17.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n18.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n19.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n2.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n20.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n21.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n22.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n23.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n24.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n25.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n3.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n4.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n5.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n6.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n7.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n8.out | 10 + .../2014-09-25_noreorder/bc_MT_f4_n9.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n1.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n10.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n11.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n12.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n13.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n14.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n15.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n16.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n17.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n18.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n19.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n2.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n20.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n21.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n22.out | 2 + .../2014-09-25_noreorder/bc_PT_f1_n3.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n4.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n5.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n6.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n7.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n8.out | 10 + .../2014-09-25_noreorder/bc_PT_f1_n9.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n1.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n10.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n11.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n12.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n13.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n14.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n15.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n16.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n17.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n18.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n19.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n2.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n20.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n21.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n22.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n23.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n24.out | 2 + .../2014-09-25_noreorder/bc_PT_f2_n3.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n4.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n5.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n6.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n7.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n8.out | 10 + .../2014-09-25_noreorder/bc_PT_f2_n9.out | 10 + .../2014-09-25_noreorder/bc_PT_f3_n10.out | 10 + .../2014-09-25_noreorder/bc_PT_f3_n11.out | 10 + .../2014-09-25_noreorder/bc_PT_f3_n12.out | 10 + .../2014-09-25_noreorder/bc_PT_f3_n13.out | 10 + .../2014-09-25_noreorder/bc_PT_f3_n14.out | 10 + .../2014-09-25_noreorder/bc_PT_f3_n15.out | 10 + .../2014-09-25_noreorder/bc_PT_f3_n16.out | 10 + .../2014-09-25_noreorder/bc_PT_f3_n17.out | 10 + .../2014-09-25_noreorder/bc_PT_f3_n18.out | 10 + .../2014-09-25_noreorder/bc_PT_f3_n19.out | 10 + .../2014-09-25_noreorder/bc_PT_f3_n20.out | 10 + .../2014-09-25_noreorder/bc_PT_f3_n21.out | 10 + .../2014-09-25_noreorder/bc_PT_f3_n22.out | 10 + .../2014-09-25_noreorder/bc_PT_f3_n23.out | 10 + .../2014-09-25_noreorder/bc_PT_f3_n24.out | 10 + .../2014-09-25_noreorder/bc_PT_f3_n25.out | 10 + .../2014-09-25_noreorder/bc_PT_f3_n9.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n1.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n10.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n11.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n12.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n13.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n14.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n15.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n16.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n17.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n18.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n19.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n2.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n20.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n21.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n22.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n23.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n24.out | 2 + .../2014-09-25_noreorder/bc_PT_f4_n3.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n4.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n5.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n6.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n7.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n8.out | 10 + .../2014-09-25_noreorder/bc_PT_f4_n9.out | 10 + in/results/2014-09-25_noreorder/bc_f1.dat | 25 + in/results/2014-09-25_noreorder/bc_f1_pt.dat | 21 + in/results/2014-09-25_noreorder/bc_f2.dat | 25 + in/results/2014-09-25_noreorder/bc_f2_pt.dat | 23 + in/results/2014-09-25_noreorder/bc_f3.dat | 17 + in/results/2014-09-25_noreorder/bc_f3_pt.dat | 17 + in/results/2014-09-25_noreorder/bc_f4.dat | 25 + in/results/2014-09-25_noreorder/bc_f4_pt.dat | 23 + .../2014-09-25_noreorder/mutex_MT_f1_n10.out | 10 + .../2014-09-25_noreorder/mutex_MT_f1_n11.out | 10 + .../2014-09-25_noreorder/mutex_MT_f1_n12.out | 2 + .../2014-09-25_noreorder/mutex_MT_f1_n2.out | 10 + .../2014-09-25_noreorder/mutex_MT_f1_n3.out | 10 + .../2014-09-25_noreorder/mutex_MT_f1_n4.out | 10 + .../2014-09-25_noreorder/mutex_MT_f1_n5.out | 10 + .../2014-09-25_noreorder/mutex_MT_f1_n6.out | 10 + .../2014-09-25_noreorder/mutex_MT_f1_n7.out | 10 + .../2014-09-25_noreorder/mutex_MT_f1_n8.out | 10 + .../2014-09-25_noreorder/mutex_MT_f1_n9.out | 10 + .../2014-09-25_noreorder/mutex_MT_f2_n10.out | 10 + .../2014-09-25_noreorder/mutex_MT_f2_n11.out | 10 + .../2014-09-25_noreorder/mutex_MT_f2_n12.out | 2 + .../2014-09-25_noreorder/mutex_MT_f2_n2.out | 10 + .../2014-09-25_noreorder/mutex_MT_f2_n3.out | 10 + .../2014-09-25_noreorder/mutex_MT_f2_n4.out | 10 + .../2014-09-25_noreorder/mutex_MT_f2_n5.out | 10 + .../2014-09-25_noreorder/mutex_MT_f2_n6.out | 10 + .../2014-09-25_noreorder/mutex_MT_f2_n7.out | 10 + .../2014-09-25_noreorder/mutex_MT_f2_n8.out | 10 + .../2014-09-25_noreorder/mutex_MT_f2_n9.out | 10 + .../2014-09-25_noreorder/mutex_MT_f3_n10.out | 10 + .../2014-09-25_noreorder/mutex_MT_f3_n11.out | 10 + .../2014-09-25_noreorder/mutex_MT_f3_n12.out | 2 + .../2014-09-25_noreorder/mutex_MT_f3_n2.out | 10 + .../2014-09-25_noreorder/mutex_MT_f3_n3.out | 10 + .../2014-09-25_noreorder/mutex_MT_f3_n4.out | 10 + .../2014-09-25_noreorder/mutex_MT_f3_n5.out | 10 + .../2014-09-25_noreorder/mutex_MT_f3_n6.out | 10 + .../2014-09-25_noreorder/mutex_MT_f3_n7.out | 10 + .../2014-09-25_noreorder/mutex_MT_f3_n8.out | 10 + .../2014-09-25_noreorder/mutex_MT_f3_n9.out | 10 + .../2014-09-25_noreorder/mutex_PT_f1_n10.out | 10 + .../2014-09-25_noreorder/mutex_PT_f1_n11.out | 10 + .../2014-09-25_noreorder/mutex_PT_f1_n12.out | 10 + .../2014-09-25_noreorder/mutex_PT_f1_n13.out | 2 + .../2014-09-25_noreorder/mutex_PT_f1_n2.out | 10 + .../2014-09-25_noreorder/mutex_PT_f1_n3.out | 10 + .../2014-09-25_noreorder/mutex_PT_f1_n4.out | 10 + .../2014-09-25_noreorder/mutex_PT_f1_n5.out | 10 + .../2014-09-25_noreorder/mutex_PT_f1_n6.out | 10 + .../2014-09-25_noreorder/mutex_PT_f1_n7.out | 10 + .../2014-09-25_noreorder/mutex_PT_f1_n8.out | 10 + .../2014-09-25_noreorder/mutex_PT_f1_n9.out | 10 + .../2014-09-25_noreorder/mutex_PT_f2_n10.out | 10 + .../2014-09-25_noreorder/mutex_PT_f2_n11.out | 10 + .../2014-09-25_noreorder/mutex_PT_f2_n12.out | 10 + .../2014-09-25_noreorder/mutex_PT_f2_n13.out | 10 + .../2014-09-25_noreorder/mutex_PT_f2_n14.out | 2 + .../2014-09-25_noreorder/mutex_PT_f2_n2.out | 10 + .../2014-09-25_noreorder/mutex_PT_f2_n3.out | 10 + .../2014-09-25_noreorder/mutex_PT_f2_n4.out | 10 + .../2014-09-25_noreorder/mutex_PT_f2_n5.out | 10 + .../2014-09-25_noreorder/mutex_PT_f2_n6.out | 10 + .../2014-09-25_noreorder/mutex_PT_f2_n7.out | 10 + .../2014-09-25_noreorder/mutex_PT_f2_n8.out | 10 + .../2014-09-25_noreorder/mutex_PT_f2_n9.out | 10 + .../2014-09-25_noreorder/mutex_PT_f3_n10.out | 10 + .../2014-09-25_noreorder/mutex_PT_f3_n11.out | 10 + .../2014-09-25_noreorder/mutex_PT_f3_n12.out | 10 + .../2014-09-25_noreorder/mutex_PT_f3_n13.out | 2 + .../2014-09-25_noreorder/mutex_PT_f3_n2.out | 10 + .../2014-09-25_noreorder/mutex_PT_f3_n3.out | 10 + .../2014-09-25_noreorder/mutex_PT_f3_n4.out | 10 + .../2014-09-25_noreorder/mutex_PT_f3_n5.out | 10 + .../2014-09-25_noreorder/mutex_PT_f3_n6.out | 10 + .../2014-09-25_noreorder/mutex_PT_f3_n7.out | 10 + .../2014-09-25_noreorder/mutex_PT_f3_n8.out | 10 + .../2014-09-25_noreorder/mutex_PT_f3_n9.out | 10 + in/results/2014-09-25_noreorder/mutex_f1.dat | 10 + .../2014-09-25_noreorder/mutex_f1_pt.dat | 11 + in/results/2014-09-25_noreorder/mutex_f2.dat | 10 + .../2014-09-25_noreorder/mutex_f2_pt.dat | 12 + in/results/2014-09-25_noreorder/mutex_f3.dat | 10 + .../2014-09-25_noreorder/mutex_f3_pt.dat | 11 + .../pipe_abs_MT_v1_f0_n10.out | 10 + .../pipe_abs_MT_v1_f0_n11.out | 10 + .../pipe_abs_MT_v1_f0_n12.out | 10 + .../pipe_abs_MT_v1_f0_n13.out | 10 + .../pipe_abs_MT_v1_f0_n14.out | 10 + .../pipe_abs_MT_v1_f0_n15.out | 10 + .../pipe_abs_MT_v1_f0_n16.out | 10 + .../pipe_abs_MT_v1_f0_n17.out | 10 + .../pipe_abs_MT_v1_f0_n18.out | 10 + .../pipe_abs_MT_v1_f0_n19.out | 10 + .../pipe_abs_MT_v1_f0_n2.out | 10 + .../pipe_abs_MT_v1_f0_n20.out | 10 + .../pipe_abs_MT_v1_f0_n21.out | 10 + .../pipe_abs_MT_v1_f0_n22.out | 10 + .../pipe_abs_MT_v1_f0_n23.out | 10 + .../pipe_abs_MT_v1_f0_n24.out | 10 + .../pipe_abs_MT_v1_f0_n25.out | 10 + .../pipe_abs_MT_v1_f0_n26.out | 10 + .../pipe_abs_MT_v1_f0_n27.out | 10 + .../pipe_abs_MT_v1_f0_n28.out | 10 + .../pipe_abs_MT_v1_f0_n29.out | 10 + .../pipe_abs_MT_v1_f0_n3.out | 10 + .../pipe_abs_MT_v1_f0_n30.out | 10 + .../pipe_abs_MT_v1_f0_n31.out | 10 + .../pipe_abs_MT_v1_f0_n32.out | 10 + .../pipe_abs_MT_v1_f0_n33.out | 10 + .../pipe_abs_MT_v1_f0_n34.out | 10 + .../pipe_abs_MT_v1_f0_n35.out | 10 + .../pipe_abs_MT_v1_f0_n36.out | 10 + .../pipe_abs_MT_v1_f0_n37.out | 10 + .../pipe_abs_MT_v1_f0_n38.out | 10 + .../pipe_abs_MT_v1_f0_n39.out | 10 + .../pipe_abs_MT_v1_f0_n4.out | 10 + .../pipe_abs_MT_v1_f0_n40.out | 10 + .../pipe_abs_MT_v1_f0_n5.out | 10 + .../pipe_abs_MT_v1_f0_n6.out | 10 + .../pipe_abs_MT_v1_f0_n7.out | 10 + .../pipe_abs_MT_v1_f0_n8.out | 10 + .../pipe_abs_MT_v1_f0_n9.out | 10 + .../pipe_abs_MT_v2_f0_n10.out | 10 + .../pipe_abs_MT_v2_f0_n11.out | 10 + .../pipe_abs_MT_v2_f0_n12.out | 2 + .../pipe_abs_MT_v2_f0_n2.out | 10 + .../pipe_abs_MT_v2_f0_n3.out | 10 + .../pipe_abs_MT_v2_f0_n4.out | 10 + .../pipe_abs_MT_v2_f0_n5.out | 10 + .../pipe_abs_MT_v2_f0_n6.out | 10 + .../pipe_abs_MT_v2_f0_n7.out | 10 + .../pipe_abs_MT_v2_f0_n8.out | 10 + .../pipe_abs_MT_v2_f0_n9.out | 10 + .../pipe_abs_PT_v1_f0_n10.out | 10 + .../pipe_abs_PT_v1_f0_n11.out | 10 + .../pipe_abs_PT_v1_f0_n12.out | 10 + .../pipe_abs_PT_v1_f0_n13.out | 10 + .../pipe_abs_PT_v1_f0_n14.out | 10 + .../pipe_abs_PT_v1_f0_n15.out | 10 + .../pipe_abs_PT_v1_f0_n16.out | 10 + .../pipe_abs_PT_v1_f0_n17.out | 10 + .../pipe_abs_PT_v1_f0_n18.out | 10 + .../pipe_abs_PT_v1_f0_n19.out | 10 + .../pipe_abs_PT_v1_f0_n2.out | 10 + .../pipe_abs_PT_v1_f0_n20.out | 10 + .../pipe_abs_PT_v1_f0_n21.out | 10 + .../pipe_abs_PT_v1_f0_n22.out | 10 + .../pipe_abs_PT_v1_f0_n23.out | 10 + .../pipe_abs_PT_v1_f0_n24.out | 10 + .../pipe_abs_PT_v1_f0_n25.out | 10 + .../pipe_abs_PT_v1_f0_n26.out | 10 + .../pipe_abs_PT_v1_f0_n27.out | 10 + .../pipe_abs_PT_v1_f0_n28.out | 10 + .../pipe_abs_PT_v1_f0_n29.out | 10 + .../pipe_abs_PT_v1_f0_n3.out | 10 + .../pipe_abs_PT_v1_f0_n30.out | 10 + .../pipe_abs_PT_v1_f0_n31.out | 10 + .../pipe_abs_PT_v1_f0_n32.out | 10 + .../pipe_abs_PT_v1_f0_n33.out | 10 + .../pipe_abs_PT_v1_f0_n34.out | 10 + .../pipe_abs_PT_v1_f0_n35.out | 10 + .../pipe_abs_PT_v1_f0_n36.out | 10 + .../pipe_abs_PT_v1_f0_n37.out | 10 + .../pipe_abs_PT_v1_f0_n38.out | 10 + .../pipe_abs_PT_v1_f0_n39.out | 10 + .../pipe_abs_PT_v1_f0_n4.out | 10 + .../pipe_abs_PT_v1_f0_n40.out | 10 + .../pipe_abs_PT_v1_f0_n5.out | 10 + .../pipe_abs_PT_v1_f0_n6.out | 10 + .../pipe_abs_PT_v1_f0_n7.out | 10 + .../pipe_abs_PT_v1_f0_n8.out | 10 + .../pipe_abs_PT_v1_f0_n9.out | 10 + .../pipe_abs_PT_v2_f0_n10.out | 10 + .../pipe_abs_PT_v2_f0_n11.out | 10 + .../pipe_abs_PT_v2_f0_n12.out | 2 + .../pipe_abs_PT_v2_f0_n2.out | 10 + .../pipe_abs_PT_v2_f0_n3.out | 10 + .../pipe_abs_PT_v2_f0_n4.out | 10 + .../pipe_abs_PT_v2_f0_n5.out | 10 + .../pipe_abs_PT_v2_f0_n6.out | 10 + .../pipe_abs_PT_v2_f0_n7.out | 10 + .../pipe_abs_PT_v2_f0_n8.out | 10 + .../pipe_abs_PT_v2_f0_n9.out | 10 + .../2014-09-25_noreorder/pipe_abs_v1_f0.dat | 39 + .../pipe_abs_v1_f0_pt.dat | 39 + .../2014-09-25_noreorder/pipe_abs_v2_f0.dat | 10 + .../pipe_abs_v2_f0_pt.dat | 10 + .../2014-09-25_noreorder/summary_bc_MT_f1 | 25 + .../2014-09-25_noreorder/summary_bc_MT_f2 | 25 + .../2014-09-25_noreorder/summary_bc_MT_f3 | 17 + .../2014-09-25_noreorder/summary_bc_MT_f4 | 25 + .../2014-09-25_noreorder/summary_bc_PT_f1 | 21 + .../2014-09-25_noreorder/summary_bc_PT_f2 | 23 + .../2014-09-25_noreorder/summary_bc_PT_f3 | 17 + .../2014-09-25_noreorder/summary_bc_PT_f4 | 23 + .../2014-09-25_noreorder/summary_mutex_MT_f1 | 10 + .../2014-09-25_noreorder/summary_mutex_MT_f2 | 10 + .../2014-09-25_noreorder/summary_mutex_MT_f3 | 10 + .../2014-09-25_noreorder/summary_mutex_PT_f1 | 11 + .../2014-09-25_noreorder/summary_mutex_PT_f2 | 12 + .../2014-09-25_noreorder/summary_mutex_PT_f3 | 11 + .../summary_pipe_abs_MT_v1_f0 | 39 + .../summary_pipe_abs_MT_v2_f0 | 10 + .../summary_pipe_abs_PT_v1_f0 | 39 + .../summary_pipe_abs_PT_v2_f0 | 10 + in/results/2014-09-25_reorder/bc_MT_f1_n1.out | 10 + .../2014-09-25_reorder/bc_MT_f1_n10.out | 10 + .../2014-09-25_reorder/bc_MT_f1_n11.out | 10 + .../2014-09-25_reorder/bc_MT_f1_n12.out | 10 + .../2014-09-25_reorder/bc_MT_f1_n13.out | 10 + .../2014-09-25_reorder/bc_MT_f1_n14.out | 10 + .../2014-09-25_reorder/bc_MT_f1_n15.out | 10 + .../2014-09-25_reorder/bc_MT_f1_n16.out | 10 + .../2014-09-25_reorder/bc_MT_f1_n17.out | 10 + .../2014-09-25_reorder/bc_MT_f1_n18.out | 10 + .../2014-09-25_reorder/bc_MT_f1_n19.out | 10 + in/results/2014-09-25_reorder/bc_MT_f1_n2.out | 10 + .../2014-09-25_reorder/bc_MT_f1_n20.out | 10 + .../2014-09-25_reorder/bc_MT_f1_n21.out | 10 + .../2014-09-25_reorder/bc_MT_f1_n22.out | 10 + .../2014-09-25_reorder/bc_MT_f1_n23.out | 10 + .../2014-09-25_reorder/bc_MT_f1_n24.out | 10 + .../2014-09-25_reorder/bc_MT_f1_n25.out | 10 + in/results/2014-09-25_reorder/bc_MT_f1_n3.out | 10 + in/results/2014-09-25_reorder/bc_MT_f1_n4.out | 10 + in/results/2014-09-25_reorder/bc_MT_f1_n5.out | 10 + in/results/2014-09-25_reorder/bc_MT_f1_n6.out | 10 + in/results/2014-09-25_reorder/bc_MT_f1_n7.out | 10 + in/results/2014-09-25_reorder/bc_MT_f1_n8.out | 10 + in/results/2014-09-25_reorder/bc_MT_f1_n9.out | 10 + in/results/2014-09-25_reorder/bc_MT_f2_n1.out | 10 + .../2014-09-25_reorder/bc_MT_f2_n10.out | 10 + .../2014-09-25_reorder/bc_MT_f2_n11.out | 10 + .../2014-09-25_reorder/bc_MT_f2_n12.out | 10 + .../2014-09-25_reorder/bc_MT_f2_n13.out | 10 + .../2014-09-25_reorder/bc_MT_f2_n14.out | 10 + .../2014-09-25_reorder/bc_MT_f2_n15.out | 10 + .../2014-09-25_reorder/bc_MT_f2_n16.out | 10 + .../2014-09-25_reorder/bc_MT_f2_n17.out | 10 + .../2014-09-25_reorder/bc_MT_f2_n18.out | 10 + .../2014-09-25_reorder/bc_MT_f2_n19.out | 10 + in/results/2014-09-25_reorder/bc_MT_f2_n2.out | 10 + .../2014-09-25_reorder/bc_MT_f2_n20.out | 10 + .../2014-09-25_reorder/bc_MT_f2_n21.out | 10 + .../2014-09-25_reorder/bc_MT_f2_n22.out | 10 + .../2014-09-25_reorder/bc_MT_f2_n23.out | 10 + .../2014-09-25_reorder/bc_MT_f2_n24.out | 10 + .../2014-09-25_reorder/bc_MT_f2_n25.out | 10 + in/results/2014-09-25_reorder/bc_MT_f2_n3.out | 10 + in/results/2014-09-25_reorder/bc_MT_f2_n4.out | 10 + in/results/2014-09-25_reorder/bc_MT_f2_n5.out | 10 + in/results/2014-09-25_reorder/bc_MT_f2_n6.out | 10 + in/results/2014-09-25_reorder/bc_MT_f2_n7.out | 10 + in/results/2014-09-25_reorder/bc_MT_f2_n8.out | 10 + in/results/2014-09-25_reorder/bc_MT_f2_n9.out | 10 + .../2014-09-25_reorder/bc_MT_f3_n10.out | 10 + .../2014-09-25_reorder/bc_MT_f3_n11.out | 10 + .../2014-09-25_reorder/bc_MT_f3_n12.out | 10 + .../2014-09-25_reorder/bc_MT_f3_n13.out | 10 + .../2014-09-25_reorder/bc_MT_f3_n14.out | 10 + .../2014-09-25_reorder/bc_MT_f3_n15.out | 10 + .../2014-09-25_reorder/bc_MT_f3_n16.out | 10 + .../2014-09-25_reorder/bc_MT_f3_n17.out | 10 + .../2014-09-25_reorder/bc_MT_f3_n18.out | 10 + .../2014-09-25_reorder/bc_MT_f3_n19.out | 10 + .../2014-09-25_reorder/bc_MT_f3_n20.out | 10 + .../2014-09-25_reorder/bc_MT_f3_n21.out | 10 + .../2014-09-25_reorder/bc_MT_f3_n22.out | 10 + .../2014-09-25_reorder/bc_MT_f3_n23.out | 10 + .../2014-09-25_reorder/bc_MT_f3_n24.out | 10 + .../2014-09-25_reorder/bc_MT_f3_n25.out | 10 + in/results/2014-09-25_reorder/bc_MT_f3_n9.out | 10 + in/results/2014-09-25_reorder/bc_MT_f4_n1.out | 10 + .../2014-09-25_reorder/bc_MT_f4_n10.out | 10 + .../2014-09-25_reorder/bc_MT_f4_n11.out | 10 + .../2014-09-25_reorder/bc_MT_f4_n12.out | 10 + .../2014-09-25_reorder/bc_MT_f4_n13.out | 10 + .../2014-09-25_reorder/bc_MT_f4_n14.out | 10 + .../2014-09-25_reorder/bc_MT_f4_n15.out | 10 + .../2014-09-25_reorder/bc_MT_f4_n16.out | 10 + .../2014-09-25_reorder/bc_MT_f4_n17.out | 10 + .../2014-09-25_reorder/bc_MT_f4_n18.out | 10 + .../2014-09-25_reorder/bc_MT_f4_n19.out | 10 + in/results/2014-09-25_reorder/bc_MT_f4_n2.out | 10 + .../2014-09-25_reorder/bc_MT_f4_n20.out | 10 + .../2014-09-25_reorder/bc_MT_f4_n21.out | 10 + .../2014-09-25_reorder/bc_MT_f4_n22.out | 10 + .../2014-09-25_reorder/bc_MT_f4_n23.out | 10 + .../2014-09-25_reorder/bc_MT_f4_n24.out | 10 + .../2014-09-25_reorder/bc_MT_f4_n25.out | 10 + in/results/2014-09-25_reorder/bc_MT_f4_n3.out | 10 + in/results/2014-09-25_reorder/bc_MT_f4_n4.out | 10 + in/results/2014-09-25_reorder/bc_MT_f4_n5.out | 10 + in/results/2014-09-25_reorder/bc_MT_f4_n6.out | 10 + in/results/2014-09-25_reorder/bc_MT_f4_n7.out | 10 + in/results/2014-09-25_reorder/bc_MT_f4_n8.out | 10 + in/results/2014-09-25_reorder/bc_MT_f4_n9.out | 10 + in/results/2014-09-25_reorder/bc_PT_f1_n1.out | 10 + .../2014-09-25_reorder/bc_PT_f1_n10.out | 10 + .../2014-09-25_reorder/bc_PT_f1_n11.out | 10 + .../2014-09-25_reorder/bc_PT_f1_n12.out | 10 + .../2014-09-25_reorder/bc_PT_f1_n13.out | 10 + .../2014-09-25_reorder/bc_PT_f1_n14.out | 10 + .../2014-09-25_reorder/bc_PT_f1_n15.out | 10 + .../2014-09-25_reorder/bc_PT_f1_n16.out | 10 + .../2014-09-25_reorder/bc_PT_f1_n17.out | 10 + .../2014-09-25_reorder/bc_PT_f1_n18.out | 10 + .../2014-09-25_reorder/bc_PT_f1_n19.out | 10 + in/results/2014-09-25_reorder/bc_PT_f1_n2.out | 10 + .../2014-09-25_reorder/bc_PT_f1_n20.out | 10 + .../2014-09-25_reorder/bc_PT_f1_n21.out | 10 + .../2014-09-25_reorder/bc_PT_f1_n22.out | 2 + in/results/2014-09-25_reorder/bc_PT_f1_n3.out | 10 + in/results/2014-09-25_reorder/bc_PT_f1_n4.out | 10 + in/results/2014-09-25_reorder/bc_PT_f1_n5.out | 10 + in/results/2014-09-25_reorder/bc_PT_f1_n6.out | 10 + in/results/2014-09-25_reorder/bc_PT_f1_n7.out | 10 + in/results/2014-09-25_reorder/bc_PT_f1_n8.out | 10 + in/results/2014-09-25_reorder/bc_PT_f1_n9.out | 10 + in/results/2014-09-25_reorder/bc_PT_f2_n1.out | 10 + .../2014-09-25_reorder/bc_PT_f2_n10.out | 10 + .../2014-09-25_reorder/bc_PT_f2_n11.out | 10 + .../2014-09-25_reorder/bc_PT_f2_n12.out | 10 + .../2014-09-25_reorder/bc_PT_f2_n13.out | 10 + .../2014-09-25_reorder/bc_PT_f2_n14.out | 10 + .../2014-09-25_reorder/bc_PT_f2_n15.out | 10 + .../2014-09-25_reorder/bc_PT_f2_n16.out | 10 + .../2014-09-25_reorder/bc_PT_f2_n17.out | 10 + .../2014-09-25_reorder/bc_PT_f2_n18.out | 10 + .../2014-09-25_reorder/bc_PT_f2_n19.out | 10 + in/results/2014-09-25_reorder/bc_PT_f2_n2.out | 10 + .../2014-09-25_reorder/bc_PT_f2_n20.out | 10 + .../2014-09-25_reorder/bc_PT_f2_n21.out | 10 + .../2014-09-25_reorder/bc_PT_f2_n22.out | 10 + .../2014-09-25_reorder/bc_PT_f2_n23.out | 10 + .../2014-09-25_reorder/bc_PT_f2_n24.out | 2 + in/results/2014-09-25_reorder/bc_PT_f2_n3.out | 10 + in/results/2014-09-25_reorder/bc_PT_f2_n4.out | 10 + in/results/2014-09-25_reorder/bc_PT_f2_n5.out | 10 + in/results/2014-09-25_reorder/bc_PT_f2_n6.out | 10 + in/results/2014-09-25_reorder/bc_PT_f2_n7.out | 10 + in/results/2014-09-25_reorder/bc_PT_f2_n8.out | 10 + in/results/2014-09-25_reorder/bc_PT_f2_n9.out | 10 + .../2014-09-25_reorder/bc_PT_f3_n10.out | 10 + .../2014-09-25_reorder/bc_PT_f3_n11.out | 10 + .../2014-09-25_reorder/bc_PT_f3_n12.out | 10 + .../2014-09-25_reorder/bc_PT_f3_n13.out | 10 + .../2014-09-25_reorder/bc_PT_f3_n14.out | 10 + .../2014-09-25_reorder/bc_PT_f3_n15.out | 10 + .../2014-09-25_reorder/bc_PT_f3_n16.out | 10 + .../2014-09-25_reorder/bc_PT_f3_n17.out | 10 + .../2014-09-25_reorder/bc_PT_f3_n18.out | 10 + .../2014-09-25_reorder/bc_PT_f3_n19.out | 10 + .../2014-09-25_reorder/bc_PT_f3_n20.out | 10 + .../2014-09-25_reorder/bc_PT_f3_n21.out | 10 + .../2014-09-25_reorder/bc_PT_f3_n22.out | 10 + .../2014-09-25_reorder/bc_PT_f3_n23.out | 10 + .../2014-09-25_reorder/bc_PT_f3_n24.out | 10 + .../2014-09-25_reorder/bc_PT_f3_n25.out | 10 + in/results/2014-09-25_reorder/bc_PT_f3_n9.out | 10 + in/results/2014-09-25_reorder/bc_PT_f4_n1.out | 10 + .../2014-09-25_reorder/bc_PT_f4_n10.out | 10 + .../2014-09-25_reorder/bc_PT_f4_n11.out | 10 + .../2014-09-25_reorder/bc_PT_f4_n12.out | 10 + .../2014-09-25_reorder/bc_PT_f4_n13.out | 10 + .../2014-09-25_reorder/bc_PT_f4_n14.out | 10 + .../2014-09-25_reorder/bc_PT_f4_n15.out | 10 + .../2014-09-25_reorder/bc_PT_f4_n16.out | 10 + .../2014-09-25_reorder/bc_PT_f4_n17.out | 10 + .../2014-09-25_reorder/bc_PT_f4_n18.out | 10 + .../2014-09-25_reorder/bc_PT_f4_n19.out | 10 + in/results/2014-09-25_reorder/bc_PT_f4_n2.out | 10 + .../2014-09-25_reorder/bc_PT_f4_n20.out | 10 + .../2014-09-25_reorder/bc_PT_f4_n21.out | 10 + .../2014-09-25_reorder/bc_PT_f4_n22.out | 10 + .../2014-09-25_reorder/bc_PT_f4_n23.out | 10 + .../2014-09-25_reorder/bc_PT_f4_n24.out | 2 + in/results/2014-09-25_reorder/bc_PT_f4_n3.out | 10 + in/results/2014-09-25_reorder/bc_PT_f4_n4.out | 10 + in/results/2014-09-25_reorder/bc_PT_f4_n5.out | 10 + in/results/2014-09-25_reorder/bc_PT_f4_n6.out | 10 + in/results/2014-09-25_reorder/bc_PT_f4_n7.out | 10 + in/results/2014-09-25_reorder/bc_PT_f4_n8.out | 10 + in/results/2014-09-25_reorder/bc_PT_f4_n9.out | 10 + in/results/2014-09-25_reorder/bc_f1.dat | 25 + in/results/2014-09-25_reorder/bc_f1_pt.dat | 21 + in/results/2014-09-25_reorder/bc_f2.dat | 25 + in/results/2014-09-25_reorder/bc_f2_pt.dat | 23 + in/results/2014-09-25_reorder/bc_f3.dat | 17 + in/results/2014-09-25_reorder/bc_f3_pt.dat | 17 + in/results/2014-09-25_reorder/bc_f4.dat | 25 + in/results/2014-09-25_reorder/bc_f4_pt.dat | 23 + .../2014-09-25_reorder/mutex_MT_f1_n10.out | 10 + .../2014-09-25_reorder/mutex_MT_f1_n11.out | 10 + .../2014-09-25_reorder/mutex_MT_f1_n12.out | 10 + .../2014-09-25_reorder/mutex_MT_f1_n13.out | 10 + .../2014-09-25_reorder/mutex_MT_f1_n14.out | 10 + .../2014-09-25_reorder/mutex_MT_f1_n15.out | 10 + .../2014-09-25_reorder/mutex_MT_f1_n16.out | 10 + .../2014-09-25_reorder/mutex_MT_f1_n17.out | 10 + .../2014-09-25_reorder/mutex_MT_f1_n18.out | 10 + .../2014-09-25_reorder/mutex_MT_f1_n19.out | 10 + .../2014-09-25_reorder/mutex_MT_f1_n2.out | 10 + .../2014-09-25_reorder/mutex_MT_f1_n20.out | 10 + .../2014-09-25_reorder/mutex_MT_f1_n21.out | 10 + .../2014-09-25_reorder/mutex_MT_f1_n22.out | 10 + .../2014-09-25_reorder/mutex_MT_f1_n23.out | 2 + .../2014-09-25_reorder/mutex_MT_f1_n3.out | 10 + .../2014-09-25_reorder/mutex_MT_f1_n4.out | 10 + .../2014-09-25_reorder/mutex_MT_f1_n5.out | 10 + .../2014-09-25_reorder/mutex_MT_f1_n6.out | 10 + .../2014-09-25_reorder/mutex_MT_f1_n7.out | 10 + .../2014-09-25_reorder/mutex_MT_f1_n8.out | 10 + .../2014-09-25_reorder/mutex_MT_f1_n9.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n10.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n11.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n12.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n13.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n14.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n15.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n16.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n17.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n18.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n19.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n2.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n20.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n21.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n22.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n23.out | 2 + .../2014-09-25_reorder/mutex_MT_f2_n3.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n4.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n5.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n6.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n7.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n8.out | 10 + .../2014-09-25_reorder/mutex_MT_f2_n9.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n10.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n11.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n12.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n13.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n14.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n15.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n16.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n17.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n18.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n19.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n2.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n20.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n21.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n22.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n23.out | 2 + .../2014-09-25_reorder/mutex_MT_f3_n3.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n4.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n5.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n6.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n7.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n8.out | 10 + .../2014-09-25_reorder/mutex_MT_f3_n9.out | 10 + .../2014-09-25_reorder/mutex_PT_f1_n10.out | 10 + .../2014-09-25_reorder/mutex_PT_f1_n11.out | 10 + .../2014-09-25_reorder/mutex_PT_f1_n12.out | 2 + .../2014-09-25_reorder/mutex_PT_f1_n2.out | 10 + .../2014-09-25_reorder/mutex_PT_f1_n3.out | 10 + .../2014-09-25_reorder/mutex_PT_f1_n4.out | 10 + .../2014-09-25_reorder/mutex_PT_f1_n5.out | 10 + .../2014-09-25_reorder/mutex_PT_f1_n6.out | 10 + .../2014-09-25_reorder/mutex_PT_f1_n7.out | 10 + .../2014-09-25_reorder/mutex_PT_f1_n8.out | 10 + .../2014-09-25_reorder/mutex_PT_f1_n9.out | 10 + .../2014-09-25_reorder/mutex_PT_f2_n10.out | 10 + .../2014-09-25_reorder/mutex_PT_f2_n11.out | 10 + .../2014-09-25_reorder/mutex_PT_f2_n12.out | 10 + .../2014-09-25_reorder/mutex_PT_f2_n13.out | 10 + .../2014-09-25_reorder/mutex_PT_f2_n14.out | 10 + .../2014-09-25_reorder/mutex_PT_f2_n15.out | 10 + .../2014-09-25_reorder/mutex_PT_f2_n16.out | 2 + .../2014-09-25_reorder/mutex_PT_f2_n2.out | 10 + .../2014-09-25_reorder/mutex_PT_f2_n3.out | 10 + .../2014-09-25_reorder/mutex_PT_f2_n4.out | 10 + .../2014-09-25_reorder/mutex_PT_f2_n5.out | 10 + .../2014-09-25_reorder/mutex_PT_f2_n6.out | 10 + .../2014-09-25_reorder/mutex_PT_f2_n7.out | 10 + .../2014-09-25_reorder/mutex_PT_f2_n8.out | 10 + .../2014-09-25_reorder/mutex_PT_f2_n9.out | 10 + .../2014-09-25_reorder/mutex_PT_f3_n10.out | 10 + .../2014-09-25_reorder/mutex_PT_f3_n11.out | 10 + .../2014-09-25_reorder/mutex_PT_f3_n12.out | 2 + .../2014-09-25_reorder/mutex_PT_f3_n2.out | 10 + .../2014-09-25_reorder/mutex_PT_f3_n3.out | 10 + .../2014-09-25_reorder/mutex_PT_f3_n4.out | 10 + .../2014-09-25_reorder/mutex_PT_f3_n5.out | 10 + .../2014-09-25_reorder/mutex_PT_f3_n6.out | 10 + .../2014-09-25_reorder/mutex_PT_f3_n7.out | 10 + .../2014-09-25_reorder/mutex_PT_f3_n8.out | 10 + .../2014-09-25_reorder/mutex_PT_f3_n9.out | 10 + in/results/2014-09-25_reorder/mutex_f1.dat | 21 + in/results/2014-09-25_reorder/mutex_f1_pt.dat | 10 + in/results/2014-09-25_reorder/mutex_f2.dat | 21 + in/results/2014-09-25_reorder/mutex_f2_pt.dat | 14 + in/results/2014-09-25_reorder/mutex_f3.dat | 21 + in/results/2014-09-25_reorder/mutex_f3_pt.dat | 10 + .../pipe_abs_MT_v1_f0_n10.out | 10 + .../pipe_abs_MT_v1_f0_n11.out | 10 + .../pipe_abs_MT_v1_f0_n12.out | 10 + .../pipe_abs_MT_v1_f0_n13.out | 10 + .../pipe_abs_MT_v1_f0_n14.out | 10 + .../pipe_abs_MT_v1_f0_n15.out | 10 + .../pipe_abs_MT_v1_f0_n16.out | 10 + .../pipe_abs_MT_v1_f0_n17.out | 10 + .../pipe_abs_MT_v1_f0_n18.out | 10 + .../pipe_abs_MT_v1_f0_n19.out | 10 + .../pipe_abs_MT_v1_f0_n2.out | 10 + .../pipe_abs_MT_v1_f0_n20.out | 10 + .../pipe_abs_MT_v1_f0_n21.out | 10 + .../pipe_abs_MT_v1_f0_n22.out | 10 + .../pipe_abs_MT_v1_f0_n23.out | 10 + .../pipe_abs_MT_v1_f0_n24.out | 10 + .../pipe_abs_MT_v1_f0_n25.out | 10 + .../pipe_abs_MT_v1_f0_n26.out | 10 + .../pipe_abs_MT_v1_f0_n27.out | 10 + .../pipe_abs_MT_v1_f0_n28.out | 10 + .../pipe_abs_MT_v1_f0_n29.out | 10 + .../pipe_abs_MT_v1_f0_n3.out | 10 + .../pipe_abs_MT_v1_f0_n30.out | 10 + .../pipe_abs_MT_v1_f0_n31.out | 10 + .../pipe_abs_MT_v1_f0_n32.out | 10 + .../pipe_abs_MT_v1_f0_n33.out | 10 + .../pipe_abs_MT_v1_f0_n34.out | 10 + .../pipe_abs_MT_v1_f0_n35.out | 10 + .../pipe_abs_MT_v1_f0_n36.out | 10 + .../pipe_abs_MT_v1_f0_n37.out | 10 + .../pipe_abs_MT_v1_f0_n38.out | 10 + .../pipe_abs_MT_v1_f0_n39.out | 10 + .../pipe_abs_MT_v1_f0_n4.out | 10 + .../pipe_abs_MT_v1_f0_n40.out | 10 + .../pipe_abs_MT_v1_f0_n5.out | 10 + .../pipe_abs_MT_v1_f0_n6.out | 10 + .../pipe_abs_MT_v1_f0_n7.out | 10 + .../pipe_abs_MT_v1_f0_n8.out | 10 + .../pipe_abs_MT_v1_f0_n9.out | 10 + .../pipe_abs_MT_v2_f0_n10.out | 10 + .../pipe_abs_MT_v2_f0_n11.out | 10 + .../pipe_abs_MT_v2_f0_n12.out | 2 + .../pipe_abs_MT_v2_f0_n2.out | 10 + .../pipe_abs_MT_v2_f0_n3.out | 10 + .../pipe_abs_MT_v2_f0_n4.out | 10 + .../pipe_abs_MT_v2_f0_n5.out | 10 + .../pipe_abs_MT_v2_f0_n6.out | 10 + .../pipe_abs_MT_v2_f0_n7.out | 10 + .../pipe_abs_MT_v2_f0_n8.out | 10 + .../pipe_abs_MT_v2_f0_n9.out | 10 + .../pipe_abs_PT_v1_f0_n10.out | 10 + .../pipe_abs_PT_v1_f0_n11.out | 10 + .../pipe_abs_PT_v1_f0_n12.out | 10 + .../pipe_abs_PT_v1_f0_n13.out | 10 + .../pipe_abs_PT_v1_f0_n14.out | 10 + .../pipe_abs_PT_v1_f0_n15.out | 10 + .../pipe_abs_PT_v1_f0_n16.out | 10 + .../pipe_abs_PT_v1_f0_n17.out | 10 + .../pipe_abs_PT_v1_f0_n18.out | 10 + .../pipe_abs_PT_v1_f0_n19.out | 10 + .../pipe_abs_PT_v1_f0_n2.out | 10 + .../pipe_abs_PT_v1_f0_n20.out | 10 + .../pipe_abs_PT_v1_f0_n21.out | 10 + .../pipe_abs_PT_v1_f0_n22.out | 10 + .../pipe_abs_PT_v1_f0_n23.out | 10 + .../pipe_abs_PT_v1_f0_n24.out | 10 + .../pipe_abs_PT_v1_f0_n25.out | 10 + .../pipe_abs_PT_v1_f0_n26.out | 10 + .../pipe_abs_PT_v1_f0_n27.out | 10 + .../pipe_abs_PT_v1_f0_n28.out | 10 + .../pipe_abs_PT_v1_f0_n29.out | 10 + .../pipe_abs_PT_v1_f0_n3.out | 10 + .../pipe_abs_PT_v1_f0_n30.out | 10 + .../pipe_abs_PT_v1_f0_n31.out | 10 + .../pipe_abs_PT_v1_f0_n32.out | 10 + .../pipe_abs_PT_v1_f0_n33.out | 10 + .../pipe_abs_PT_v1_f0_n34.out | 10 + .../pipe_abs_PT_v1_f0_n35.out | 10 + .../pipe_abs_PT_v1_f0_n36.out | 10 + .../pipe_abs_PT_v1_f0_n37.out | 10 + .../pipe_abs_PT_v1_f0_n38.out | 10 + .../pipe_abs_PT_v1_f0_n39.out | 10 + .../pipe_abs_PT_v1_f0_n4.out | 10 + .../pipe_abs_PT_v1_f0_n40.out | 10 + .../pipe_abs_PT_v1_f0_n5.out | 10 + .../pipe_abs_PT_v1_f0_n6.out | 10 + .../pipe_abs_PT_v1_f0_n7.out | 10 + .../pipe_abs_PT_v1_f0_n8.out | 10 + .../pipe_abs_PT_v1_f0_n9.out | 10 + .../pipe_abs_PT_v2_f0_n10.out | 10 + .../pipe_abs_PT_v2_f0_n11.out | 10 + .../pipe_abs_PT_v2_f0_n12.out | 2 + .../pipe_abs_PT_v2_f0_n2.out | 10 + .../pipe_abs_PT_v2_f0_n3.out | 10 + .../pipe_abs_PT_v2_f0_n4.out | 10 + .../pipe_abs_PT_v2_f0_n5.out | 10 + .../pipe_abs_PT_v2_f0_n6.out | 10 + .../pipe_abs_PT_v2_f0_n7.out | 10 + .../pipe_abs_PT_v2_f0_n8.out | 10 + .../pipe_abs_PT_v2_f0_n9.out | 10 + .../2014-09-25_reorder/pipe_abs_v1_f0.dat | 39 + .../2014-09-25_reorder/pipe_abs_v1_f0_pt.dat | 39 + .../2014-09-25_reorder/pipe_abs_v2_f0.dat | 10 + .../2014-09-25_reorder/pipe_abs_v2_f0_pt.dat | 10 + .../2014-09-25_reorder/summary_bc_MT_f1 | 25 + .../2014-09-25_reorder/summary_bc_MT_f2 | 25 + .../2014-09-25_reorder/summary_bc_MT_f3 | 17 + .../2014-09-25_reorder/summary_bc_MT_f4 | 25 + .../2014-09-25_reorder/summary_bc_PT_f1 | 21 + .../2014-09-25_reorder/summary_bc_PT_f2 | 23 + .../2014-09-25_reorder/summary_bc_PT_f3 | 17 + .../2014-09-25_reorder/summary_bc_PT_f4 | 23 + .../2014-09-25_reorder/summary_mutex_MT_f1 | 21 + .../2014-09-25_reorder/summary_mutex_MT_f2 | 21 + .../2014-09-25_reorder/summary_mutex_MT_f3 | 21 + .../2014-09-25_reorder/summary_mutex_PT_f1 | 10 + .../2014-09-25_reorder/summary_mutex_PT_f2 | 14 + .../2014-09-25_reorder/summary_mutex_PT_f3 | 10 + .../summary_pipe_abs_MT_v1_f0 | 39 + .../summary_pipe_abs_MT_v2_f0 | 10 + .../summary_pipe_abs_PT_v1_f0 | 39 + .../summary_pipe_abs_PT_v2_f0 | 10 + in/results_old/10.out | 9 + in/results_old/12.out | 9 + in/results_old/14.out | 9 + in/results_old/16.out | 9 + in/results_old/18.out | 9 + in/results_old/20.out | 9 + in/results_old/22.out | 9 + in/results_old/24.out | 9 + in/results_old/26.out | 9 + in/results_old/28.out | 9 + in/results_old/30.out | 9 + in/results_old/32.out | 9 + in/results_old/34.out | 9 + in/results_old/36.out | 9 + in/results_old/38.out | 9 + in/results_old/40.out | 9 + in/results_old/42.out | 9 + in/results_old/44.out | 9 + in/results_old/46.out | 9 + in/results_old/48.out | 9 + in/results_old/50.out | 9 + in/results_old/52.out | 9 + in/results_old/8.out | 9 + macro.hh | 31 + main.cc | 217 + main.hh | 30 + mc.cc | 504 + mc.hh | 76 + memtime.hh | 67 + options.cc | 1 + options.hh | 37 + rs.cc | 170 + rs.hh | 99 + rsin_driver.cc | 46 + rsin_driver.hh | 48 + rsin_parser.ll | 113 + rsin_parser.yy | 325 + rsmc-1.0a_linux_ubuntu/USAGE | 42 + rsmc-1.0a_linux_ubuntu/examples/abs_10_V1.rs | 79 + rsmc-1.0a_linux_ubuntu/examples/abs_10_V2.rs | 79 + rsmc-1.0a_linux_ubuntu/examples/abs_5_V1.rs | 44 + rsmc-1.0a_linux_ubuntu/examples/abs_5_V2.rs | 44 + rsmc-1.0a_linux_ubuntu/examples/bc_16_P1.rs | 303 + rsmc-1.0a_linux_ubuntu/examples/bc_16_P2.rs | 303 + rsmc-1.0a_linux_ubuntu/examples/bc_16_P3.rs | 303 + rsmc-1.0a_linux_ubuntu/examples/bc_16_P4.rs | 303 + .../examples/generators/gen_abstract1.py | 47 + .../examples/generators/gen_bc.py | 118 + .../examples/generators/gen_mutex.py | 76 + rsmc-1.0a_linux_ubuntu/examples/hsr.rs | 43 + .../examples/mutex_10_P1.rs | 168 + .../examples/mutex_10_P2.rs | 168 + .../examples/mutex_10_P3.rs | 168 + rsmc-1.0a_linux_ubuntu/examples/mutex_6_P1.rs | 80 + rsmc-1.0a_linux_ubuntu/examples/mutex_6_P2.rs | 80 + rsmc-1.0a_linux_ubuntu/examples/mutex_6_P3.rs | 80 + rsmc-1.0a_linux_ubuntu/rsmc | Bin 0 -> 3535485 bytes rsmc-1.0a_macosx.tgz | Bin 0 -> 287665 bytes rsmc-1.0a_macosx/USAGE | 42 + rsmc-1.0a_macosx/examples/abs_10_V1.rs | 79 + rsmc-1.0a_macosx/examples/abs_10_V2.rs | 79 + rsmc-1.0a_macosx/examples/abs_5_V1.rs | 44 + rsmc-1.0a_macosx/examples/abs_5_V2.rs | 44 + rsmc-1.0a_macosx/examples/bc_16_P1.rs | 303 + rsmc-1.0a_macosx/examples/bc_16_P2.rs | 303 + rsmc-1.0a_macosx/examples/bc_16_P3.rs | 303 + rsmc-1.0a_macosx/examples/bc_16_P4.rs | 303 + .../examples/generators/gen_abstract1.py | 47 + .../examples/generators/gen_bc.py | 118 + .../examples/generators/gen_mutex.py | 76 + rsmc-1.0a_macosx/examples/hsr.rs | 43 + rsmc-1.0a_macosx/examples/mutex_10_P1.rs | 168 + rsmc-1.0a_macosx/examples/mutex_10_P2.rs | 168 + rsmc-1.0a_macosx/examples/mutex_10_P3.rs | 168 + rsmc-1.0a_macosx/examples/mutex_6_P1.rs | 80 + rsmc-1.0a_macosx/examples/mutex_6_P2.rs | 80 + rsmc-1.0a_macosx/examples/mutex_6_P3.rs | 80 + rsmc-1.0a_macosx/rsmc | Bin 0 -> 680028 bytes symrs.cc | 411 + symrs.hh | 150 + test.rs | 19 + 2071 files changed, 222512 insertions(+) create mode 100644 Makefile create mode 100644 bdd_macro.hh create mode 100644 cudd.hh create mode 100644 cudd_local/LICENSE create mode 100644 cudd_local/Makefile create mode 100644 cudd_local/README create mode 100644 cudd_local/RELEASE.NOTES create mode 100644 cudd_local/cudd/Makefile create mode 100644 cudd_local/cudd/cudd.h create mode 100644 cudd_local/cudd/cuddAPI.c create mode 100644 cudd_local/cudd/cuddAddAbs.c create mode 100644 cudd_local/cudd/cuddAddApply.c create mode 100644 cudd_local/cudd/cuddAddFind.c create mode 100644 cudd_local/cudd/cuddAddInv.c create mode 100644 cudd_local/cudd/cuddAddIte.c create mode 100644 cudd_local/cudd/cuddAddNeg.c create mode 100644 cudd_local/cudd/cuddAddWalsh.c create mode 100644 cudd_local/cudd/cuddAndAbs.c create mode 100644 cudd_local/cudd/cuddAnneal.c create mode 100644 cudd_local/cudd/cuddApa.c create mode 100644 cudd_local/cudd/cuddApprox.c create mode 100644 cudd_local/cudd/cuddBddAbs.c create mode 100644 cudd_local/cudd/cuddBddCorr.c create mode 100644 cudd_local/cudd/cuddBddIte.c create mode 100644 cudd_local/cudd/cuddBridge.c create mode 100644 cudd_local/cudd/cuddCache.c create mode 100644 cudd_local/cudd/cuddCheck.c create mode 100644 cudd_local/cudd/cuddClip.c create mode 100644 cudd_local/cudd/cuddCof.c create mode 100644 cudd_local/cudd/cuddCompose.c create mode 100644 cudd_local/cudd/cuddDecomp.c create mode 100644 cudd_local/cudd/cuddEssent.c create mode 100644 cudd_local/cudd/cuddExact.c create mode 100644 cudd_local/cudd/cuddExport.c create mode 100644 cudd_local/cudd/cuddGenCof.c create mode 100644 cudd_local/cudd/cuddGenetic.c create mode 100644 cudd_local/cudd/cuddGroup.c create mode 100644 cudd_local/cudd/cuddHarwell.c create mode 100644 cudd_local/cudd/cuddInit.c create mode 100644 cudd_local/cudd/cuddInt.h create mode 100644 cudd_local/cudd/cuddInteract.c create mode 100644 cudd_local/cudd/cuddLCache.c create mode 100644 cudd_local/cudd/cuddLevelQ.c create mode 100644 cudd_local/cudd/cuddLinear.c create mode 100644 cudd_local/cudd/cuddLiteral.c create mode 100644 cudd_local/cudd/cuddMatMult.c create mode 100644 cudd_local/cudd/cuddPriority.c create mode 100644 cudd_local/cudd/cuddRead.c create mode 100644 cudd_local/cudd/cuddRef.c create mode 100644 cudd_local/cudd/cuddReorder.c create mode 100644 cudd_local/cudd/cuddSat.c create mode 100644 cudd_local/cudd/cuddSign.c create mode 100644 cudd_local/cudd/cuddSolve.c create mode 100644 cudd_local/cudd/cuddSplit.c create mode 100644 cudd_local/cudd/cuddSubsetHB.c create mode 100644 cudd_local/cudd/cuddSubsetSP.c create mode 100644 cudd_local/cudd/cuddSymmetry.c create mode 100644 cudd_local/cudd/cuddTable.c create mode 100644 cudd_local/cudd/cuddUtil.c create mode 100644 cudd_local/cudd/cuddWindow.c create mode 100644 cudd_local/cudd/cuddZddCount.c create mode 100644 cudd_local/cudd/cuddZddFuncs.c create mode 100644 cudd_local/cudd/cuddZddGroup.c create mode 100644 cudd_local/cudd/cuddZddIsop.c create mode 100644 cudd_local/cudd/cuddZddLin.c create mode 100644 cudd_local/cudd/cuddZddMisc.c create mode 100644 cudd_local/cudd/cuddZddPort.c create mode 100644 cudd_local/cudd/cuddZddReord.c create mode 100644 cudd_local/cudd/cuddZddSetop.c create mode 100644 cudd_local/cudd/cuddZddSymm.c create mode 100644 cudd_local/cudd/cuddZddUtil.c create mode 100644 cudd_local/cudd/doc/cudd.doc create mode 100644 cudd_local/cudd/doc/cudd.ps create mode 100644 cudd_local/cudd/doc/cuddAllAbs.html create mode 100644 cudd_local/cudd/doc/cuddAllByFile.html create mode 100644 cudd_local/cudd/doc/cuddAllByFunc.html create mode 100644 cudd_local/cudd/doc/cuddAllDet.html create mode 100644 cudd_local/cudd/doc/cuddAllFile.html create mode 100644 cudd_local/cudd/doc/cuddDesc.html create mode 100644 cudd_local/cudd/doc/cuddExt.html create mode 100644 cudd_local/cudd/doc/cuddExtAbs.html create mode 100644 cudd_local/cudd/doc/cuddExtDet.html create mode 100644 cudd_local/cudd/doc/cuddIntro.css create mode 100644 cudd_local/cudd/doc/cuddIntro.html create mode 100644 cudd_local/cudd/doc/cuddTitle.html create mode 100644 cudd_local/cudd/doc/footnode.html create mode 100644 cudd_local/cudd/doc/icons/blueball.png create mode 100644 cudd_local/cudd/doc/icons/ch_beg_r.png create mode 100644 cudd_local/cudd/doc/icons/ch_begin.png create mode 100644 cudd_local/cudd/doc/icons/ch_del_r.png create mode 100644 cudd_local/cudd/doc/icons/ch_delet.png create mode 100644 cudd_local/cudd/doc/icons/ch_end.png create mode 100644 cudd_local/cudd/doc/icons/ch_end_r.png create mode 100644 cudd_local/cudd/doc/icons/contents.png create mode 100644 cudd_local/cudd/doc/icons/crossref.png create mode 100644 cudd_local/cudd/doc/icons/footnote.png create mode 100644 cudd_local/cudd/doc/icons/greenball.png create mode 100644 cudd_local/cudd/doc/icons/image.png create mode 100644 cudd_local/cudd/doc/icons/index.png create mode 100644 cudd_local/cudd/doc/icons/next.png create mode 100644 cudd_local/cudd/doc/icons/next_g.png create mode 100644 cudd_local/cudd/doc/icons/nx_grp.png create mode 100644 cudd_local/cudd/doc/icons/nx_grp_g.png create mode 100644 cudd_local/cudd/doc/icons/orangeball.png create mode 100644 cudd_local/cudd/doc/icons/pinkball.png create mode 100644 cudd_local/cudd/doc/icons/prev.png create mode 100644 cudd_local/cudd/doc/icons/prev_g.png create mode 100644 cudd_local/cudd/doc/icons/purpleball.png create mode 100644 cudd_local/cudd/doc/icons/pv_grp.png create mode 100644 cudd_local/cudd/doc/icons/pv_grp_g.png create mode 100644 cudd_local/cudd/doc/icons/redball.png create mode 100644 cudd_local/cudd/doc/icons/up.png create mode 100644 cudd_local/cudd/doc/icons/up_g.png create mode 100644 cudd_local/cudd/doc/icons/whiteball.png create mode 100644 cudd_local/cudd/doc/icons/yellowball.png create mode 100644 cudd_local/cudd/doc/img1.png create mode 100644 cudd_local/cudd/doc/img10.png create mode 100644 cudd_local/cudd/doc/img11.png create mode 100644 cudd_local/cudd/doc/img12.png create mode 100644 cudd_local/cudd/doc/img13.png create mode 100644 cudd_local/cudd/doc/img14.png create mode 100644 cudd_local/cudd/doc/img15.png create mode 100644 cudd_local/cudd/doc/img16.png create mode 100644 cudd_local/cudd/doc/img17.png create mode 100644 cudd_local/cudd/doc/img18.png create mode 100644 cudd_local/cudd/doc/img19.png create mode 100644 cudd_local/cudd/doc/img2.png create mode 100644 cudd_local/cudd/doc/img20.png create mode 100644 cudd_local/cudd/doc/img21.png create mode 100644 cudd_local/cudd/doc/img22.png create mode 100644 cudd_local/cudd/doc/img3.png create mode 100644 cudd_local/cudd/doc/img4.png create mode 100644 cudd_local/cudd/doc/img5.png create mode 100644 cudd_local/cudd/doc/img6.png create mode 100644 cudd_local/cudd/doc/img7.png create mode 100644 cudd_local/cudd/doc/img8.png create mode 100644 cudd_local/cudd/doc/img9.png create mode 100644 cudd_local/cudd/doc/index.html create mode 100644 cudd_local/cudd/doc/node1.html create mode 100644 cudd_local/cudd/doc/node2.html create mode 100644 cudd_local/cudd/doc/node3.html create mode 100644 cudd_local/cudd/doc/node4.html create mode 100644 cudd_local/cudd/doc/node5.html create mode 100644 cudd_local/cudd/doc/node6.html create mode 100644 cudd_local/cudd/doc/node7.html create mode 100644 cudd_local/cudd/doc/node8.html create mode 100644 cudd_local/cudd/libcudd.a create mode 100644 cudd_local/cudd/r7x8.1.mat create mode 100644 cudd_local/cudd/r7x8.1.out create mode 100644 cudd_local/cudd/testcudd.c create mode 100644 cudd_local/dddmp/Makefile create mode 100644 cudd_local/dddmp/README.dddmp create mode 100644 cudd_local/dddmp/README.testdddmp create mode 100644 cudd_local/dddmp/RELEASE_NOTES create mode 100644 cudd_local/dddmp/dddmp.h create mode 100644 cudd_local/dddmp/dddmpBinary.c create mode 100644 cudd_local/dddmp/dddmpConvert.c create mode 100644 cudd_local/dddmp/dddmpDbg.c create mode 100644 cudd_local/dddmp/dddmpDdNodeBdd.c create mode 100644 cudd_local/dddmp/dddmpDdNodeCnf.c create mode 100644 cudd_local/dddmp/dddmpInt.h create mode 100644 cudd_local/dddmp/dddmpLoad.c create mode 100644 cudd_local/dddmp/dddmpLoadCnf.c create mode 100644 cudd_local/dddmp/dddmpNodeAdd.c create mode 100644 cudd_local/dddmp/dddmpNodeBdd.c create mode 100644 cudd_local/dddmp/dddmpNodeCnf.c create mode 100644 cudd_local/dddmp/dddmpStoreAdd.c create mode 100644 cudd_local/dddmp/dddmpStoreBdd.c create mode 100644 cudd_local/dddmp/dddmpStoreCnf.c create mode 100644 cudd_local/dddmp/dddmpStoreMisc.c create mode 100644 cudd_local/dddmp/dddmpUtil.c create mode 100644 cudd_local/dddmp/doc/cmdIndex.html create mode 100644 cudd_local/dddmp/doc/commands.html create mode 100644 cudd_local/dddmp/doc/credit.html create mode 100644 cudd_local/dddmp/doc/dddmp-2.0-A4.ps create mode 100644 cudd_local/dddmp/doc/dddmp-2.0-Letter.ps create mode 100644 cudd_local/dddmp/doc/dddmpAllAbs.html create mode 100644 cudd_local/dddmp/doc/dddmpAllByFile.html create mode 100644 cudd_local/dddmp/doc/dddmpAllByFunc.html create mode 100644 cudd_local/dddmp/doc/dddmpAllDet.html create mode 100644 cudd_local/dddmp/doc/dddmpAllFile.html create mode 100644 cudd_local/dddmp/doc/dddmpDesc.html create mode 100644 cudd_local/dddmp/doc/dddmpDoc.txt create mode 100644 cudd_local/dddmp/doc/dddmpExt.html create mode 100644 cudd_local/dddmp/doc/dddmpExtAbs.html create mode 100644 cudd_local/dddmp/doc/dddmpExtDet.html create mode 100644 cudd_local/dddmp/doc/dddmpTitle.html create mode 100644 cudd_local/dddmp/doc/packages.html create mode 100644 cudd_local/dddmp/doc/pkgIndex.html create mode 100644 cudd_local/dddmp/exp/0.add create mode 100644 cudd_local/dddmp/exp/0.bdd create mode 100644 cudd_local/dddmp/exp/0or1.bdd create mode 100644 cudd_local/dddmp/exp/1.add create mode 100644 cudd_local/dddmp/exp/1.bdd create mode 100644 cudd_local/dddmp/exp/2.bdd create mode 100644 cudd_local/dddmp/exp/2and3.bdd create mode 100644 cudd_local/dddmp/exp/3.bdd create mode 100644 cudd_local/dddmp/exp/4.bdd create mode 100644 cudd_local/dddmp/exp/4.bdd.bis1 create mode 100644 cudd_local/dddmp/exp/4.bdd.bis2 create mode 100644 cudd_local/dddmp/exp/4.bdd.bis3 create mode 100644 cudd_local/dddmp/exp/4.bdd.bis4 create mode 100644 cudd_local/dddmp/exp/4.cnf create mode 100644 cudd_local/dddmp/exp/4.cnf.bis create mode 100644 cudd_local/dddmp/exp/4.max1 create mode 100644 cudd_local/dddmp/exp/4.max2 create mode 100644 cudd_local/dddmp/exp/4bis.bdd create mode 100644 cudd_local/dddmp/exp/4xor5.bdd create mode 100644 cudd_local/dddmp/exp/5.bdd create mode 100644 cudd_local/dddmp/exp/composeids.txt create mode 100644 cudd_local/dddmp/exp/one.bdd create mode 100644 cudd_local/dddmp/exp/runAllTest.out create mode 100755 cudd_local/dddmp/exp/runAllTest.script create mode 100644 cudd_local/dddmp/exp/s27RP1.bdd create mode 100644 cudd_local/dddmp/exp/s27deltaDddmp1.bdd create mode 100644 cudd_local/dddmp/exp/s27deltaDddmp1.bdd.bis create mode 100644 cudd_local/dddmp/exp/s27deltaDddmp2.bdd create mode 100644 cudd_local/dddmp/exp/test1.out create mode 100755 cudd_local/dddmp/exp/test1.script create mode 100644 cudd_local/dddmp/exp/test2.out create mode 100755 cudd_local/dddmp/exp/test2.script create mode 100644 cudd_local/dddmp/exp/test3.out create mode 100755 cudd_local/dddmp/exp/test3.script create mode 100644 cudd_local/dddmp/exp/test4.out create mode 100755 cudd_local/dddmp/exp/test4.script create mode 100644 cudd_local/dddmp/exp/test5.out create mode 100755 cudd_local/dddmp/exp/test5.script create mode 100644 cudd_local/dddmp/exp/test6.out create mode 100755 cudd_local/dddmp/exp/test6.script create mode 100644 cudd_local/dddmp/exp/test7.out create mode 100755 cudd_local/dddmp/exp/test7.script create mode 100644 cudd_local/dddmp/exp/varauxids.ord create mode 100644 cudd_local/dddmp/exp/varnames.ord create mode 100644 cudd_local/dddmp/exp/zero.bdd create mode 100644 cudd_local/dddmp/libdddmp.a create mode 100644 cudd_local/dddmp/testdddmp.c create mode 100644 cudd_local/epd/Makefile create mode 100644 cudd_local/epd/epd.c create mode 100644 cudd_local/epd/epd.h create mode 100644 cudd_local/epd/libepd.a create mode 100644 cudd_local/include/cudd.h create mode 100644 cudd_local/include/cudd/cudd.h create mode 100644 cudd_local/include/cudd/cuddInt.h create mode 100644 cudd_local/include/cudd/cuddObj.hh create mode 100644 cudd_local/include/cudd/dddmp.h create mode 100644 cudd_local/include/cudd/epd.h create mode 100644 cudd_local/include/cudd/mnemosyne.h create mode 100644 cudd_local/include/cudd/mtr.h create mode 100644 cudd_local/include/cudd/st.h create mode 100644 cudd_local/include/cudd/util.h create mode 100644 cudd_local/include/cuddInt.h create mode 100644 cudd_local/include/cuddObj.hh create mode 100644 cudd_local/include/dddmp.h create mode 100644 cudd_local/include/epd.h create mode 100644 cudd_local/include/mnemosyne.h create mode 100644 cudd_local/include/mtr.h create mode 100644 cudd_local/include/st.h create mode 100644 cudd_local/include/util.h create mode 100644 cudd_local/mnemosyne/Makefile create mode 100644 cudd_local/mnemosyne/README create mode 100644 cudd_local/mnemosyne/mnemalyse.c create mode 100644 cudd_local/mnemosyne/mnemconf.h create mode 100644 cudd_local/mnemosyne/mnemosyne.c create mode 100644 cudd_local/mnemosyne/mnemosyne.h create mode 100644 cudd_local/mnemosyne/mtest.c create mode 100644 cudd_local/mtr/Makefile create mode 100644 cudd_local/mtr/Makefile.sis create mode 100644 cudd_local/mtr/doc/mtr.doc create mode 100644 cudd_local/mtr/doc/mtrAllAbs.html create mode 100644 cudd_local/mtr/doc/mtrAllDet.html create mode 100644 cudd_local/mtr/doc/mtrExtAbs.html create mode 100644 cudd_local/mtr/doc/mtrExtDet.html create mode 100644 cudd_local/mtr/libmtr.a create mode 100644 cudd_local/mtr/mtr.h create mode 100644 cudd_local/mtr/mtrBasic.c create mode 100644 cudd_local/mtr/mtrGroup.c create mode 100644 cudd_local/mtr/mtrInt.h create mode 100644 cudd_local/mtr/test.groups create mode 100644 cudd_local/mtr/testmtr.c create mode 100644 cudd_local/nanotrav/C17.blif create mode 100644 cudd_local/nanotrav/C17.out create mode 100644 cudd_local/nanotrav/C880.blif create mode 100644 cudd_local/nanotrav/C880.out create mode 100644 cudd_local/nanotrav/Makefile create mode 100644 cudd_local/nanotrav/README create mode 100644 cudd_local/nanotrav/bnet.c create mode 100644 cudd_local/nanotrav/bnet.h create mode 100644 cudd_local/nanotrav/chkMterm.c create mode 100644 cudd_local/nanotrav/doc/bnetAllAbs.html create mode 100644 cudd_local/nanotrav/doc/bnetAllDet.html create mode 100644 cudd_local/nanotrav/doc/bnetExtAbs.html create mode 100644 cudd_local/nanotrav/doc/bnetExtDet.html create mode 100644 cudd_local/nanotrav/doc/ntrAllAbs.html create mode 100644 cudd_local/nanotrav/doc/ntrAllDet.html create mode 100644 cudd_local/nanotrav/doc/ntrExtAbs.html create mode 100644 cudd_local/nanotrav/doc/ntrExtDet.html create mode 100644 cudd_local/nanotrav/main.c create mode 100644 cudd_local/nanotrav/mult32a.blif create mode 100644 cudd_local/nanotrav/mult32a.out create mode 100644 cudd_local/nanotrav/nanotrav.1 create mode 100644 cudd_local/nanotrav/ntr.c create mode 100644 cudd_local/nanotrav/ntr.h create mode 100644 cudd_local/nanotrav/ntrBddTest.c create mode 100644 cudd_local/nanotrav/ntrHeap.c create mode 100644 cudd_local/nanotrav/ntrMflow.c create mode 100644 cudd_local/nanotrav/ntrShort.c create mode 100644 cudd_local/nanotrav/ntrZddTest.c create mode 100644 cudd_local/nanotrav/rcn25.blif create mode 100644 cudd_local/nanotrav/rcn25.out create mode 100644 cudd_local/nanotrav/s27.blif create mode 100644 cudd_local/nanotrav/s27.out create mode 100755 cudd_local/nanotrav/tst.sh create mode 100644 cudd_local/nanotrav/ucbqsort.c create mode 100644 cudd_local/obj/Makefile create mode 100644 cudd_local/obj/cuddObj.cc create mode 100644 cudd_local/obj/cuddObj.hh create mode 100644 cudd_local/obj/libobj.a create mode 100644 cudd_local/obj/test.out create mode 100644 cudd_local/obj/testobj.cc create mode 100755 cudd_local/setup.sh create mode 100755 cudd_local/shutdown.sh create mode 100644 cudd_local/sis/Makefile.sis create mode 100644 cudd_local/sis/cuddBdd.h create mode 100644 cudd_local/sis/cuddBddPort.c create mode 100644 cudd_local/sis/cuddPwPt.c create mode 100644 cudd_local/sis/st.c create mode 100644 cudd_local/sis/st.h create mode 100644 cudd_local/st/Makefile create mode 100644 cudd_local/st/doc/stAllAbs.html create mode 100644 cudd_local/st/doc/stAllDet.html create mode 100644 cudd_local/st/doc/stExtAbs.html create mode 100644 cudd_local/st/doc/stExtDet.html create mode 100644 cudd_local/st/libst.a create mode 100644 cudd_local/st/st.c create mode 100644 cudd_local/st/st.h create mode 100644 cudd_local/util/Makefile create mode 100644 cudd_local/util/cpu_stats.c create mode 100644 cudd_local/util/cpu_time.c create mode 100644 cudd_local/util/datalimit.c create mode 100644 cudd_local/util/libutil.a create mode 100644 cudd_local/util/pathsearch.c create mode 100644 cudd_local/util/pipefork.c create mode 100644 cudd_local/util/prtime.c create mode 100644 cudd_local/util/ptime.c create mode 100644 cudd_local/util/restart.c create mode 100644 cudd_local/util/safe_mem.c create mode 100644 cudd_local/util/saveimage.c create mode 100644 cudd_local/util/state.c create mode 100644 cudd_local/util/strsav.c create mode 100644 cudd_local/util/stub.c create mode 100644 cudd_local/util/test-res.c create mode 100644 cudd_local/util/test-sav.c create mode 100644 cudd_local/util/texpand.c create mode 100644 cudd_local/util/util.h create mode 100755 cudd_local_enable.sh create mode 100644 formrsctl.cc create mode 100644 formrsctl.hh create mode 100644 in/bench_bc.sh create mode 100644 in/bench_mutex.sh create mode 100644 in/bench_pipe.sh create mode 100644 in/benchmark.sh create mode 100644 in/benchmark_abs1.sh create mode 100644 in/benchmark_abs1_PT.sh create mode 100644 in/benchmark_bc.sh create mode 100644 in/benchmark_mutex.sh create mode 100644 in/benchmark_mutex_PT.sh create mode 100644 in/gen_abstract1.py create mode 100755 in/gen_bc.py create mode 100755 in/gen_mutex.py create mode 100755 in/get_results.sh create mode 100644 in/hsr.rs create mode 100644 in/old_syntax/bc32.rs create mode 100644 in/old_syntax/bc8.rs create mode 100644 in/old_syntax/coffee.rs create mode 100644 in/old_syntax/expr.rs create mode 100644 in/old_syntax/f1.dat create mode 100755 in/old_syntax/gen_bc.py create mode 100644 in/old_syntax/simple_I1.rs create mode 100644 in/old_syntax/test.rs create mode 100644 in/old_syntax/u1.rs create mode 100644 in/old_syntax/u2.rs create mode 100644 in/results/2014-09-01/bc_MT_f1_n1.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n10.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n11.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n12.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n13.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n14.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n15.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n16.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n17.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n18.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n19.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n2.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n20.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n21.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n22.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n23.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n24.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n25.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n3.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n4.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n5.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n6.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n7.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n8.out create mode 100644 in/results/2014-09-01/bc_MT_f1_n9.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n1.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n10.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n11.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n12.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n13.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n14.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n15.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n16.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n17.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n18.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n19.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n2.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n20.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n21.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n22.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n23.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n24.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n25.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n3.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n4.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n5.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n6.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n7.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n8.out create mode 100644 in/results/2014-09-01/bc_MT_f2_n9.out create mode 100644 in/results/2014-09-01/bc_MT_f3_n10.out create mode 100644 in/results/2014-09-01/bc_MT_f3_n11.out create mode 100644 in/results/2014-09-01/bc_MT_f3_n12.out create mode 100644 in/results/2014-09-01/bc_MT_f3_n13.out create mode 100644 in/results/2014-09-01/bc_MT_f3_n14.out create mode 100644 in/results/2014-09-01/bc_MT_f3_n15.out create mode 100644 in/results/2014-09-01/bc_MT_f3_n16.out create mode 100644 in/results/2014-09-01/bc_MT_f3_n17.out create mode 100644 in/results/2014-09-01/bc_MT_f3_n18.out create mode 100644 in/results/2014-09-01/bc_MT_f3_n19.out create mode 100644 in/results/2014-09-01/bc_MT_f3_n20.out create mode 100644 in/results/2014-09-01/bc_MT_f3_n21.out create mode 100644 in/results/2014-09-01/bc_MT_f3_n22.out create mode 100644 in/results/2014-09-01/bc_MT_f3_n23.out create mode 100644 in/results/2014-09-01/bc_MT_f3_n24.out create mode 100644 in/results/2014-09-01/bc_MT_f3_n25.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n1.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n10.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n11.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n12.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n13.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n14.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n15.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n16.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n17.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n18.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n19.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n2.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n20.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n21.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n22.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n23.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n24.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n25.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n3.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n4.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n5.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n6.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n7.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n8.out create mode 100644 in/results/2014-09-01/bc_MT_f4_n9.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n1.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n10.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n11.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n12.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n13.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n14.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n15.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n16.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n17.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n18.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n19.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n2.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n20.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n21.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n22.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n23.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n24.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n25.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n3.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n4.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n5.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n6.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n7.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n8.out create mode 100644 in/results/2014-09-01/bc_PT_f1_n9.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n1.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n10.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n11.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n12.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n13.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n14.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n15.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n16.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n17.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n18.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n19.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n2.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n20.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n21.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n22.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n23.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n24.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n25.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n3.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n4.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n5.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n6.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n7.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n8.out create mode 100644 in/results/2014-09-01/bc_PT_f2_n9.out create mode 100644 in/results/2014-09-01/bc_PT_f3_n10.out create mode 100644 in/results/2014-09-01/bc_PT_f3_n11.out create mode 100644 in/results/2014-09-01/bc_PT_f3_n12.out create mode 100644 in/results/2014-09-01/bc_PT_f3_n13.out create mode 100644 in/results/2014-09-01/bc_PT_f3_n14.out create mode 100644 in/results/2014-09-01/bc_PT_f3_n15.out create mode 100644 in/results/2014-09-01/bc_PT_f3_n16.out create mode 100644 in/results/2014-09-01/bc_PT_f3_n17.out create mode 100644 in/results/2014-09-01/bc_PT_f3_n18.out create mode 100644 in/results/2014-09-01/bc_PT_f3_n19.out create mode 100644 in/results/2014-09-01/bc_PT_f3_n20.out create mode 100644 in/results/2014-09-01/bc_PT_f3_n21.out create mode 100644 in/results/2014-09-01/bc_PT_f3_n22.out create mode 100644 in/results/2014-09-01/bc_PT_f3_n23.out create mode 100644 in/results/2014-09-01/bc_PT_f3_n24.out create mode 100644 in/results/2014-09-01/bc_PT_f3_n25.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n1.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n10.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n11.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n12.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n13.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n14.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n15.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n16.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n17.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n18.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n19.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n2.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n20.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n21.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n22.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n23.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n24.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n25.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n3.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n4.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n5.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n6.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n7.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n8.out create mode 100644 in/results/2014-09-01/bc_PT_f4_n9.out create mode 100644 in/results/2014-09-01/bc_f1.dat create mode 100644 in/results/2014-09-01/bc_f1_pt.dat create mode 100644 in/results/2014-09-01/bc_f2.dat create mode 100644 in/results/2014-09-01/bc_f2_pt.dat create mode 100644 in/results/2014-09-01/bc_f3.dat create mode 100644 in/results/2014-09-01/bc_f3_pt.dat create mode 100644 in/results/2014-09-01/bc_f4.dat create mode 100644 in/results/2014-09-01/bc_f4_pt.dat create mode 100644 in/results/2014-09-01/summary_bc_MT_f1 create mode 100644 in/results/2014-09-01/summary_bc_MT_f2 create mode 100644 in/results/2014-09-01/summary_bc_MT_f3 create mode 100644 in/results/2014-09-01/summary_bc_MT_f4 create mode 100644 in/results/2014-09-01/summary_bc_PT_f1 create mode 100644 in/results/2014-09-01/summary_bc_PT_f2 create mode 100644 in/results/2014-09-01/summary_bc_PT_f3 create mode 100644 in/results/2014-09-01/summary_bc_PT_f4 create mode 100644 in/results/2014-09-16/bc_MT_f1_n1.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n10.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n11.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n12.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n13.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n14.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n15.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n16.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n17.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n18.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n19.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n2.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n20.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n21.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n22.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n23.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n24.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n25.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n3.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n4.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n5.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n6.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n7.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n8.out create mode 100644 in/results/2014-09-16/bc_MT_f1_n9.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n1.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n10.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n11.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n12.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n13.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n14.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n15.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n16.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n17.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n18.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n19.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n2.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n20.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n21.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n22.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n23.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n24.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n25.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n3.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n4.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n5.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n6.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n7.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n8.out create mode 100644 in/results/2014-09-16/bc_MT_f2_n9.out create mode 100644 in/results/2014-09-16/bc_MT_f3_n10.out create mode 100644 in/results/2014-09-16/bc_MT_f3_n11.out create mode 100644 in/results/2014-09-16/bc_MT_f3_n12.out create mode 100644 in/results/2014-09-16/bc_MT_f3_n13.out create mode 100644 in/results/2014-09-16/bc_MT_f3_n14.out create mode 100644 in/results/2014-09-16/bc_MT_f3_n15.out create mode 100644 in/results/2014-09-16/bc_MT_f3_n16.out create mode 100644 in/results/2014-09-16/bc_MT_f3_n17.out create mode 100644 in/results/2014-09-16/bc_MT_f3_n18.out create mode 100644 in/results/2014-09-16/bc_MT_f3_n19.out create mode 100644 in/results/2014-09-16/bc_MT_f3_n20.out create mode 100644 in/results/2014-09-16/bc_MT_f3_n21.out create mode 100644 in/results/2014-09-16/bc_MT_f3_n22.out create mode 100644 in/results/2014-09-16/bc_MT_f3_n23.out create mode 100644 in/results/2014-09-16/bc_MT_f3_n24.out create mode 100644 in/results/2014-09-16/bc_MT_f3_n25.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n1.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n10.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n11.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n12.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n13.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n14.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n15.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n16.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n17.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n18.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n19.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n2.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n20.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n21.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n22.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n23.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n24.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n25.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n3.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n4.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n5.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n6.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n7.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n8.out create mode 100644 in/results/2014-09-16/bc_MT_f4_n9.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n1.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n10.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n11.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n12.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n13.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n14.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n15.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n16.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n17.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n18.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n19.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n2.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n20.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n21.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n22.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n23.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n24.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n25.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n3.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n4.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n5.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n6.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n7.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n8.out create mode 100644 in/results/2014-09-16/bc_PT_f1_n9.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n1.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n10.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n11.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n12.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n13.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n14.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n15.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n16.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n17.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n18.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n19.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n2.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n20.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n21.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n22.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n23.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n24.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n25.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n3.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n4.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n5.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n6.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n7.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n8.out create mode 100644 in/results/2014-09-16/bc_PT_f2_n9.out create mode 100644 in/results/2014-09-16/bc_PT_f3_n10.out create mode 100644 in/results/2014-09-16/bc_PT_f3_n11.out create mode 100644 in/results/2014-09-16/bc_PT_f3_n12.out create mode 100644 in/results/2014-09-16/bc_PT_f3_n13.out create mode 100644 in/results/2014-09-16/bc_PT_f3_n14.out create mode 100644 in/results/2014-09-16/bc_PT_f3_n15.out create mode 100644 in/results/2014-09-16/bc_PT_f3_n16.out create mode 100644 in/results/2014-09-16/bc_PT_f3_n17.out create mode 100644 in/results/2014-09-16/bc_PT_f3_n18.out create mode 100644 in/results/2014-09-16/bc_PT_f3_n19.out create mode 100644 in/results/2014-09-16/bc_PT_f3_n20.out create mode 100644 in/results/2014-09-16/bc_PT_f3_n21.out create mode 100644 in/results/2014-09-16/bc_PT_f3_n22.out create mode 100644 in/results/2014-09-16/bc_PT_f3_n23.out create mode 100644 in/results/2014-09-16/bc_PT_f3_n24.out create mode 100644 in/results/2014-09-16/bc_PT_f3_n25.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n1.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n10.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n11.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n12.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n13.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n14.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n15.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n16.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n17.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n18.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n19.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n2.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n20.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n21.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n22.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n23.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n24.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n25.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n3.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n4.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n5.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n6.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n7.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n8.out create mode 100644 in/results/2014-09-16/bc_PT_f4_n9.out create mode 100644 in/results/2014-09-16/bc_f1.dat create mode 100644 in/results/2014-09-16/bc_f1_pt.dat create mode 100644 in/results/2014-09-16/bc_f2.dat create mode 100644 in/results/2014-09-16/bc_f2_pt.dat create mode 100644 in/results/2014-09-16/bc_f3.dat create mode 100644 in/results/2014-09-16/bc_f3_pt.dat create mode 100644 in/results/2014-09-16/bc_f4.dat create mode 100644 in/results/2014-09-16/bc_f4_pt.dat create mode 100644 in/results/2014-09-16/mutex_MT_f1_n10.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n11.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n12.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n13.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n14.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n15.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n16.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n17.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n18.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n19.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n2.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n20.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n21.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n22.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n23.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n24.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n25.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n26.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n27.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n28.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n29.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n3.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n30.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n31.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n32.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n33.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n34.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n35.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n36.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n37.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n38.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n39.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n4.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n40.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n5.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n6.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n7.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n8.out create mode 100644 in/results/2014-09-16/mutex_MT_f1_n9.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n10.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n11.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n12.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n13.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n14.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n15.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n16.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n17.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n18.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n19.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n2.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n20.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n21.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n22.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n23.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n24.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n25.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n26.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n27.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n28.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n29.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n3.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n30.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n31.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n32.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n33.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n34.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n35.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n36.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n37.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n38.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n39.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n4.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n40.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n5.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n6.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n7.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n8.out create mode 100644 in/results/2014-09-16/mutex_MT_f2_n9.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n10.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n11.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n12.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n13.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n14.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n15.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n16.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n17.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n18.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n19.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n2.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n20.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n21.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n22.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n23.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n24.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n25.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n26.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n27.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n28.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n29.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n3.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n30.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n31.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n32.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n33.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n34.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n35.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n36.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n37.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n38.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n39.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n4.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n40.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n5.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n6.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n7.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n8.out create mode 100644 in/results/2014-09-16/mutex_MT_f3_n9.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n10.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n11.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n12.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n13.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n14.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n15.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n16.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n17.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n18.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n19.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n2.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n20.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n21.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n22.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n23.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n24.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n25.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n26.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n27.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n28.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n29.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n3.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n30.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n31.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n32.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n33.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n34.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n35.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n36.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n37.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n38.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n39.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n4.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n40.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n5.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n6.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n7.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n8.out create mode 100644 in/results/2014-09-16/mutex_PT_f1_n9.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n10.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n11.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n12.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n13.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n14.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n15.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n16.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n17.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n18.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n19.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n2.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n20.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n21.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n22.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n23.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n24.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n25.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n26.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n27.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n28.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n29.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n3.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n30.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n31.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n32.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n33.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n34.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n35.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n36.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n37.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n38.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n39.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n4.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n40.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n5.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n6.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n7.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n8.out create mode 100644 in/results/2014-09-16/mutex_PT_f2_n9.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n10.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n11.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n12.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n13.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n14.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n15.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n16.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n17.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n18.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n19.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n2.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n20.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n21.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n22.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n23.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n24.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n25.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n26.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n27.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n28.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n29.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n3.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n30.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n31.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n32.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n33.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n34.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n35.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n36.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n37.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n38.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n39.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n4.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n40.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n5.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n6.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n7.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n8.out create mode 100644 in/results/2014-09-16/mutex_PT_f3_n9.out create mode 100644 in/results/2014-09-16/mutex_f1.dat create mode 100644 in/results/2014-09-16/mutex_f1_pt.dat create mode 100644 in/results/2014-09-16/mutex_f2.dat create mode 100644 in/results/2014-09-16/mutex_f2_pt.dat create mode 100644 in/results/2014-09-16/mutex_f3.dat create mode 100644 in/results/2014-09-16/mutex_f3_pt.dat create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n10.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n11.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n12.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n13.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n14.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n15.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n16.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n17.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n18.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n19.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n2.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n20.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n21.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n22.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n23.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n24.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n25.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n26.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n27.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n28.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n29.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n3.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n30.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n31.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n32.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n33.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n34.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n35.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n36.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n37.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n38.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n39.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n4.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n40.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n5.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n6.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n7.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n8.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v1_f0_n9.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n10.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n11.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n12.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n13.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n14.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n15.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n16.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n17.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n18.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n19.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n2.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n20.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n21.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n22.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n23.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n24.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n25.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n26.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n27.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n28.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n29.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n3.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n30.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n31.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n32.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n33.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n34.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n35.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n36.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n37.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n38.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n39.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n4.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n40.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n5.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n6.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n7.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n8.out create mode 100644 in/results/2014-09-16/pipe_abs_MT_v2_f0_n9.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n10.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n11.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n12.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n13.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n14.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n15.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n16.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n17.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n18.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n19.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n2.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n20.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n21.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n22.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n23.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n24.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n25.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n26.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n27.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n28.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n29.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n3.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n30.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n31.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n32.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n33.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n34.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n35.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n36.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n37.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n38.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n39.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n4.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n40.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n5.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n6.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n7.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n8.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v1_f0_n9.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n10.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n11.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n12.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n13.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n14.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n15.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n16.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n17.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n18.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n19.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n2.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n20.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n21.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n22.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n23.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n24.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n25.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n26.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n27.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n28.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n29.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n3.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n30.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n31.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n32.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n33.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n34.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n35.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n36.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n37.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n38.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n39.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n4.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n40.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n5.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n6.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n7.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n8.out create mode 100644 in/results/2014-09-16/pipe_abs_PT_v2_f0_n9.out create mode 100644 in/results/2014-09-16/pipe_abs_v1_f0.dat create mode 100644 in/results/2014-09-16/pipe_abs_v1_f0_pt.dat create mode 100644 in/results/2014-09-16/pipe_abs_v2_f0.dat create mode 100644 in/results/2014-09-16/pipe_abs_v2_f0_pt.dat create mode 100644 in/results/2014-09-16/summary_bc_MT_f1 create mode 100644 in/results/2014-09-16/summary_bc_MT_f2 create mode 100644 in/results/2014-09-16/summary_bc_MT_f3 create mode 100644 in/results/2014-09-16/summary_bc_MT_f4 create mode 100644 in/results/2014-09-16/summary_bc_PT_f1 create mode 100644 in/results/2014-09-16/summary_bc_PT_f2 create mode 100644 in/results/2014-09-16/summary_bc_PT_f3 create mode 100644 in/results/2014-09-16/summary_bc_PT_f4 create mode 100644 in/results/2014-09-16/summary_mutex_MT_f1 create mode 100644 in/results/2014-09-16/summary_mutex_MT_f2 create mode 100644 in/results/2014-09-16/summary_mutex_MT_f3 create mode 100644 in/results/2014-09-16/summary_mutex_PT_f1 create mode 100644 in/results/2014-09-16/summary_mutex_PT_f2 create mode 100644 in/results/2014-09-16/summary_mutex_PT_f3 create mode 100644 in/results/2014-09-16/summary_pipe_abs_MT_v1_f0 create mode 100644 in/results/2014-09-16/summary_pipe_abs_MT_v2_f0 create mode 100644 in/results/2014-09-16/summary_pipe_abs_PT_v1_f0 create mode 100644 in/results/2014-09-16/summary_pipe_abs_PT_v2_f0 create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n1.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n10.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n11.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n12.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n13.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n14.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n15.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n16.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n17.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n18.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n19.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n2.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n20.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n21.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n22.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n23.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n24.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n25.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n3.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n4.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n5.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n6.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n7.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n8.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f1_n9.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n1.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n10.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n11.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n12.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n13.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n14.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n15.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n16.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n17.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n18.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n19.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n2.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n20.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n21.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n22.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n23.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n24.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n25.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n3.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n4.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n5.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n6.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n7.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n8.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f2_n9.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f3_n10.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f3_n11.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f3_n12.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f3_n13.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f3_n14.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f3_n15.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f3_n16.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f3_n17.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f3_n18.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f3_n19.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f3_n20.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f3_n21.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f3_n22.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f3_n23.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f3_n24.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f3_n25.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f3_n9.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n1.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n10.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n11.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n12.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n13.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n14.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n15.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n16.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n17.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n18.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n19.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n2.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n20.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n21.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n22.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n23.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n24.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n25.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n3.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n4.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n5.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n6.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n7.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n8.out create mode 100644 in/results/2014-09-25_noreorder/bc_MT_f4_n9.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n1.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n10.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n11.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n12.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n13.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n14.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n15.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n16.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n17.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n18.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n19.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n2.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n20.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n21.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n22.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n3.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n4.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n5.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n6.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n7.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n8.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f1_n9.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n1.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n10.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n11.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n12.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n13.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n14.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n15.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n16.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n17.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n18.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n19.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n2.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n20.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n21.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n22.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n23.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n24.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n3.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n4.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n5.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n6.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n7.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n8.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f2_n9.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f3_n10.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f3_n11.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f3_n12.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f3_n13.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f3_n14.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f3_n15.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f3_n16.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f3_n17.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f3_n18.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f3_n19.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f3_n20.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f3_n21.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f3_n22.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f3_n23.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f3_n24.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f3_n25.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f3_n9.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n1.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n10.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n11.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n12.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n13.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n14.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n15.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n16.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n17.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n18.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n19.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n2.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n20.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n21.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n22.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n23.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n24.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n3.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n4.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n5.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n6.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n7.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n8.out create mode 100644 in/results/2014-09-25_noreorder/bc_PT_f4_n9.out create mode 100644 in/results/2014-09-25_noreorder/bc_f1.dat create mode 100644 in/results/2014-09-25_noreorder/bc_f1_pt.dat create mode 100644 in/results/2014-09-25_noreorder/bc_f2.dat create mode 100644 in/results/2014-09-25_noreorder/bc_f2_pt.dat create mode 100644 in/results/2014-09-25_noreorder/bc_f3.dat create mode 100644 in/results/2014-09-25_noreorder/bc_f3_pt.dat create mode 100644 in/results/2014-09-25_noreorder/bc_f4.dat create mode 100644 in/results/2014-09-25_noreorder/bc_f4_pt.dat create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f1_n10.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f1_n11.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f1_n12.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f1_n2.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f1_n3.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f1_n4.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f1_n5.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f1_n6.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f1_n7.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f1_n8.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f1_n9.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f2_n10.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f2_n11.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f2_n12.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f2_n2.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f2_n3.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f2_n4.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f2_n5.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f2_n6.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f2_n7.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f2_n8.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f2_n9.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f3_n10.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f3_n11.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f3_n12.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f3_n2.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f3_n3.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f3_n4.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f3_n5.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f3_n6.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f3_n7.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f3_n8.out create mode 100644 in/results/2014-09-25_noreorder/mutex_MT_f3_n9.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f1_n10.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f1_n11.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f1_n12.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f1_n13.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f1_n2.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f1_n3.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f1_n4.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f1_n5.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f1_n6.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f1_n7.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f1_n8.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f1_n9.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f2_n10.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f2_n11.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f2_n12.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f2_n13.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f2_n14.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f2_n2.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f2_n3.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f2_n4.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f2_n5.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f2_n6.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f2_n7.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f2_n8.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f2_n9.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f3_n10.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f3_n11.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f3_n12.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f3_n13.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f3_n2.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f3_n3.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f3_n4.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f3_n5.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f3_n6.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f3_n7.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f3_n8.out create mode 100644 in/results/2014-09-25_noreorder/mutex_PT_f3_n9.out create mode 100644 in/results/2014-09-25_noreorder/mutex_f1.dat create mode 100644 in/results/2014-09-25_noreorder/mutex_f1_pt.dat create mode 100644 in/results/2014-09-25_noreorder/mutex_f2.dat create mode 100644 in/results/2014-09-25_noreorder/mutex_f2_pt.dat create mode 100644 in/results/2014-09-25_noreorder/mutex_f3.dat create mode 100644 in/results/2014-09-25_noreorder/mutex_f3_pt.dat create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n10.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n11.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n12.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n13.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n14.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n15.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n16.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n17.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n18.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n19.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n2.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n20.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n21.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n22.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n23.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n24.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n25.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n26.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n27.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n28.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n29.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n3.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n30.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n31.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n32.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n33.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n34.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n35.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n36.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n37.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n38.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n39.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n4.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n40.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n5.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n6.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n7.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n8.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v1_f0_n9.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v2_f0_n10.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v2_f0_n11.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v2_f0_n12.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v2_f0_n2.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v2_f0_n3.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v2_f0_n4.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v2_f0_n5.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v2_f0_n6.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v2_f0_n7.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v2_f0_n8.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_MT_v2_f0_n9.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n10.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n11.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n12.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n13.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n14.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n15.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n16.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n17.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n18.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n19.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n2.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n20.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n21.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n22.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n23.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n24.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n25.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n26.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n27.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n28.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n29.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n3.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n30.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n31.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n32.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n33.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n34.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n35.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n36.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n37.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n38.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n39.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n4.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n40.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n5.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n6.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n7.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n8.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v1_f0_n9.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v2_f0_n10.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v2_f0_n11.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v2_f0_n12.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v2_f0_n2.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v2_f0_n3.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v2_f0_n4.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v2_f0_n5.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v2_f0_n6.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v2_f0_n7.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v2_f0_n8.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_PT_v2_f0_n9.out create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_v1_f0.dat create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_v1_f0_pt.dat create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_v2_f0.dat create mode 100644 in/results/2014-09-25_noreorder/pipe_abs_v2_f0_pt.dat create mode 100644 in/results/2014-09-25_noreorder/summary_bc_MT_f1 create mode 100644 in/results/2014-09-25_noreorder/summary_bc_MT_f2 create mode 100644 in/results/2014-09-25_noreorder/summary_bc_MT_f3 create mode 100644 in/results/2014-09-25_noreorder/summary_bc_MT_f4 create mode 100644 in/results/2014-09-25_noreorder/summary_bc_PT_f1 create mode 100644 in/results/2014-09-25_noreorder/summary_bc_PT_f2 create mode 100644 in/results/2014-09-25_noreorder/summary_bc_PT_f3 create mode 100644 in/results/2014-09-25_noreorder/summary_bc_PT_f4 create mode 100644 in/results/2014-09-25_noreorder/summary_mutex_MT_f1 create mode 100644 in/results/2014-09-25_noreorder/summary_mutex_MT_f2 create mode 100644 in/results/2014-09-25_noreorder/summary_mutex_MT_f3 create mode 100644 in/results/2014-09-25_noreorder/summary_mutex_PT_f1 create mode 100644 in/results/2014-09-25_noreorder/summary_mutex_PT_f2 create mode 100644 in/results/2014-09-25_noreorder/summary_mutex_PT_f3 create mode 100644 in/results/2014-09-25_noreorder/summary_pipe_abs_MT_v1_f0 create mode 100644 in/results/2014-09-25_noreorder/summary_pipe_abs_MT_v2_f0 create mode 100644 in/results/2014-09-25_noreorder/summary_pipe_abs_PT_v1_f0 create mode 100644 in/results/2014-09-25_noreorder/summary_pipe_abs_PT_v2_f0 create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n1.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n10.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n11.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n12.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n13.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n14.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n15.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n16.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n17.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n18.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n19.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n2.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n20.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n21.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n22.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n23.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n24.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n25.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n3.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n4.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n5.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n6.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n7.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n8.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f1_n9.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n1.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n10.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n11.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n12.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n13.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n14.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n15.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n16.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n17.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n18.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n19.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n2.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n20.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n21.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n22.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n23.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n24.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n25.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n3.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n4.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n5.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n6.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n7.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n8.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f2_n9.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f3_n10.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f3_n11.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f3_n12.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f3_n13.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f3_n14.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f3_n15.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f3_n16.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f3_n17.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f3_n18.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f3_n19.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f3_n20.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f3_n21.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f3_n22.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f3_n23.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f3_n24.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f3_n25.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f3_n9.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n1.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n10.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n11.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n12.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n13.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n14.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n15.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n16.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n17.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n18.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n19.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n2.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n20.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n21.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n22.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n23.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n24.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n25.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n3.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n4.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n5.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n6.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n7.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n8.out create mode 100644 in/results/2014-09-25_reorder/bc_MT_f4_n9.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n1.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n10.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n11.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n12.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n13.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n14.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n15.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n16.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n17.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n18.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n19.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n2.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n20.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n21.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n22.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n3.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n4.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n5.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n6.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n7.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n8.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f1_n9.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n1.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n10.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n11.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n12.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n13.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n14.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n15.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n16.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n17.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n18.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n19.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n2.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n20.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n21.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n22.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n23.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n24.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n3.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n4.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n5.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n6.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n7.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n8.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f2_n9.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f3_n10.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f3_n11.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f3_n12.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f3_n13.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f3_n14.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f3_n15.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f3_n16.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f3_n17.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f3_n18.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f3_n19.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f3_n20.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f3_n21.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f3_n22.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f3_n23.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f3_n24.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f3_n25.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f3_n9.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n1.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n10.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n11.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n12.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n13.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n14.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n15.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n16.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n17.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n18.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n19.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n2.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n20.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n21.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n22.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n23.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n24.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n3.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n4.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n5.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n6.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n7.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n8.out create mode 100644 in/results/2014-09-25_reorder/bc_PT_f4_n9.out create mode 100644 in/results/2014-09-25_reorder/bc_f1.dat create mode 100644 in/results/2014-09-25_reorder/bc_f1_pt.dat create mode 100644 in/results/2014-09-25_reorder/bc_f2.dat create mode 100644 in/results/2014-09-25_reorder/bc_f2_pt.dat create mode 100644 in/results/2014-09-25_reorder/bc_f3.dat create mode 100644 in/results/2014-09-25_reorder/bc_f3_pt.dat create mode 100644 in/results/2014-09-25_reorder/bc_f4.dat create mode 100644 in/results/2014-09-25_reorder/bc_f4_pt.dat create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n10.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n11.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n12.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n13.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n14.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n15.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n16.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n17.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n18.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n19.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n2.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n20.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n21.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n22.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n23.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n3.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n4.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n5.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n6.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n7.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n8.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f1_n9.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n10.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n11.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n12.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n13.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n14.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n15.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n16.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n17.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n18.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n19.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n2.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n20.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n21.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n22.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n23.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n3.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n4.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n5.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n6.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n7.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n8.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f2_n9.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n10.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n11.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n12.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n13.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n14.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n15.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n16.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n17.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n18.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n19.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n2.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n20.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n21.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n22.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n23.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n3.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n4.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n5.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n6.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n7.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n8.out create mode 100644 in/results/2014-09-25_reorder/mutex_MT_f3_n9.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f1_n10.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f1_n11.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f1_n12.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f1_n2.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f1_n3.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f1_n4.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f1_n5.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f1_n6.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f1_n7.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f1_n8.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f1_n9.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f2_n10.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f2_n11.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f2_n12.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f2_n13.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f2_n14.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f2_n15.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f2_n16.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f2_n2.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f2_n3.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f2_n4.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f2_n5.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f2_n6.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f2_n7.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f2_n8.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f2_n9.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f3_n10.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f3_n11.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f3_n12.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f3_n2.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f3_n3.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f3_n4.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f3_n5.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f3_n6.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f3_n7.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f3_n8.out create mode 100644 in/results/2014-09-25_reorder/mutex_PT_f3_n9.out create mode 100644 in/results/2014-09-25_reorder/mutex_f1.dat create mode 100644 in/results/2014-09-25_reorder/mutex_f1_pt.dat create mode 100644 in/results/2014-09-25_reorder/mutex_f2.dat create mode 100644 in/results/2014-09-25_reorder/mutex_f2_pt.dat create mode 100644 in/results/2014-09-25_reorder/mutex_f3.dat create mode 100644 in/results/2014-09-25_reorder/mutex_f3_pt.dat create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n10.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n11.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n12.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n13.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n14.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n15.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n16.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n17.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n18.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n19.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n2.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n20.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n21.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n22.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n23.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n24.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n25.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n26.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n27.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n28.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n29.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n3.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n30.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n31.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n32.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n33.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n34.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n35.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n36.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n37.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n38.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n39.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n4.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n40.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n5.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n6.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n7.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n8.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v1_f0_n9.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v2_f0_n10.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v2_f0_n11.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v2_f0_n12.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v2_f0_n2.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v2_f0_n3.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v2_f0_n4.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v2_f0_n5.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v2_f0_n6.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v2_f0_n7.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v2_f0_n8.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_MT_v2_f0_n9.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n10.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n11.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n12.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n13.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n14.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n15.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n16.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n17.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n18.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n19.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n2.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n20.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n21.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n22.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n23.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n24.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n25.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n26.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n27.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n28.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n29.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n3.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n30.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n31.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n32.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n33.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n34.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n35.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n36.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n37.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n38.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n39.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n4.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n40.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n5.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n6.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n7.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n8.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v1_f0_n9.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v2_f0_n10.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v2_f0_n11.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v2_f0_n12.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v2_f0_n2.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v2_f0_n3.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v2_f0_n4.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v2_f0_n5.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v2_f0_n6.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v2_f0_n7.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v2_f0_n8.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_PT_v2_f0_n9.out create mode 100644 in/results/2014-09-25_reorder/pipe_abs_v1_f0.dat create mode 100644 in/results/2014-09-25_reorder/pipe_abs_v1_f0_pt.dat create mode 100644 in/results/2014-09-25_reorder/pipe_abs_v2_f0.dat create mode 100644 in/results/2014-09-25_reorder/pipe_abs_v2_f0_pt.dat create mode 100644 in/results/2014-09-25_reorder/summary_bc_MT_f1 create mode 100644 in/results/2014-09-25_reorder/summary_bc_MT_f2 create mode 100644 in/results/2014-09-25_reorder/summary_bc_MT_f3 create mode 100644 in/results/2014-09-25_reorder/summary_bc_MT_f4 create mode 100644 in/results/2014-09-25_reorder/summary_bc_PT_f1 create mode 100644 in/results/2014-09-25_reorder/summary_bc_PT_f2 create mode 100644 in/results/2014-09-25_reorder/summary_bc_PT_f3 create mode 100644 in/results/2014-09-25_reorder/summary_bc_PT_f4 create mode 100644 in/results/2014-09-25_reorder/summary_mutex_MT_f1 create mode 100644 in/results/2014-09-25_reorder/summary_mutex_MT_f2 create mode 100644 in/results/2014-09-25_reorder/summary_mutex_MT_f3 create mode 100644 in/results/2014-09-25_reorder/summary_mutex_PT_f1 create mode 100644 in/results/2014-09-25_reorder/summary_mutex_PT_f2 create mode 100644 in/results/2014-09-25_reorder/summary_mutex_PT_f3 create mode 100644 in/results/2014-09-25_reorder/summary_pipe_abs_MT_v1_f0 create mode 100644 in/results/2014-09-25_reorder/summary_pipe_abs_MT_v2_f0 create mode 100644 in/results/2014-09-25_reorder/summary_pipe_abs_PT_v1_f0 create mode 100644 in/results/2014-09-25_reorder/summary_pipe_abs_PT_v2_f0 create mode 100644 in/results_old/10.out create mode 100644 in/results_old/12.out create mode 100644 in/results_old/14.out create mode 100644 in/results_old/16.out create mode 100644 in/results_old/18.out create mode 100644 in/results_old/20.out create mode 100644 in/results_old/22.out create mode 100644 in/results_old/24.out create mode 100644 in/results_old/26.out create mode 100644 in/results_old/28.out create mode 100644 in/results_old/30.out create mode 100644 in/results_old/32.out create mode 100644 in/results_old/34.out create mode 100644 in/results_old/36.out create mode 100644 in/results_old/38.out create mode 100644 in/results_old/40.out create mode 100644 in/results_old/42.out create mode 100644 in/results_old/44.out create mode 100644 in/results_old/46.out create mode 100644 in/results_old/48.out create mode 100644 in/results_old/50.out create mode 100644 in/results_old/52.out create mode 100644 in/results_old/8.out create mode 100644 macro.hh create mode 100644 main.cc create mode 100644 main.hh create mode 100644 mc.cc create mode 100644 mc.hh create mode 100644 memtime.hh create mode 100644 options.cc create mode 100644 options.hh create mode 100644 rs.cc create mode 100644 rs.hh create mode 100644 rsin_driver.cc create mode 100644 rsin_driver.hh create mode 100644 rsin_parser.ll create mode 100644 rsin_parser.yy create mode 100644 rsmc-1.0a_linux_ubuntu/USAGE create mode 100644 rsmc-1.0a_linux_ubuntu/examples/abs_10_V1.rs create mode 100644 rsmc-1.0a_linux_ubuntu/examples/abs_10_V2.rs create mode 100644 rsmc-1.0a_linux_ubuntu/examples/abs_5_V1.rs create mode 100644 rsmc-1.0a_linux_ubuntu/examples/abs_5_V2.rs create mode 100644 rsmc-1.0a_linux_ubuntu/examples/bc_16_P1.rs create mode 100644 rsmc-1.0a_linux_ubuntu/examples/bc_16_P2.rs create mode 100644 rsmc-1.0a_linux_ubuntu/examples/bc_16_P3.rs create mode 100644 rsmc-1.0a_linux_ubuntu/examples/bc_16_P4.rs create mode 100644 rsmc-1.0a_linux_ubuntu/examples/generators/gen_abstract1.py create mode 100755 rsmc-1.0a_linux_ubuntu/examples/generators/gen_bc.py create mode 100755 rsmc-1.0a_linux_ubuntu/examples/generators/gen_mutex.py create mode 100644 rsmc-1.0a_linux_ubuntu/examples/hsr.rs create mode 100644 rsmc-1.0a_linux_ubuntu/examples/mutex_10_P1.rs create mode 100644 rsmc-1.0a_linux_ubuntu/examples/mutex_10_P2.rs create mode 100644 rsmc-1.0a_linux_ubuntu/examples/mutex_10_P3.rs create mode 100644 rsmc-1.0a_linux_ubuntu/examples/mutex_6_P1.rs create mode 100644 rsmc-1.0a_linux_ubuntu/examples/mutex_6_P2.rs create mode 100644 rsmc-1.0a_linux_ubuntu/examples/mutex_6_P3.rs create mode 100755 rsmc-1.0a_linux_ubuntu/rsmc create mode 100644 rsmc-1.0a_macosx.tgz create mode 100644 rsmc-1.0a_macosx/USAGE create mode 100644 rsmc-1.0a_macosx/examples/abs_10_V1.rs create mode 100644 rsmc-1.0a_macosx/examples/abs_10_V2.rs create mode 100644 rsmc-1.0a_macosx/examples/abs_5_V1.rs create mode 100644 rsmc-1.0a_macosx/examples/abs_5_V2.rs create mode 100644 rsmc-1.0a_macosx/examples/bc_16_P1.rs create mode 100644 rsmc-1.0a_macosx/examples/bc_16_P2.rs create mode 100644 rsmc-1.0a_macosx/examples/bc_16_P3.rs create mode 100644 rsmc-1.0a_macosx/examples/bc_16_P4.rs create mode 100644 rsmc-1.0a_macosx/examples/generators/gen_abstract1.py create mode 100755 rsmc-1.0a_macosx/examples/generators/gen_bc.py create mode 100755 rsmc-1.0a_macosx/examples/generators/gen_mutex.py create mode 100644 rsmc-1.0a_macosx/examples/hsr.rs create mode 100644 rsmc-1.0a_macosx/examples/mutex_10_P1.rs create mode 100644 rsmc-1.0a_macosx/examples/mutex_10_P2.rs create mode 100644 rsmc-1.0a_macosx/examples/mutex_10_P3.rs create mode 100644 rsmc-1.0a_macosx/examples/mutex_6_P1.rs create mode 100644 rsmc-1.0a_macosx/examples/mutex_6_P2.rs create mode 100644 rsmc-1.0a_macosx/examples/mutex_6_P3.rs create mode 100755 rsmc-1.0a_macosx/rsmc create mode 100644 symrs.cc create mode 100644 symrs.hh create mode 100644 test.rs diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d5811ff --- /dev/null +++ b/Makefile @@ -0,0 +1,41 @@ +CC = g++ +CUDD_PATH = cudd +CUDD_INCLUDE = $(CUDD_PATH)/obj/cuddObj.o $(CUDD_PATH)/cudd/libcudd.a $(CUDD_PATH)/mtr/libmtr.a \ + $(CUDD_PATH)/st/libst.a $(CUDD_PATH)/util/libutil.a \ + $(CUDD_PATH)/epd/libepd.a $(CUDD_PATH)/obj/libobj.a +INCLUDES=-Icudd/include +CPPFLAGS = -Wall $(INCLUDES) #-Werror +#CPPFLAGS = -Wall -DNDEBUG +CXXFLAGS = -std=c++14 -O3 -DPUBLIC_RELEASE -DNDEBUG #-g +LDLIBS = $(CUDD_INCLUDE) #-lcuddobj #/lib64/libcudd.so.2 #$(CUDD_INCLUDE) + +OBJ = rs.o symrs.o mc.o rsin_driver.o rsin_parser.o rsin_parser.lex.o formrsctl.o + +all: main + +cleanly: + rm -f *.lex.cc *.lex.o location.hh stack.hh position.hh rsin_parser.cc rsin_parser.hh + +clean: cleanly + rm -f *.o main *~ makefile.dep tags + +cleanall: clean + +makefile.dep: *.cc *.hh + for i in *.cc; do g++ $(INCLUDES) -MM -MG "$${i}"; done > $@ + +include makefile.dep + +main: main.o $(OBJ) + +rsin_parser.hh: rsin_parser.cc + +rsin_parser.cc: rsin_parser.yy + bison -o rsin_parser.cc rsin_parser.yy + +rsin_parser.o: rsin_parser.cc + +rsin_parser.lex.cc: rsin_parser.ll + flex rsin_parser.ll + mv lex.yy.c rsin_parser.lex.cc + diff --git a/bdd_macro.hh b/bdd_macro.hh new file mode 100644 index 0000000..0751d77 --- /dev/null +++ b/bdd_macro.hh @@ -0,0 +1,8 @@ +#ifndef __BDD_MACRO_HH__ +#define __BDD_MACRO_HH__ + +#define BDD_IFF(p,q) (!(p+q)+(p*q)) +#define BDD_TRUE (cuddMgr->bddOne()) +#define BDD_FALSE (cuddMgr->bddZero()) + +#endif diff --git a/cudd.hh b/cudd.hh new file mode 100644 index 0000000..876bc10 --- /dev/null +++ b/cudd.hh @@ -0,0 +1 @@ +#include diff --git a/cudd_local/LICENSE b/cudd_local/LICENSE new file mode 100644 index 0000000..99c7fba --- /dev/null +++ b/cudd_local/LICENSE @@ -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/cudd_local/Makefile b/cudd_local/Makefile new file mode 100644 index 0000000..3ff406d --- /dev/null +++ b/cudd_local/Makefile @@ -0,0 +1,318 @@ +# $Id$ +# +# Makefile for the CUDD distribution kit +#--------------------------------------------------------------------------- + +# Beginning of the configuration section. These symbol definitions can +# be overridden from the command line. + +# C++ compiler +CXX = g++ +#CXX = icpc +#CXX = ecpc +#CXX = CC +#CXX = /usr/local/opt/SUNWspro/bin/CC +#CXX = cxx + +# Specific options for compilation of C++ files. +CXXFLAGS = +# Stricter standard conformance for g++. +#CXXFLAGS = -std=c++98 +# For Sun CC version 5, this invokes compatibility mode. +#CXXFLAGS = -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. +#CXXFLAGS = +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 = $(CXX) + +# 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 two are typical settings for optimized code with gcc. +#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 4.2.4 or higher on i686. +#XCFLAGS = -DHAVE_IEEE_754 -DBSD +# 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/7 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=native -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) + +#------------------------------------------------------------------------ + +.PHONY : build +.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 + +check_leaks: + sh ./setup.sh + @for dir in $(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 CXX=$(CXX) CXXFLAGS=$(CXXFLAGS) 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 CXX=$(CXX) CXXFLAGS=$(CXXFLAGS) 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 $(DIRS) obj; do \ + (cd $$dir; \ + echo Cleaning $$dir ...; \ + make -s clean ) \ + done + +distclean: + @for dir in $(DIRS) obj; do \ + (cd $$dir; \ + echo Cleaning $$dir ...; \ + make -s EXE="$(EXE)" distclean ) \ + done + sh ./shutdown.sh diff --git a/cudd_local/README b/cudd_local/README new file mode 100644 index 0000000..864a416 --- /dev/null +++ b/cudd_local/README @@ -0,0 +1,177 @@ +$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 Ubuntu with gcc + PC (ia32 and ia64) running Ubuntu with g++ + PC (ia32 and ia64) running Linux RedHat with gcc + PC (ia32 and ia64) running Linux RedHat with g++ + PC (ia64) running Cygwin on Windows 7 and Vista with gcc + PC (ia64) running Cygwin on Windows 7 and Vista with g++ + +Platforms to which I have no longer access and therefore are no longer +supported. + + 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++ + 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. + +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.5.0/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/cudd_local/RELEASE.NOTES b/cudd_local/RELEASE.NOTES new file mode 100644 index 0000000..22867e5 --- /dev/null +++ b/cudd_local/RELEASE.NOTES @@ -0,0 +1,131 @@ +Release 2.5.0 of Cudd introduces the ability to set timeouts. The +function that is interrupted returns NULL (which the application must +be prepared to handle,) but the BDDs are uncorrupted and the invoking +program can continue to use the manager. + +In addition, reordering is now aware of timeouts, so that it gives up +when a timeout is approaching to give the invoking program a chance to +obtain some results. + +The response time to the timeout is not immediate, though most of the time +it is well below one second. Checking for timeouts has a small overhead. +In experiments, less than 1% has been observed on average. + +Creation of BDD managers with many variables (e.g., tens or hundreds +of thousands) is now much more efficient. Computing small supports of +BDDs when there are many variables is also much more efficient, but +this has been at the cost of separating the function for BDDs and ADDs +(Cudd_Support) from that for ZDDs (Cudd_zddSupport). + +The C++ interface has undergone a major upgrade. + +The handling of variable gruops in reordering has been much improved. +(Thanks to Arie Gurfinkel for a very detailed bug report!) A handful +of other bugs have been fixed as well. + + +New Functions: + +unsigned long Cudd_ReadStartTime(DdManager *unique); + +unsigned long Cudd_ReadElapsedTime(DdManager *unique); + +void Cudd_SetStartTime(DdManager *unique, unsigned long st); + +void Cudd_ResetStartTime(DdManager *unique); + +unsigned long Cudd_ReadTimeLimit(DdManager *unique); + +void Cudd_SetTimeLimit(DdManager *unique, unsigned long tl); + +void Cudd_UpdateTimeLimit(DdManager * unique); + +void Cudd_IncreaseTimeLimit(DdManager * unique, unsigned long increase); + +void Cudd_UnsetTimeLimit(DdManager *unique); + +int Cudd_TimeLimited(DdManager *unique); + +unsigned int Cudd_ReadMaxReorderings (DdManager *dd); + +void Cudd_SetMaxReorderings (DdManager *dd, unsigned int mr); + +unsigned int Cudd_ReadOrderRandomization(DdManager * dd); + +void Cudd_SetOrderRandomization(DdManager * dd, unsigned int factor); + +int Cudd_PrintGroupedOrder(DdManager * dd, const char *str, void *data); + +int Cudd_EnableOrderingMonitoring(DdManager *dd); + +int Cudd_DisableOrderingMonitoring(DdManager *dd); + +int Cudd_OrderingMonitoring(DdManager *dd); + +DdNode * Cudd_bddExistAbstractLimit(DdManager * manager, DdNode * f, DdNode * cube, unsigned int limit); + +DdNode * Cudd_bddIteLimit (DdManager *dd, DdNode *f, DdNode *g, DdNode *h, unsigned int limit); + +DdNode * Cudd_bddOrLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit); + +DdNode * Cudd_bddXnorLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit); + +int Cudd_CheckCube (DdManager *dd, DdNode *g); + +DdNode * Cudd_bddMaximallyExpand(DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f); + +DdNode * Cudd_bddLargestPrimeUnate(DdManager *dd , DdNode *f, DdNode *phaseBdd); + +int Cudd_Reserve(DdManager *manager, int amount); + +int Cudd_SupportIndices(DdManager * dd, DdNode * f, int **indices); + +int Cudd_VectorSupportIndices(DdManager * dd, DdNode ** F, int n, int **indices); + +DdNode * Cudd_zddSupport(DdManager * dd, DdNode * f); + + +Changed prototypes: + +unsigned int Cudd_ReadReorderings (DdManager *dd); + +---------------------------------------------------------------------- + +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/cudd_local/cudd/Makefile b/cudd_local/cudd/Makefile new file mode 100644 index 0000000..d769547 --- /dev/null +++ b/cudd_local/cudd/Makefile @@ -0,0 +1,124 @@ +# $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).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).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/cudd_local/cudd/cudd.h b/cudd_local/cudd/cudd.h new file mode 100644 index 0000000..4a54f8e --- /dev/null +++ b/cudd_local/cudd/cudd.h @@ -0,0 +1,1070 @@ +/**CHeaderFile***************************************************************** + + FileName [cudd.h] + + PackageName [cudd] + + Synopsis [The University of Colorado decision diagram package.] + + Description [External functions and data strucures of the CUDD package. + + Modified by Abelardo Pardo to interface it to VIS. + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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.180 2012/02/05 01:07: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.5.0" + +#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 + +#define CUDD_TRUE 1 +#define CUDD_FALSE 0 + +#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_TIMEOUT_EXPIRED, + 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 + +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; +}; + +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 + node 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 + node 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 + node 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. + + 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.

+ 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) : CUDD_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. +

+ 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.

+ 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) : CUDD_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. +

+ 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.

+ 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) : CUDD_TRUE;\ + (void) Cudd_NextNode(gen, &node)) + + +/**Macro*********************************************************************** + + Synopsis [Iterates over the paths of a ZDD.] + + Description [Iterates over the paths of a ZDD f. +

+ 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.

+ 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) : CUDD_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 unsigned long Cudd_ReadStartTime(DdManager *unique); +extern unsigned long Cudd_ReadElapsedTime(DdManager *unique); +extern void Cudd_SetStartTime(DdManager *unique, unsigned long st); +extern void Cudd_ResetStartTime(DdManager *unique); +extern unsigned long Cudd_ReadTimeLimit(DdManager *unique); +extern void Cudd_SetTimeLimit(DdManager *unique, unsigned long tl); +extern void Cudd_UpdateTimeLimit(DdManager * unique); +extern void Cudd_IncreaseTimeLimit(DdManager * unique, unsigned long increase); +extern void Cudd_UnsetTimeLimit(DdManager *unique); +extern int Cudd_TimeLimited(DdManager *unique); +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 unsigned int Cudd_ReadReorderings (DdManager *dd); +extern unsigned int Cudd_ReadMaxReorderings (DdManager *dd); +extern void Cudd_SetMaxReorderings (DdManager *dd, unsigned int mr); +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 int Cudd_ReadOrderRandomization(DdManager * dd); +extern void Cudd_SetOrderRandomization(DdManager * dd, unsigned int factor); +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 int Cudd_PrintGroupedOrder(DdManager * dd, const char *str, void *data); +extern int Cudd_EnableOrderingMonitoring(DdManager *dd); +extern int Cudd_DisableOrderingMonitoring(DdManager *dd); +extern int Cudd_OrderingMonitoring(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_bddExistAbstractLimit(DdManager * manager, DdNode * f, DdNode * cube, unsigned int limit); +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_bddIteLimit (DdManager *dd, DdNode *f, DdNode *g, DdNode *h, unsigned int limit); +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_bddOrLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit); +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 DdNode * Cudd_bddXnorLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit); +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 int Cudd_CheckCube (DdManager *dd, 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 *Pi, 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 DdNode * Cudd_bddMaximallyExpand(DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f); +extern DdNode * Cudd_bddLargestPrimeUnate(DdManager *dd , DdNode *f, DdNode *phaseBdd); +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_Reserve(DdManager *manager, int amount); +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 int Cudd_SupportIndices(DdManager * dd, DdNode * f, int **indices); +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 int Cudd_VectorSupportIndices(DdManager * dd, DdNode ** F, int n, int **indices); +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 DdNode * Cudd_zddSupport(DdManager * dd, DdNode * f); +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/cudd_local/cudd/cuddAPI.c b/cudd_local/cudd/cuddAPI.c new file mode 100644 index 0000000..0985cf1 --- /dev/null +++ b/cudd_local/cudd/cuddAPI.c @@ -0,0 +1,4893 @@ +/**CFile*********************************************************************** + + FileName [cuddAPI.c] + + PackageName [cudd] + + Synopsis [Application interface functions.] + + Description [External procedures included in this module: +

+ Static procedures included in this module: + ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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.64 2012/02/05 01:07:18 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 [Returns the start time of the manager.] + + Description [Returns the start time of the manager. This is initially set + to the number of milliseconds since the program started, but may be reset by + the application.] + + SideEffects [None] + + SeeAlso [Cudd_SetStartTime Cudd_ResetStartTime Cudd_ReadTimeLimit] + +******************************************************************************/ +unsigned long +Cudd_ReadStartTime( + DdManager * unique) +{ + return unique->startTime; + +} /* end of Cudd_ReadStartTime */ + + +/**Function******************************************************************** + + Synopsis [Returns the time elapsed since the start time of the manager.] + + Description [Returns the time elapsed since the start time of the manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadStartTime Cudd_SetStartTime] + +******************************************************************************/ +unsigned long +Cudd_ReadElapsedTime( + DdManager * unique) +{ + return util_cpu_time() - unique->startTime; + +} /* end of Cudd_ReadElapsedTime */ + + +/**Function******************************************************************** + + Synopsis [Sets the start time of the manager.] + + Description [Sets the start time of the manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadStartTime Cudd_ResetStartTime Cudd_ReadElapsedTime + Cudd_SetTimeLimit] + +******************************************************************************/ +void +Cudd_SetStartTime( + DdManager * unique, + unsigned long st) +{ + unique->startTime = st; + +} /* end of Cudd_SetStartTime */ + + +/**Function******************************************************************** + + Synopsis [Resets the start time of the manager.] + + Description [Resets the start time of the manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadStartTime Cudd_SetStartTime Cudd_SetTimeLimit] + +******************************************************************************/ +void +Cudd_ResetStartTime( + DdManager * unique) +{ + unique->startTime = util_cpu_time(); + +} /* end of Cudd_ResetStartTime */ + + +/**Function******************************************************************** + + Synopsis [Returns the time limit for the manager.] + + Description [Returns the time limit for the manager. This is initially set + to a very large number, but may be reset by the application.] + + SideEffects [None] + + SeeAlso [Cudd_SetTimeLimit Cudd_UpdateTimeLimit Cudd_UnsetTimeLimit + Cudd_IncreaseTimeLimit Cudd_TimeLimited Cudd_ReadStartTime] + +******************************************************************************/ +unsigned long +Cudd_ReadTimeLimit( + DdManager * unique) +{ + return unique->timeLimit; + +} /* end of Cudd_ReadTimeLimit */ + + +/**Function******************************************************************** + + Synopsis [Sets the time limit for the manager.] + + Description [Sets the time limit for the manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadTimeLimit Cudd_UnsetTimeLimit Cudd_UpdateTimeLimit + Cudd_IncreaseTimeLimit Cudd_TimeLimited Cudd_SetStartTime] + +******************************************************************************/ +void +Cudd_SetTimeLimit( + DdManager * unique, + unsigned long tl) +{ + unique->timeLimit = tl; + +} /* end of Cudd_SetTimeLimit */ + + +/**Function******************************************************************** + + Synopsis [Updates the time limit for the manager.] + + Description [Updates the time limit for the manager by subtracting the + elapsed time from it.] + + SideEffects [None] + + SeeAlso [Cudd_ReadTimeLimit Cudd_SetTimeLimit Cudd_UnsetTimeLimit + Cudd_IncreaseTimeLimit Cudd_TimeLimited Cudd_SetStartTime] + +******************************************************************************/ +void +Cudd_UpdateTimeLimit( + DdManager * unique) +{ + unsigned long elapsed; + if (unique->timeLimit == ~0UL) + return; + elapsed = util_cpu_time() - unique->startTime; + if (unique->timeLimit >= elapsed) { + unique->timeLimit -= elapsed; + } else { + unique->timeLimit = 0; + } + +} /* end of Cudd_UpdateTimeLimit */ + + +/**Function******************************************************************** + + Synopsis [Increases the time limit for the manager.] + + Description [Increases the time limit for the manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadTimeLimit Cudd_SetTimeLimit Cudd_UnsetTimeLimit + Cudd_UpdateTimeLimit Cudd_TimeLimited Cudd_SetStartTime] + +******************************************************************************/ +void +Cudd_IncreaseTimeLimit( + DdManager * unique, + unsigned long increase) +{ + if (unique->timeLimit == ~0UL) + unique->timeLimit = increase; + else + unique->timeLimit += increase; + +} /* end of Cudd_IncreaseTimeLimit */ + + +/**Function******************************************************************** + + Synopsis [Unsets the time limit for the manager.] + + Description [Unsets the time limit for the manager. Actually, sets it to + a very large value.] + + SideEffects [None] + + SeeAlso [Cudd_ReadTimeLimit Cudd_SetTimeLimit Cudd_UpdateTimeLimit + Cudd_IncreaseTimeLimit Cudd_TimeLimited Cudd_SetStartTime] + +******************************************************************************/ +void +Cudd_UnsetTimeLimit( + DdManager * unique) +{ + unique->timeLimit = ~0UL; + +} /* end of Cudd_UnsetTimeLimit */ + + +/**Function******************************************************************** + + Synopsis [Returns true if the time limit for the manager is set.] + + Description [Returns true if the time limit for the manager is set.] + + SideEffects [None] + + SeeAlso [Cudd_ReadTimeLimit Cudd_SetTimeLimit Cudd_UpdateTimeLimit + Cudd_UnsetTimeLimit Cudd_IncreaseTimeLimit] + +******************************************************************************/ +int +Cudd_TimeLimited( + DdManager * unique) +{ + return unique->timeLimit != ~0UL; + +} /* end of Cudd_TimeLimited */ + + +/**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 M be the + ratio of the two numbers. For the purpose of realignment, the ZDD + variables from M*i to (M+1)*i-1 are + reagarded as corresponding to BDD variable i. 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 M be the + ratio of the two numbers. For the purpose of realignment, the ZDD + variables from M*i to (M+1)*i-1 are + reagarded as corresponding to BDD variable i. 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 i.] + + 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.] + + SideEffects [None] + + SeeAlso [Cudd_ReadMaxCacheHard] + +******************************************************************************/ +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] + +******************************************************************************/ +unsigned int +Cudd_ReadReorderings( + DdManager * dd) +{ + return(dd->reorderings); + +} /* end of Cudd_ReadReorderings */ + + +/**Function******************************************************************** + + Synopsis [Returns the maximum number of times reordering may be invoked.] + + Description [Returns the maximum number of times reordering may be invoked in + this manager.] + + SideEffects [None] + + SeeAlso [Cudd_ReadReorderings Cudd_SetMaxReorderings Cudd_ReduceHeap] + +******************************************************************************/ +unsigned int +Cudd_ReadMaxReorderings( + DdManager * dd) +{ + return(dd->maxReorderings); + +} /* end of Cudd_ReadMaxReorderings */ + + +/**Function******************************************************************** + + Synopsis [Sets the maximum number of times reordering may be invoked.] + + Description [Sets the maximum number of times reordering may be invoked in + this manager. The default value is (practically) infinite.] + + SideEffects [None] + + SeeAlso [Cudd_ReadReorderings Cudd_ReadMaxReorderings Cudd_ReduceHeap] + +******************************************************************************/ +void +Cudd_SetMaxReorderings( + DdManager * dd, unsigned int mr) +{ + dd->maxReorderings = mr; + +} /* end of Cudd_SetMaxReorderings */ + + +/**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 f10 = f01 or + f11 = f00 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 f10 = f01 or + f11 = f00 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 y not coming from x 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 y not coming from x 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 order randomization factor.] + + Description [Returns the order randomization factor. If non-zero this + factor is used to determine a perturbation of the next reordering threshold. + Larger factors cause larger perturbations.] + + SideEffects [None] + + SeeAlso [Cudd_SetOrderRandomization] + +******************************************************************************/ +unsigned int +Cudd_ReadOrderRandomization( + DdManager * dd) +{ + return(dd->randomizeOrder); + +} /* end of Cudd_ReadOrderRandomization */ + + +/**Function******************************************************************** + + Synopsis [Sets the order randomization factor.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_ReadOrderRandomization] + +******************************************************************************/ +void +Cudd_SetOrderRandomization( + DdManager * dd, + unsigned int factor) +{ + dd->randomizeOrder = factor; + +} /* end of Cudd_SetOrderRandomization */ + + +/**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.] + + 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) +{ + unsigned long initialTime = (long) data; + int retval; + unsigned 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 [Hook function to print the current variable order.] + + Description [Hook function to print the current variable order. It may be + called before or after reordering. Prints on the manager's stdout a + parenthesized list that describes the variable groups. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_StdPreReordHook] + +******************************************************************************/ +int +Cudd_PrintGroupedOrder( + DdManager * dd, + const char *str, + void *data) +{ + int isBdd = strcmp(str, "ZDD"); + MtrNode *tree = isBdd ? dd->tree : dd->treeZ; + int *invperm = isBdd ? dd->invperm : dd->invpermZ; + int size = isBdd ? dd->size : dd->sizeZ; + if (tree == NULL) { + int i, retval; + for (i=0; i < size; i++) { + retval = fprintf(dd->out, "%c%d", i==0 ? '(' : ',', invperm[i]); + if (retval == EOF) return(0); + } + retval = fprintf(dd->out,")\n"); + return (retval != EOF); + } else { + return Mtr_PrintGroupedOrder(tree,invperm,dd->out); + } + +} /* end of Cudd_PrintGroupedOrder */ + + +/**Function******************************************************************** + + Synopsis [Enables monitoring of ordering.] + + Description [Enables monitoring of ordering. + Returns 1 if successful; 0 otherwise.] + + SideEffects [Installs functions in the pre-reordering and post-reordering + hooks.] + + SeeAlso [Cudd_EnableReorderingReporting] + +******************************************************************************/ +int +Cudd_EnableOrderingMonitoring( + DdManager *dd) +{ + if (!Cudd_AddHook(dd, Cudd_PrintGroupedOrder, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_AddHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_AddHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_AddHook(dd, Cudd_PrintGroupedOrder, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + return(1); + +} /* end of Cudd_EnableOrderingMonitoring */ + + +/**Function******************************************************************** + + Synopsis [Disables monitoring of ordering.] + + Description [Disables monitoring of ordering. + Returns 1 if successful; 0 otherwise.] + + SideEffects [Removes functions from the pre-reordering and post-reordering + hooks.] + + SeeAlso [Cudd_EnableOrderingMonitoring] + +******************************************************************************/ +int +Cudd_DisableOrderingMonitoring( + DdManager *dd) +{ + if (!Cudd_RemoveHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_RemoveHook(dd, Cudd_PrintGroupedOrder, CUDD_PRE_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_RemoveHook(dd, Cudd_PrintGroupedOrder, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + if (!Cudd_RemoveHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) { + return(0); + } + return(1); + +} /* end of Cudd_DisableOrderingMonitoring */ + + +/**Function******************************************************************** + + Synopsis [Returns 1 if monitoring of ordering is enabled.] + + Description [Returns 1 if monitoring of ordering is enabled; + 0 otherwise.] + + SideEffects [none] + + SeeAlso [Cudd_EnableOrderingMonitoring Cudd_DisableOrderingMonitoring] + +******************************************************************************/ +int +Cudd_OrderingMonitoring( + DdManager *dd) +{ + return(Cudd_IsInHook(dd, Cudd_PrintGroupedOrder, CUDD_PRE_REORDERING_HOOK)); + +} /* end of Cudd_OrderingMonitoring */ + + +/**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/cudd_local/cudd/cuddAddAbs.c b/cudd_local/cudd/cuddAddAbs.c new file mode 100644 index 0000000..5e809c1 --- /dev/null +++ b/cudd_local/cudd/cuddAddAbs.c @@ -0,0 +1,579 @@ +/**CFile*********************************************************************** + + FileName [cuddAddAbs.c] + + PackageName [cudd] + + Synopsis [Quantification functions for ADDs.] + + Description [External procedures included in this module: + + Internal procedures included in this module: + + Static procedures included in this module: + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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.16 2012/02/05 01:07:18 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/cudd_local/cudd/cuddAddApply.c b/cudd_local/cudd/cuddAddApply.c new file mode 100644 index 0000000..4ef228a --- /dev/null +++ b/cudd_local/cudd/cuddAddApply.c @@ -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: + + Internal procedures included in this module: + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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.19 2012/02/05 01:07:18 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>=g; 0 if f<g.] + + Description [Threshold operator for Apply (f if f >=g; 0 if f<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 > g and 0 otherwise.] + + Description [Returns 1 if f > 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] + + SeeAlso [cuddAddMonadicApplyRecur] + +******************************************************************************/ +DdNode * +cuddAddApplyRecur( + DdManager * dd, + DD_AOP op, + DdNode * f, + DdNode * g) +{ + DdNode *res, + *fv, *fvn, *gv, *gvn, + *T, *E; + unsigned int ford, gord; + unsigned int index; + DD_CTFP cacheOp; + + /* Check terminal cases. Op may swap f and g to increase the + * cache hit rate. + */ + statLine(dd); + res = (*op)(dd,&f,&g); + if (res != NULL) return(res); + + /* Check cache. */ + cacheOp = (DD_CTFP) op; + res = cuddCacheLookup2(dd,cacheOp,f,g); + if (res != NULL) return(res); + + /* Recursive step. */ + ford = cuddI(dd,f->index); + gord = cuddI(dd,g->index); + if (ford <= gord) { + index = f->index; + fv = cuddT(f); + fvn = cuddE(f); + } else { + index = g->index; + fv = fvn = f; + } + if (gord <= ford) { + gv = cuddT(g); + gvn = cuddE(g); + } else { + gv = gvn = g; + } + + T = cuddAddApplyRecur(dd,op,fv,gv); + if (T == NULL) return(NULL); + cuddRef(T); + + E = cuddAddApplyRecur(dd,op,fvn,gvn); + if (E == NULL) { + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + + res = (T == E) ? T : cuddUniqueInter(dd,(int)index,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert2(dd,cacheOp,f,g,res); + + return(res); + +} /* end of cuddAddApplyRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addMonadicApply.] + + Description [Performs the recursive step of Cudd_addMonadicApply. Returns a + pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddAddApplyRecur] + +******************************************************************************/ +DdNode * +cuddAddMonadicApplyRecur( + DdManager * dd, + DD_MAOP op, + DdNode * f) +{ + DdNode *res, *ft, *fe, *T, *E; + unsigned int index; + + /* Check terminal cases. */ + statLine(dd); + res = (*op)(dd,f); + if (res != NULL) return(res); + + /* Check cache. */ + res = cuddCacheLookup1(dd,op,f); + if (res != NULL) return(res); + + /* Recursive step. */ + index = f->index; + ft = cuddT(f); + fe = cuddE(f); + + T = cuddAddMonadicApplyRecur(dd,op,ft); + if (T == NULL) return(NULL); + cuddRef(T); + + E = cuddAddMonadicApplyRecur(dd,op,fe); + if (E == NULL) { + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + + res = (T == E) ? T : cuddUniqueInter(dd,(int)index,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert1(dd,op,f,res); + + return(res); + +} /* end of cuddAddMonadicApplyRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/cudd_local/cudd/cuddAddFind.c b/cudd_local/cudd/cuddAddFind.c new file mode 100644 index 0000000..1352a87 --- /dev/null +++ b/cudd_local/cudd/cuddAddFind.c @@ -0,0 +1,316 @@ +/**CFile*********************************************************************** + + FileName [cuddAddFind.c] + + PackageName [cudd] + + Synopsis [Functions to find maximum and minimum in an ADD and to + extract the i-th bit.] + + Description [External procedures included in this module: + + Static functions included in this module: + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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: cuddAddFind.c,v 1.9 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * addDoIthBit (DdManager *dd, DdNode *f, DdNode *index); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Finds the maximum discriminant of f.] + + Description [Returns a pointer to a constant ADD.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_addFindMax( + DdManager * dd, + DdNode * f) +{ + DdNode *t, *e, *res; + + statLine(dd); + if (cuddIsConstant(f)) { + return(f); + } + + res = cuddCacheLookup1(dd,Cudd_addFindMax,f); + if (res != NULL) { + return(res); + } + + t = Cudd_addFindMax(dd,cuddT(f)); + if (t == DD_PLUS_INFINITY(dd)) return(t); + + e = Cudd_addFindMax(dd,cuddE(f)); + + res = (cuddV(t) >= cuddV(e)) ? t : e; + + cuddCacheInsert1(dd,Cudd_addFindMax,f,res); + + return(res); + +} /* end of Cudd_addFindMax */ + + +/**Function******************************************************************** + + Synopsis [Finds the minimum discriminant of f.] + + Description [Returns a pointer to a constant ADD.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_addFindMin( + DdManager * dd, + DdNode * f) +{ + DdNode *t, *e, *res; + + statLine(dd); + if (cuddIsConstant(f)) { + return(f); + } + + res = cuddCacheLookup1(dd,Cudd_addFindMin,f); + if (res != NULL) { + return(res); + } + + t = Cudd_addFindMin(dd,cuddT(f)); + if (t == DD_MINUS_INFINITY(dd)) return(t); + + e = Cudd_addFindMin(dd,cuddE(f)); + + res = (cuddV(t) <= cuddV(e)) ? t : e; + + cuddCacheInsert1(dd,Cudd_addFindMin,f,res); + + return(res); + +} /* end of Cudd_addFindMin */ + + +/**Function******************************************************************** + + Synopsis [Extracts the i-th bit from an ADD.] + + Description [Produces an ADD from another ADD by replacing all + discriminants whose i-th bit is equal to 1 with 1, and all other + discriminants with 0. The i-th bit refers to the integer + representation of the leaf value. If the value is has a fractional + part, it is ignored. Repeated calls to this procedure allow one to + transform an integer-valued ADD into an array of ADDs, one for each + bit of the leaf values. Returns a pointer to the resulting ADD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddIthBit] + +******************************************************************************/ +DdNode * +Cudd_addIthBit( + DdManager * dd, + DdNode * f, + int bit) +{ + DdNode *res; + DdNode *index; + + /* Use a constant node to remember the bit, so that we can use the + ** global cache. + */ + index = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) bit); + if (index == NULL) return(NULL); + cuddRef(index); + + do { + dd->reordered = 0; + res = addDoIthBit(dd, f, index); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd, index); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, index); + cuddDeref(res); + return(res); + +} /* end of Cudd_addIthBit */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addIthBit.] + + Description [Performs the recursive step for Cudd_addIthBit. + Returns a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +addDoIthBit( + DdManager * dd, + DdNode * f, + DdNode * index) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int mask, value; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + mask = 1 << ((int) cuddV(index)); + value = (int) cuddV(f); + return((value & mask) == 0 ? DD_ZERO(dd) : DD_ONE(dd)); + } + + /* Check cache. */ + res = cuddCacheLookup2(dd,addDoIthBit,f,index); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = addDoIthBit(dd,fv,index); + if (T == NULL) return(NULL); + cuddRef(T); + + E = addDoIthBit(dd,fvn,index); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert2(dd,addDoIthBit,f,index,res); + + return(res); + +} /* end of addDoIthBit */ + diff --git a/cudd_local/cudd/cuddAddInv.c b/cudd_local/cudd/cuddAddInv.c new file mode 100644 index 0000000..454aa81 --- /dev/null +++ b/cudd_local/cudd/cuddAddInv.c @@ -0,0 +1,201 @@ +/**CFile*********************************************************************** + + FileName [cuddAddInv.c] + + PackageName [cudd] + + Synopsis [Function to compute the scalar inverse of an ADD.] + + Description [External procedures included in this module: + + Internal procedures included in this module: + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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: cuddAddInv.c,v 1.10 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the scalar inverse of an ADD.] + + Description [Computes an n ADD where the discriminants are the + multiplicative inverses of the corresponding discriminants of the + argument ADD. Returns a pointer to the resulting ADD in case of + success. Returns NULL if any discriminants smaller than epsilon is + encountered.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_addScalarInverse( + DdManager * dd, + DdNode * f, + DdNode * epsilon) +{ + DdNode *res; + + if (!cuddIsConstant(epsilon)) { + (void) fprintf(dd->err,"Invalid epsilon\n"); + return(NULL); + } + do { + dd->reordered = 0; + res = cuddAddScalarInverseRecur(dd,f,epsilon); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addScalarInverse */ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of addScalarInverse.] + + Description [Returns a pointer to the resulting ADD in case of + success. Returns NULL if any discriminants smaller than epsilon is + encountered.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +cuddAddScalarInverseRecur( + DdManager * dd, + DdNode * f, + DdNode * epsilon) +{ + DdNode *t, *e, *res; + CUDD_VALUE_TYPE value; + + statLine(dd); + if (cuddIsConstant(f)) { + if (ddAbs(cuddV(f)) < cuddV(epsilon)) return(NULL); + value = 1.0 / cuddV(f); + res = cuddUniqueConst(dd,value); + return(res); + } + + res = cuddCacheLookup2(dd,Cudd_addScalarInverse,f,epsilon); + if (res != NULL) return(res); + + t = cuddAddScalarInverseRecur(dd,cuddT(f),epsilon); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddAddScalarInverseRecur(dd,cuddE(f),epsilon); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + res = (t == e) ? t : cuddUniqueInter(dd,(int)f->index,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert2(dd,Cudd_addScalarInverse,f,epsilon,res); + + return(res); + +} /* end of cuddAddScalarInverseRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/cudd_local/cudd/cuddAddIte.c b/cudd_local/cudd/cuddAddIte.c new file mode 100644 index 0000000..a6e84c5 --- /dev/null +++ b/cudd_local/cudd/cuddAddIte.c @@ -0,0 +1,639 @@ +/**CFile*********************************************************************** + + FileName [cuddAddIte.c] + + PackageName [cudd] + + Synopsis [ADD ITE function and satellites.] + + Description [External procedures included in this module: + + Internal procedures included in this module: + + Static procedures included in this module: + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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: cuddAddIte.c,v 1.16 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void addVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *one, DdNode *zero); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements ITE(f,g,h).] + + Description [Implements ITE(f,g,h). This procedure assumes that f is + a 0-1 ADD. Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addIteConstant Cudd_addApply] + +******************************************************************************/ +DdNode * +Cudd_addIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddIteRecur(dd,f,g,h); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addIte */ + + +/**Function******************************************************************** + + Synopsis [Implements ITEconstant for ADDs.] + + Description [Implements ITEconstant for ADDs. f must be a 0-1 ADD. + Returns a pointer to the resulting ADD (which may or may not be + constant) or DD_NON_CONSTANT. No new nodes are created. This function + can be used, for instance, to check that g has a constant value + (specified by h) whenever f is 1. If the constant value is unknown, + then one should use Cudd_addEvalConst.] + + SideEffects [None] + + SeeAlso [Cudd_addIte Cudd_addEvalConst Cudd_bddIteConstant] + +******************************************************************************/ +DdNode * +Cudd_addIteConstant( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *one,*zero; + DdNode *Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*r,*t,*e; + unsigned int topf,topg,toph,v; + + statLine(dd); + /* Trivial cases. */ + if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */ + return(g); + } + if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ + return(h); + } + + /* From now on, f is known not to be a constant. */ + addVarToConst(f,&g,&h,one,zero); + + /* Check remaining one variable cases. */ + if (g == h) { /* ITE(F,G,G) = G */ + return(g); + } + if (cuddIsConstant(g) && cuddIsConstant(h)) { + return(DD_NON_CONSTANT); + } + + topf = cuddI(dd,f->index); + topg = cuddI(dd,g->index); + toph = cuddI(dd,h->index); + v = ddMin(topg,toph); + + /* ITE(F,G,H) = (x,G,H) (non constant) if F = (x,1,0), x < top(G,H). */ + if (topf < v && cuddIsConstant(cuddT(f)) && cuddIsConstant(cuddE(f))) { + return(DD_NON_CONSTANT); + } + + /* Check cache. */ + r = cuddConstantLookup(dd,DD_ADD_ITE_CONSTANT_TAG,f,g,h); + if (r != NULL) { + return(r); + } + + /* Compute cofactors. */ + if (topf <= v) { + v = ddMin(topf,v); /* v = top_var(F,G,H) */ + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + if (topg == v) { + Gv = cuddT(g); Gnv = cuddE(g); + } else { + Gv = Gnv = g; + } + if (toph == v) { + Hv = cuddT(h); Hnv = cuddE(h); + } else { + Hv = Hnv = h; + } + + /* Recursive step. */ + t = Cudd_addIteConstant(dd,Fv,Gv,Hv); + if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) { + cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + e = Cudd_addIteConstant(dd,Fnv,Gnv,Hnv); + if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) { + cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, t); + return(t); + +} /* end of Cudd_addIteConstant */ + + +/**Function******************************************************************** + + Synopsis [Checks whether ADD g is constant whenever ADD f is 1.] + + Description [Checks whether ADD g is constant whenever ADD f is 1. f + must be a 0-1 ADD. Returns a pointer to the resulting ADD (which may + or may not be constant) or DD_NON_CONSTANT. If f is identically 0, + the check is assumed to be successful, and the background value is + returned. No new nodes are created.] + + SideEffects [None] + + SeeAlso [Cudd_addIteConstant Cudd_addLeq] + +******************************************************************************/ +DdNode * +Cudd_addEvalConst( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *zero; + DdNode *Fv,*Fnv,*Gv,*Gnv,*r,*t,*e; + unsigned int topf,topg; + +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(f)); +#endif + + statLine(dd); + /* Terminal cases. */ + if (f == DD_ONE(dd) || cuddIsConstant(g)) { + return(g); + } + if (f == (zero = DD_ZERO(dd))) { + return(dd->background); + } + +#ifdef DD_DEBUG + assert(!cuddIsConstant(f)); +#endif + /* From now on, f and g are known not to be constants. */ + + topf = cuddI(dd,f->index); + topg = cuddI(dd,g->index); + + /* Check cache. */ + r = cuddConstantLookup(dd,DD_ADD_EVAL_CONST_TAG,f,g,g); + if (r != NULL) { + return(r); + } + + /* Compute cofactors. */ + if (topf <= topg) { + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + if (topg <= topf) { + Gv = cuddT(g); Gnv = cuddE(g); + } else { + Gv = Gnv = g; + } + + /* Recursive step. */ + if (Fv != zero) { + t = Cudd_addEvalConst(dd,Fv,Gv); + if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) { + cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + if (Fnv != zero) { + e = Cudd_addEvalConst(dd,Fnv,Gnv); + if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) { + cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + } + cuddCacheInsert2(dd,Cudd_addEvalConst,f,g,t); + return(t); + } else { /* Fnv must be != zero */ + e = Cudd_addEvalConst(dd,Fnv,Gnv); + cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, e); + return(e); + } + +} /* end of Cudd_addEvalConst */ + + +/**Function******************************************************************** + + Synopsis [Computes the complement of an ADD a la C language.] + + Description [Computes the complement of an ADD a la C language: The + complement of 0 is 1 and the complement of everything else is 0. + Returns a pointer to the resulting ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addNegate] + +******************************************************************************/ +DdNode * +Cudd_addCmpl( + DdManager * dd, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddCmplRecur(dd,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addCmpl */ + + +/**Function******************************************************************** + + Synopsis [Determines whether f is less than or equal to g.] + + Description [Returns 1 if f is less than or equal to g; 0 otherwise. + No new nodes are created. This procedure works for arbitrary ADDs. + For 0-1 ADDs Cudd_addEvalConst is more efficient.] + + SideEffects [None] + + SeeAlso [Cudd_addIteConstant Cudd_addEvalConst Cudd_bddLeq] + +******************************************************************************/ +int +Cudd_addLeq( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *tmp, *fv, *fvn, *gv, *gvn; + unsigned int topf, topg, res; + + /* Terminal cases. */ + if (f == g) return(1); + + statLine(dd); + if (cuddIsConstant(f)) { + if (cuddIsConstant(g)) return(cuddV(f) <= cuddV(g)); + if (f == DD_MINUS_INFINITY(dd)) return(1); + if (f == DD_PLUS_INFINITY(dd)) return(0); /* since f != g */ + } + if (g == DD_PLUS_INFINITY(dd)) return(1); + if (g == DD_MINUS_INFINITY(dd)) return(0); /* since f != g */ + + /* Check cache. */ + tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_addLeq,f,g); + if (tmp != NULL) { + return(tmp == DD_ONE(dd)); + } + + /* Compute cofactors. One of f and g is not constant. */ + topf = cuddI(dd,f->index); + topg = cuddI(dd,g->index); + if (topf <= topg) { + fv = cuddT(f); fvn = cuddE(f); + } else { + fv = fvn = f; + } + if (topg <= topf) { + gv = cuddT(g); gvn = cuddE(g); + } else { + gv = gvn = g; + } + + res = Cudd_addLeq(dd,fvn,gvn) && Cudd_addLeq(dd,fv,gv); + + /* Store result in cache and return. */ + cuddCacheInsert2(dd,(DD_CTFP) Cudd_addLeq,f,g, + Cudd_NotCond(DD_ONE(dd),res==0)); + return(res); + +} /* end of Cudd_addLeq */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_addIte(f,g,h).] + + Description [Implements the recursive step of Cudd_addIte(f,g,h). + Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addIte] + +******************************************************************************/ +DdNode * +cuddAddIteRecur( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *one,*zero; + DdNode *r,*Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*t,*e; + unsigned int topf,topg,toph,v; + int index; + + statLine(dd); + /* Trivial cases. */ + + /* One variable cases. */ + if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */ + return(g); + } + if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ + return(h); + } + + /* From now on, f is known to not be a constant. */ + addVarToConst(f,&g,&h,one,zero); + + /* Check remaining one variable cases. */ + if (g == h) { /* ITE(F,G,G) = G */ + return(g); + } + + if (g == one) { /* ITE(F,1,0) = F */ + if (h == zero) return(f); + } + + topf = cuddI(dd,f->index); + topg = cuddI(dd,g->index); + toph = cuddI(dd,h->index); + v = ddMin(topg,toph); + + /* A shortcut: ITE(F,G,H) = (x,G,H) if F=(x,1,0), x < top(G,H). */ + if (topf < v && cuddT(f) == one && cuddE(f) == zero) { + r = cuddUniqueInter(dd,(int)f->index,g,h); + return(r); + } + if (topf < v && cuddT(f) == zero && cuddE(f) == one) { + r = cuddUniqueInter(dd,(int)f->index,h,g); + return(r); + } + + /* Check cache. */ + r = cuddCacheLookup(dd,DD_ADD_ITE_TAG,f,g,h); + if (r != NULL) { + return(r); + } + + /* Compute cofactors. */ + if (topf <= v) { + v = ddMin(topf,v); /* v = top_var(F,G,H) */ + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + if (topg == v) { + index = g->index; + Gv = cuddT(g); Gnv = cuddE(g); + } else { + Gv = Gnv = g; + } + if (toph == v) { + index = h->index; + Hv = cuddT(h); Hnv = cuddE(h); + } else { + Hv = Hnv = h; + } + + /* Recursive step. */ + t = cuddAddIteRecur(dd,Fv,Gv,Hv); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddAddIteRecur(dd,Fnv,Gnv,Hnv); + if (e == NULL) { + Cudd_RecursiveDeref(dd,t); + return(NULL); + } + cuddRef(e); + + r = (t == e) ? t : cuddUniqueInter(dd,index,t,e); + if (r == NULL) { + Cudd_RecursiveDeref(dd,t); + Cudd_RecursiveDeref(dd,e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert(dd,DD_ADD_ITE_TAG,f,g,h,r); + + return(r); + +} /* end of cuddAddIteRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addCmpl.] + + Description [Performs the recursive step of Cudd_addCmpl. Returns a + pointer to the resulting ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addCmpl] + +******************************************************************************/ +DdNode * +cuddAddCmplRecur( + DdManager * dd, + DdNode * f) +{ + DdNode *one,*zero; + DdNode *r,*Fv,*Fnv,*t,*e; + + statLine(dd); + one = DD_ONE(dd); + zero = DD_ZERO(dd); + + if (cuddIsConstant(f)) { + if (f == zero) { + return(one); + } else { + return(zero); + } + } + r = cuddCacheLookup1(dd,Cudd_addCmpl,f); + if (r != NULL) { + return(r); + } + Fv = cuddT(f); + Fnv = cuddE(f); + t = cuddAddCmplRecur(dd,Fv); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddAddCmplRecur(dd,Fnv); + if (e == NULL) { + Cudd_RecursiveDeref(dd,t); + return(NULL); + } + cuddRef(e); + r = (t == e) ? t : cuddUniqueInter(dd,(int)f->index,t,e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + cuddCacheInsert1(dd,Cudd_addCmpl,f,r); + return(r); + +} /* end of cuddAddCmplRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Replaces variables with constants if possible (part of + canonical form).] + + Description [] + + SideEffects [None] + +******************************************************************************/ +static void +addVarToConst( + DdNode * f, + DdNode ** gp, + DdNode ** hp, + DdNode * one, + DdNode * zero) +{ + DdNode *g = *gp; + DdNode *h = *hp; + + if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ + *gp = one; + } + + if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ + *hp = zero; + } + +} /* end of addVarToConst */ diff --git a/cudd_local/cudd/cuddAddNeg.c b/cudd_local/cudd/cuddAddNeg.c new file mode 100644 index 0000000..92c1cd7 --- /dev/null +++ b/cudd_local/cudd/cuddAddNeg.c @@ -0,0 +1,290 @@ +/**CFile*********************************************************************** + + FileName [cuddAddNeg.c] + + PackageName [cudd] + + Synopsis [Function to compute the negation of an ADD.] + + Description [External procedures included in this module: + + Internal procedures included in this module: + ] + + Author [Fabio Somenzi, Balakrishna Kumthekar] + + Copyright [Copyright (c) 1995-2012, 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: cuddAddNeg.c,v 1.14 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Computes the additive inverse of an ADD.] + + Description [Computes the additive inverse of an ADD. Returns a pointer + to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addCmpl] + +******************************************************************************/ +DdNode * +Cudd_addNegate( + DdManager * dd, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddNegateRecur(dd,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addNegate */ + + +/**Function******************************************************************** + + Synopsis [Rounds off the discriminants of an ADD.] + + Description [Rounds off the discriminants of an ADD. The discriminants are + rounded off to N digits after the decimal. Returns a pointer to the result + ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_addRoundOff( + DdManager * dd, + DdNode * f, + int N) +{ + DdNode *res; + double trunc = pow(10.0,(double)N); + + do { + dd->reordered = 0; + res = cuddAddRoundOffRecur(dd,f,trunc); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addRoundOff */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_addNegate.] + + Description [Implements the recursive step of Cudd_addNegate. + Returns a pointer to the result.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +cuddAddNegateRecur( + DdManager * dd, + DdNode * f) +{ + DdNode *res, + *fv, *fvn, + *T, *E; + + statLine(dd); + /* Check terminal cases. */ + if (cuddIsConstant(f)) { + res = cuddUniqueConst(dd,-cuddV(f)); + return(res); + } + + /* Check cache */ + res = cuddCacheLookup1(dd,Cudd_addNegate,f); + if (res != NULL) return(res); + + /* Recursive Step */ + fv = cuddT(f); + fvn = cuddE(f); + T = cuddAddNegateRecur(dd,fv); + if (T == NULL) return(NULL); + cuddRef(T); + + E = cuddAddNegateRecur(dd,fvn); + if (E == NULL) { + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + res = (T == E) ? T : cuddUniqueInter(dd,(int)f->index,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert1(dd,Cudd_addNegate,f,res); + + return(res); + +} /* end of cuddAddNegateRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_addRoundOff.] + + Description [Implements the recursive step of Cudd_addRoundOff. + Returns a pointer to the result.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +cuddAddRoundOffRecur( + DdManager * dd, + DdNode * f, + double trunc) +{ + + DdNode *res, *fv, *fvn, *T, *E; + double n; + DD_CTFP1 cacheOp; + + statLine(dd); + if (cuddIsConstant(f)) { + n = ceil(cuddV(f)*trunc)/trunc; + res = cuddUniqueConst(dd,n); + return(res); + } + cacheOp = (DD_CTFP1) Cudd_addRoundOff; + res = cuddCacheLookup1(dd,cacheOp,f); + if (res != NULL) { + return(res); + } + /* Recursive Step */ + fv = cuddT(f); + fvn = cuddE(f); + T = cuddAddRoundOffRecur(dd,fv,trunc); + if (T == NULL) { + return(NULL); + } + cuddRef(T); + E = cuddAddRoundOffRecur(dd,fvn,trunc); + if (E == NULL) { + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + res = (T == E) ? T : cuddUniqueInter(dd,(int)f->index,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert1(dd,cacheOp,f,res); + return(res); + +} /* end of cuddAddRoundOffRecur */ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/cudd_local/cudd/cuddAddWalsh.c b/cudd_local/cudd/cuddAddWalsh.c new file mode 100644 index 0000000..146b1d3 --- /dev/null +++ b/cudd_local/cudd/cuddAddWalsh.c @@ -0,0 +1,391 @@ +/**CFile*********************************************************************** + + FileName [cuddAddWalsh.c] + + PackageName [cudd] + + Synopsis [Functions that generate Walsh matrices and residue + functions in ADD form.] + + Description [External procedures included in this module: + + Static procedures included in this module: + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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: cuddAddWalsh.c,v 1.11 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * addWalshInt (DdManager *dd, DdNode **x, DdNode **y, int n); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Generates a Walsh matrix in ADD form.] + + Description [Generates a Walsh matrix in ADD form. Returns a pointer + to the matrixi if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +DdNode * +Cudd_addWalsh( + DdManager * dd, + DdNode ** x, + DdNode ** y, + int n) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = addWalshInt(dd, x, y, n); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addWalsh */ + + +/**Function******************************************************************** + + Synopsis [Builds an ADD for the residue modulo m of an n-bit + number.] + + Description [Builds an ADD for the residue modulo m of an n-bit + number. The modulus must be at least 2, and the number of bits at + least 1. Parameter options specifies whether the MSB should be on top + or the LSB; and whther the number whose residue is computed is in + two's complement notation or not. The macro CUDD_RESIDUE_DEFAULT + specifies LSB on top and unsigned number. The macro CUDD_RESIDUE_MSB + specifies MSB on top, and the macro CUDD_RESIDUE_TC specifies two's + complement residue. To request MSB on top and two's complement residue + simultaneously, one can OR the two macros: + CUDD_RESIDUE_MSB | CUDD_RESIDUE_TC. + Cudd_addResidue returns a pointer to the resulting ADD if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_addResidue( + DdManager * dd /* manager */, + int n /* number of bits */, + int m /* modulus */, + int options /* options */, + int top /* index of top variable */) +{ + int msbLsb; /* MSB on top (1) or LSB on top (0) */ + int tc; /* two's complement (1) or unsigned (0) */ + int i, j, k, t, residue, thisOne, previous, index; + DdNode **array[2], *var, *tmp, *res; + + /* Sanity check. */ + if (n < 1 && m < 2) return(NULL); + + msbLsb = options & CUDD_RESIDUE_MSB; + tc = options & CUDD_RESIDUE_TC; + + /* Allocate and initialize working arrays. */ + array[0] = ALLOC(DdNode *,m); + if (array[0] == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + array[1] = ALLOC(DdNode *,m); + if (array[1] == NULL) { + FREE(array[0]); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < m; i++) { + array[0][i] = array[1][i] = NULL; + } + + /* Initialize residues. */ + for (i = 0; i < m; i++) { + tmp = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) i); + if (tmp == NULL) { + for (j = 0; j < i; j++) { + Cudd_RecursiveDeref(dd,array[1][j]); + } + FREE(array[0]); + FREE(array[1]); + return(NULL); + } + cuddRef(tmp); + array[1][i] = tmp; + } + + /* Main iteration. */ + residue = 1; /* residue of 2**0 */ + for (k = 0; k < n; k++) { + /* Choose current and previous arrays. */ + thisOne = k & 1; + previous = thisOne ^ 1; + /* Build an ADD projection function. */ + if (msbLsb) { + index = top+n-k-1; + } else { + index = top+k; + } + var = cuddUniqueInter(dd,index,DD_ONE(dd),DD_ZERO(dd)); + if (var == NULL) { + for (j = 0; j < m; j++) { + Cudd_RecursiveDeref(dd,array[previous][j]); + } + FREE(array[0]); + FREE(array[1]); + return(NULL); + } + cuddRef(var); + for (i = 0; i < m; i ++) { + t = (i + residue) % m; + tmp = Cudd_addIte(dd,var,array[previous][t],array[previous][i]); + if (tmp == NULL) { + for (j = 0; j < i; j++) { + Cudd_RecursiveDeref(dd,array[thisOne][j]); + } + for (j = 0; j < m; j++) { + Cudd_RecursiveDeref(dd,array[previous][j]); + } + FREE(array[0]); + FREE(array[1]); + return(NULL); + } + cuddRef(tmp); + array[thisOne][i] = tmp; + } + /* One layer completed. Free the other array for the next iteration. */ + for (i = 0; i < m; i++) { + Cudd_RecursiveDeref(dd,array[previous][i]); + } + Cudd_RecursiveDeref(dd,var); + /* Update residue of 2**k. */ + residue = (2 * residue) % m; + /* Adjust residue for MSB, if this is a two's complement number. */ + if (tc && (k == n - 1)) { + residue = (m - residue) % m; + } + } + + /* We are only interested in the 0-residue node of the top layer. */ + for (i = 1; i < m; i++) { + Cudd_RecursiveDeref(dd,array[(n - 1) & 1][i]); + } + res = array[(n - 1) & 1][0]; + + FREE(array[0]); + FREE(array[1]); + + cuddDeref(res); + return(res); + +} /* end of Cudd_addResidue */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_addWalsh.] + + Description [Generates a Walsh matrix in ADD form. Returns a pointer + to the matrixi if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +static DdNode * +addWalshInt( + DdManager * dd, + DdNode ** x, + DdNode ** y, + int n) +{ + DdNode *one, *minusone; + DdNode *t, *u, *t1, *u1, *v, *w; + int i; + + one = DD_ONE(dd); + if (n == 0) return(one); + + /* Build bottom part of ADD outside loop */ + minusone = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) -1); + if (minusone == NULL) return(NULL); + cuddRef(minusone); + v = Cudd_addIte(dd, y[n-1], minusone, one); + if (v == NULL) { + Cudd_RecursiveDeref(dd, minusone); + return(NULL); + } + cuddRef(v); + u = Cudd_addIte(dd, x[n-1], v, one); + if (u == NULL) { + Cudd_RecursiveDeref(dd, minusone); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + if (n>1) { + w = Cudd_addIte(dd, y[n-1], one, minusone); + if (w == NULL) { + Cudd_RecursiveDeref(dd, minusone); + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(w); + t = Cudd_addIte(dd, x[n-1], w, minusone); + if (t == NULL) { + Cudd_RecursiveDeref(dd, minusone); + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(t); + Cudd_RecursiveDeref(dd, w); + } + cuddDeref(minusone); /* minusone is in the result; it won't die */ + + /* Loop to build the rest of the ADD */ + for (i=n-2; i>=0; i--) { + t1 = t; u1 = u; + v = Cudd_addIte(dd, y[i], t1, u1); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + return(NULL); + } + cuddRef(v); + u = Cudd_addIte(dd, x[i], v, u1); + if (u == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + if (i>0) { + w = Cudd_addIte(dd, y[i], u1, t1); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(w); + t = Cudd_addIte(dd, x[i], w, t1); + if (u == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(t); + Cudd_RecursiveDeref(dd, w); + } + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + } + + cuddDeref(u); + return(u); + +} /* end of addWalshInt */ diff --git a/cudd_local/cudd/cuddAndAbs.c b/cudd_local/cudd/cuddAndAbs.c new file mode 100644 index 0000000..a800830 --- /dev/null +++ b/cudd_local/cudd/cuddAndAbs.c @@ -0,0 +1,373 @@ +/**CFile*********************************************************************** + + FileName [cuddAndAbs.c] + + PackageName [cudd] + + Synopsis [Combined AND and existential abstraction for BDDs] + + Description [External procedures included in this module: + + Internal procedures included in this module: + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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: cuddAndAbs.c,v 1.20 2012/02/05 01:07:18 fabio Exp $"; +#endif + + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Takes the AND of two BDDs and simultaneously abstracts the + variables in cube.] + + Description [Takes the AND of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. + Returns a pointer to the result is successful; NULL otherwise. + Cudd_bddAndAbstract implements the semiring matrix multiplication + algorithm for the boolean semiring.] + + SideEffects [None] + + SeeAlso [Cudd_addMatrixMultiply Cudd_addTriangle Cudd_bddAnd] + +******************************************************************************/ +DdNode * +Cudd_bddAndAbstract( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube) +{ + DdNode *res; + + do { + manager->reordered = 0; + res = cuddBddAndAbstractRecur(manager, f, g, cube); + } while (manager->reordered == 1); + return(res); + +} /* end of Cudd_bddAndAbstract */ + + +/**Function******************************************************************** + + Synopsis [Takes the AND of two BDDs and simultaneously abstracts the + variables in cube. Returns NULL if too many nodes are required.] + + Description [Takes the AND of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. + Returns a pointer to the result is successful; NULL otherwise. + In particular, if the number of new nodes created exceeds + limit, this function returns NULL.] + + SideEffects [None] + + SeeAlso [Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +Cudd_bddAndAbstractLimit( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = manager->maxLive; + + manager->maxLive = (manager->keys - manager->dead) + + (manager->keysZ - manager->deadZ) + limit; + do { + manager->reordered = 0; + res = cuddBddAndAbstractRecur(manager, f, g, cube); + } while (manager->reordered == 1); + manager->maxLive = saveLimit; + return(res); + +} /* end of Cudd_bddAndAbstractLimit */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Takes the AND of two BDDs and simultaneously abstracts the + variables in cube.] + + Description [Takes the AND of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. + Returns a pointer to the result is successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +cuddBddAndAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube) +{ + DdNode *F, *ft, *fe, *G, *gt, *ge; + DdNode *one, *zero, *r, *t, *e; + unsigned int topf, topg, topcube, top, index; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); + if (f == one && g == one) return(one); + + if (cube == one) { + return(cuddBddAndRecur(manager, f, g)); + } + if (f == one || f == g) { + return(cuddBddExistAbstractRecur(manager, g, cube)); + } + if (g == one) { + return(cuddBddExistAbstractRecur(manager, f, cube)); + } + /* At this point f, g, and cube are not constant. */ + + if (f > g) { /* Try to increase cache efficiency. */ + DdNode *tmp = f; + f = g; + g = tmp; + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + F = Cudd_Regular(f); + G = Cudd_Regular(g); + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + top = ddMin(topf, topg); + topcube = manager->perm[cube->index]; + + while (topcube < top) { + cube = cuddT(cube); + if (cube == one) { + return(cuddBddAndRecur(manager, f, g)); + } + topcube = manager->perm[cube->index]; + } + /* Now, topcube >= top. */ + + /* Check cache. */ + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube); + if (r != NULL) { + return(r); + } + } + + if (topf == top) { + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } + } else { + index = G->index; + ft = fe = f; + } + + if (topg == top) { + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } + } else { + gt = ge = g; + } + + if (topcube == top) { /* quantify */ + DdNode *Cube = cuddT(cube); + t = cuddBddAndAbstractRecur(manager, ft, gt, Cube); + if (t == NULL) return(NULL); + /* Special case: 1 OR anything = 1. Hence, no need to compute + ** the else branch if t is 1. Likewise t + t * anything == t. + ** Notice that t == fe implies that fe does not depend on the + ** variables in Cube. Likewise for t == ge. + */ + if (t == one || t == fe || t == ge) { + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, + f, g, cube, t); + return(t); + } + cuddRef(t); + /* Special case: t + !t * anything == t + anything. */ + if (t == Cudd_Not(fe)) { + e = cuddBddExistAbstractRecur(manager, ge, Cube); + } else if (t == Cudd_Not(ge)) { + e = cuddBddExistAbstractRecur(manager, fe, Cube); + } else { + e = cuddBddAndAbstractRecur(manager, fe, ge, Cube); + } + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + if (t == e) { + r = t; + cuddDeref(t); + } else { + cuddRef(e); + r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + cuddRef(r); + Cudd_DelayedDerefBdd(manager, t); + Cudd_DelayedDerefBdd(manager, e); + cuddDeref(r); + } + } else { + t = cuddBddAndAbstractRecur(manager, ft, gt, cube); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddBddAndAbstractRecur(manager, fe, ge, cube); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + if (t == e) { + r = t; + cuddDeref(t); + } else { + cuddRef(e); + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager, (int) index, + Cudd_Not(t), Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + cuddDeref(e); + cuddDeref(t); + } + } + + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube, r); + return (r); + +} /* end of cuddBddAndAbstractRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/cudd_local/cudd/cuddAnneal.c b/cudd_local/cudd/cuddAnneal.c new file mode 100644 index 0000000..622c3d1 --- /dev/null +++ b/cudd_local/cudd/cuddAnneal.c @@ -0,0 +1,814 @@ +/**CFile*********************************************************************** + + FileName [cuddAnneal.c] + + PackageName [cudd] + + Synopsis [Reordering of DDs based on simulated annealing] + + Description [Internal procedures included in this file: + + Static procedures included in this file: + + ] + + SeeAlso [] + + Author [Jae-Young Jang, Jorgen Sivesind] + + Copyright [Copyright (c) 1995-2012, 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 */ +/*---------------------------------------------------------------------------*/ + +/* Annealing parameters */ +#define BETA 0.6 +#define ALPHA 0.90 +#define EXC_PROB 0.4 +#define JUMP_UP_PROB 0.36 +#define MAXGEN_RATIO 15.0 +#define STOP_TEMP 1.0 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddAnneal.c,v 1.15 2012/02/05 01:07:18 fabio Exp $"; +#endif + +#ifdef DD_STATS +extern int ddTotalNumberSwapping; +extern int ddTotalNISwaps; +static int tosses; +static int acceptances; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int stopping_criterion (int c1, int c2, int c3, int c4, double temp); +static double random_generator (void); +static int ddExchange (DdManager *table, int x, int y, double temp); +static int ddJumpingAux (DdManager *table, int x, int x_low, int x_high, double temp); +static Move * ddJumpingUp (DdManager *table, int x, int x_low, int initial_size); +static Move * ddJumpingDown (DdManager *table, int x, int x_high, int initial_size); +static int siftBackwardProb (DdManager *table, Move *moves, int size, double temp); +static void copyOrder (DdManager *table, int *array, int lower, int upper); +static int restoreOrder (DdManager *table, int *array, int lower, int upper); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Get new variable-order by simulated annealing algorithm.] + + Description [Get x, y by random selection. Choose either + exchange or jump randomly. In case of jump, choose between jump_up + and jump_down randomly. Do exchange or jump and get optimal case. + Loop until there is no improvement or temperature reaches + minimum. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddAnnealing( + DdManager * table, + int lower, + int upper) +{ + int nvars; + int size; + int x,y; + int result; + int c1, c2, c3, c4; + int BestCost; + int *BestOrder; + double NewTemp, temp; + double rand1; + int innerloop, maxGen; + int ecount, ucount, dcount; + + nvars = upper - lower + 1; + + result = cuddSifting(table,lower,upper); +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); +#endif + if (result == 0) return(0); + + size = table->keys - table->isolated; + + /* Keep track of the best order. */ + BestCost = size; + BestOrder = ALLOC(int,nvars); + if (BestOrder == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + copyOrder(table,BestOrder,lower,upper); + + temp = BETA * size; + maxGen = (int) (MAXGEN_RATIO * nvars); + + c1 = size + 10; + c2 = c1 + 10; + c3 = size; + c4 = c2 + 10; + ecount = ucount = dcount = 0; + + while (!stopping_criterion(c1, c2, c3, c4, temp)) { +#ifdef DD_STATS + (void) fprintf(table->out,"temp=%f\tsize=%d\tgen=%d\t", + temp,size,maxGen); + tosses = acceptances = 0; +#endif + for (innerloop = 0; innerloop < maxGen; innerloop++) { + /* Choose x, y randomly. */ + x = (int) Cudd_Random() % nvars; + do { + y = (int) Cudd_Random() % nvars; + } while (x == y); + x += lower; + y += lower; + if (x > y) { + int tmp = x; + x = y; + y = tmp; + } + + /* Choose move with roulette wheel. */ + rand1 = random_generator(); + if (rand1 < EXC_PROB) { + result = ddExchange(table,x,y,temp); /* exchange */ + ecount++; +#if 0 + (void) fprintf(table->out, + "Exchange of %d and %d: size = %d\n", + x,y,table->keys - table->isolated); +#endif + } else if (rand1 < EXC_PROB + JUMP_UP_PROB) { + result = ddJumpingAux(table,y,x,y,temp); /* jumping_up */ + ucount++; +#if 0 + (void) fprintf(table->out, + "Jump up of %d to %d: size = %d\n", + y,x,table->keys - table->isolated); +#endif + } else { + result = ddJumpingAux(table,x,x,y,temp); /* jumping_down */ + dcount++; +#if 0 + (void) fprintf(table->out, + "Jump down of %d to %d: size = %d\n", + x,y,table->keys - table->isolated); +#endif + } + + if (!result) { + FREE(BestOrder); + return(0); + } + + size = table->keys - table->isolated; /* keep current size */ + if (size < BestCost) { /* update best order */ + BestCost = size; + copyOrder(table,BestOrder,lower,upper); + } + } + c1 = c2; + c2 = c3; + c3 = c4; + c4 = size; + NewTemp = ALPHA * temp; + if (NewTemp >= 1.0) { + maxGen = (int)(log(NewTemp) / log(temp) * maxGen); + } + temp = NewTemp; /* control variable */ +#ifdef DD_STATS + (void) fprintf(table->out,"uphill = %d\taccepted = %d\n", + tosses,acceptances); + fflush(table->out); +#endif + } + + result = restoreOrder(table,BestOrder,lower,upper); + FREE(BestOrder); + if (!result) return(0); +#ifdef DD_STATS + fprintf(table->out,"#:N_EXCHANGE %8d : total exchanges\n",ecount); + fprintf(table->out,"#:N_JUMPUP %8d : total jumps up\n",ucount); + fprintf(table->out,"#:N_JUMPDOWN %8d : total jumps down",dcount); +#endif + return(1); + +} /* end of cuddAnnealing */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Checks termination condition.] + + Description [If temperature is STOP_TEMP or there is no improvement + then terminates. Returns 1 if the termination criterion is met; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +stopping_criterion( + int c1, + int c2, + int c3, + int c4, + double temp) +{ + if (STOP_TEMP < temp) { + return(0); + } else if ((c1 == c2) && (c1 == c3) && (c1 == c4)) { + return(1); + } else { + return(0); + } + +} /* end of stopping_criterion */ + + +/**Function******************************************************************** + + Synopsis [Random number generator.] + + Description [Returns a double precision value between 0.0 and 1.0.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static double +random_generator(void) +{ + return((double)(Cudd_Random() / 2147483561.0)); + +} /* end of random_generator */ + + +/**Function******************************************************************** + + Synopsis [This function is for exchanging two variables, x and y.] + + Description [This is the same funcion as ddSwapping except for + comparison expression. Use probability function, exp(-size_change/temp).] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddExchange( + DdManager * table, + int x, + int y, + double temp) +{ + Move *move,*moves; + int tmp; + int x_ref,y_ref; + int x_next,y_next; + int size, result; + int initial_size, limit_size; + + x_ref = x; + y_ref = y; + + x_next = cuddNextHigh(table,x); + y_next = cuddNextLow(table,y); + moves = NULL; + initial_size = limit_size = table->keys - table->isolated; + + for (;;) { + if (x_next == y_next) { + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + size = cuddSwapInPlace(table,y_next,y); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; + x = y; + y = tmp; + } else if (x == y_next) { + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + tmp = x; + x = y; + y = tmp; + } else { + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + size = cuddSwapInPlace(table,y_next,y); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + x = x_next; + y = y_next; + } + + x_next = cuddNextHigh(table,x); + y_next = cuddNextLow(table,y); + if (x_next > y_ref) break; + + if ((double) size > DD_MAX_REORDER_GROWTH * (double) limit_size) { + break; + } else if (size < limit_size) { + limit_size = size; + } + } + + if (y_next>=x_ref) { + size = cuddSwapInPlace(table,y_next,y); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + } + + /* move backward and stop at best position or accept uphill move */ + result = siftBackwardProb(table,moves,initial_size,temp); + if (!result) goto ddExchangeOutOfMem; + + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(1); + +ddExchangeOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(0); + +} /* end of ddExchange */ + + +/**Function******************************************************************** + + Synopsis [Moves a variable to a specified position.] + + Description [If x==x_low, it executes jumping_down. If x==x_high, it + executes jumping_up. This funcion is similar to ddSiftingAux. Returns + 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddJumpingAux( + DdManager * table, + int x, + int x_low, + int x_high, + double temp) +{ + Move *move; + Move *moves; /* list of moves */ + int initial_size; + int result; + + initial_size = table->keys - table->isolated; + +#ifdef DD_DEBUG + assert(table->subtables[x].keys > 0); +#endif + + moves = NULL; + + if (cuddNextLow(table,x) < x_low) { + if (cuddNextHigh(table,x) > x_high) return(1); + moves = ddJumpingDown(table,x,x_high,initial_size); + /* after that point x --> x_high unless early termination */ + if (moves == NULL) goto ddJumpingAuxOutOfMem; + /* move backward and stop at best position or accept uphill move */ + result = siftBackwardProb(table,moves,initial_size,temp); + if (!result) goto ddJumpingAuxOutOfMem; + } else if (cuddNextHigh(table,x) > x_high) { + moves = ddJumpingUp(table,x,x_low,initial_size); + /* after that point x --> x_low unless early termination */ + if (moves == NULL) goto ddJumpingAuxOutOfMem; + /* move backward and stop at best position or accept uphill move */ + result = siftBackwardProb(table,moves,initial_size,temp); + if (!result) goto ddJumpingAuxOutOfMem; + } else { + (void) fprintf(table->err,"Unexpected condition in ddJumping\n"); + goto ddJumpingAuxOutOfMem; + } + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(1); + +ddJumpingAuxOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(0); + +} /* end of ddJumpingAux */ + + +/**Function******************************************************************** + + Synopsis [This function is for jumping up.] + + Description [This is a simplified version of ddSiftingUp. It does not + use lower bounding. Returns the set of moves in case of success; NULL + if memory is full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +ddJumpingUp( + DdManager * table, + int x, + int x_low, + int initial_size) +{ + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + + moves = NULL; + y = cuddNextLow(table,x); + while (y >= x_low) { + size = cuddSwapInPlace(table,y,x); + if (size == 0) goto ddJumpingUpOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddJumpingUpOutOfMem; + move->x = y; + move->y = x; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > table->maxGrowth * (double) limit_size) { + break; + } else if (size < limit_size) { + limit_size = size; + } + x = y; + y = cuddNextLow(table,x); + } + return(moves); + +ddJumpingUpOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(NULL); + +} /* end of ddJumpingUp */ + + +/**Function******************************************************************** + + Synopsis [This function is for jumping down.] + + Description [This is a simplified version of ddSiftingDown. It does not + use lower bounding. Returns the set of moves in case of success; NULL + if memory is full.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static Move * +ddJumpingDown( + DdManager * table, + int x, + int x_high, + int initial_size) +{ + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + + moves = NULL; + y = cuddNextHigh(table,x); + while (y <= x_high) { + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddJumpingDownOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddJumpingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > table->maxGrowth * (double) limit_size) { + break; + } else if (size < limit_size) { + limit_size = size; + } + x = y; + y = cuddNextHigh(table,x); + } + return(moves); + +ddJumpingDownOutOfMem: + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } + return(NULL); + +} /* end of ddJumpingDown */ + + +/**Function******************************************************************** + + Synopsis [Returns the DD to the best position encountered during + sifting if there was improvement.] + + Description [Otherwise, "tosses a coin" to decide whether to keep + the current configuration or return the DD to the original + one. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +siftBackwardProb( + DdManager * table, + Move * moves, + int size, + double temp) +{ + Move *move; + int res; + int best_size = size; + double coin, threshold; + + /* Look for best size during the last sifting */ + for (move = moves; move != NULL; move = move->next) { + if (move->size < best_size) { + best_size = move->size; + } + } + + /* If best_size equals size, the last sifting did not produce any + ** improvement. We now toss a coin to decide whether to retain + ** this change or not. + */ + if (best_size == size) { + coin = random_generator(); +#ifdef DD_STATS + tosses++; +#endif + threshold = exp(-((double)(table->keys - table->isolated - size))/temp); + if (coin < threshold) { +#ifdef DD_STATS + acceptances++; +#endif + return(1); + } + } + + /* Either there was improvement, or we have decided not to + ** accept the uphill move. Go to best position. + */ + res = table->keys - table->isolated; + for (move = moves; move != NULL; move = move->next) { + if (res == best_size) return(1); + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + + return(1); + +} /* end of sift_backward_prob */ + + +/**Function******************************************************************** + + Synopsis [Copies the current variable order to array.] + + Description [Copies the current variable order to array. + At the same time inverts the permutation.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +copyOrder( + DdManager * table, + int * array, + int lower, + int upper) +{ + int i; + int nvars; + + nvars = upper - lower + 1; + for (i = 0; i < nvars; i++) { + array[i] = table->invperm[i+lower]; + } + +} /* end of copyOrder */ + + +/**Function******************************************************************** + + Synopsis [Restores the variable order in array by a series of sifts up.] + + Description [Restores the variable order in array by a series of sifts up. + Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +restoreOrder( + DdManager * table, + int * array, + int lower, + int upper) +{ + int i, x, y, size; + int nvars = upper - lower + 1; + + for (i = 0; i < nvars; i++) { + x = table->perm[array[i]]; +#ifdef DD_DEBUG + assert(x >= lower && x <= upper); +#endif + y = cuddNextLow(table,x); + while (y >= i + lower) { + size = cuddSwapInPlace(table,y,x); + if (size == 0) return(0); + x = y; + y = cuddNextLow(table,x); + } + } + + return(1); + +} /* end of restoreOrder */ + diff --git a/cudd_local/cudd/cuddApa.c b/cudd_local/cudd/cuddApa.c new file mode 100644 index 0000000..7c4ff8c --- /dev/null +++ b/cudd_local/cudd/cuddApa.c @@ -0,0 +1,979 @@ +/**CFile*********************************************************************** + + FileName [cuddApa.c] + + PackageName [cudd] + + Synopsis [Arbitrary precision arithmetic functions.] + + Description [External procedures included in this module: + + Static procedures included in this module: + ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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: cuddApa.c,v 1.20 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static DdNode *background, *zero; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdApaNumber cuddApaCountMintermAux (DdNode * node, int digits, DdApaNumber max, DdApaNumber min, st_table * table); +static enum st_retval cuddApaStCountfree (char * key, char * value, char * arg); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Finds the number of digits for an arbitrary precision + integer.] + + Description [Finds the number of digits for an arbitrary precision + integer given the maximum number of binary digits. The number of + binary digits should be positive. Returns the number of digits if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_ApaNumberOfDigits( + int binaryDigits) +{ + int digits; + + digits = binaryDigits / DD_APA_BITS; + if ((digits * DD_APA_BITS) != binaryDigits) + digits++; + return(digits); + +} /* end of Cudd_ApaNumberOfDigits */ + + +/**Function******************************************************************** + + Synopsis [Allocates memory for an arbitrary precision integer.] + + Description [Allocates memory for an arbitrary precision + integer. Returns a pointer to the allocated memory if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdApaNumber +Cudd_NewApaNumber( + int digits) +{ + return(ALLOC(DdApaDigit, digits)); + +} /* end of Cudd_NewApaNumber */ + + +/**Function******************************************************************** + + Synopsis [Makes a copy of an arbitrary precision integer.] + + Description [Makes a copy of an arbitrary precision integer.] + + SideEffects [Changes parameter dest.] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_ApaCopy( + int digits, + DdApaNumber source, + DdApaNumber dest) +{ + int i; + + for (i = 0; i < digits; i++) { + dest[i] = source[i]; + } + +} /* end of Cudd_ApaCopy */ + + +/**Function******************************************************************** + + Synopsis [Adds two arbitrary precision integers.] + + Description [Adds two arbitrary precision integers. Returns the + carry out of the most significant digit.] + + SideEffects [The result of the sum is stored in parameter sum.] + + SeeAlso [] + +******************************************************************************/ +DdApaDigit +Cudd_ApaAdd( + int digits, + DdApaNumber a, + DdApaNumber b, + DdApaNumber sum) +{ + int i; + DdApaDoubleDigit partial = 0; + + for (i = digits - 1; i >= 0; i--) { + partial = a[i] + b[i] + DD_MSDIGIT(partial); + sum[i] = (DdApaDigit) DD_LSDIGIT(partial); + } + return((DdApaDigit) DD_MSDIGIT(partial)); + +} /* end of Cudd_ApaAdd */ + + +/**Function******************************************************************** + + Synopsis [Subtracts two arbitrary precision integers.] + + Description [Subtracts two arbitrary precision integers. Returns the + borrow out of the most significant digit.] + + SideEffects [The result of the subtraction is stored in parameter + diff.] + + SeeAlso [] + +******************************************************************************/ +DdApaDigit +Cudd_ApaSubtract( + int digits, + DdApaNumber a, + DdApaNumber b, + DdApaNumber diff) +{ + int i; + DdApaDoubleDigit partial = DD_APA_BASE; + + for (i = digits - 1; i >= 0; i--) { + partial = DD_MSDIGIT(partial) + DD_APA_MASK + a[i] - b[i]; + diff[i] = (DdApaDigit) DD_LSDIGIT(partial); + } + return((DdApaDigit) DD_MSDIGIT(partial) - 1); + +} /* end of Cudd_ApaSubtract */ + + +/**Function******************************************************************** + + Synopsis [Divides an arbitrary precision integer by a digit.] + + Description [Divides an arbitrary precision integer by a digit.] + + SideEffects [The quotient is returned in parameter quotient.] + + SeeAlso [] + +******************************************************************************/ +DdApaDigit +Cudd_ApaShortDivision( + int digits, + DdApaNumber dividend, + DdApaDigit divisor, + DdApaNumber quotient) +{ + int i; + DdApaDigit remainder; + DdApaDoubleDigit partial; + + remainder = 0; + for (i = 0; i < digits; i++) { + partial = remainder * DD_APA_BASE + dividend[i]; + quotient[i] = (DdApaDigit) (partial/(DdApaDoubleDigit)divisor); + remainder = (DdApaDigit) (partial % divisor); + } + + return(remainder); + +} /* end of Cudd_ApaShortDivision */ + + +/**Function******************************************************************** + + Synopsis [Divides an arbitrary precision integer by an integer.] + + Description [Divides an arbitrary precision integer by a 32-bit + unsigned integer. Returns the remainder of the division. This + procedure relies on the assumption that the number of bits of a + DdApaDigit plus the number of bits of an unsigned int is less the + number of bits of the mantissa of a double. This guarantees that the + product of a DdApaDigit and an unsigned int can be represented + without loss of precision by a double. On machines where this + assumption is not satisfied, this procedure will malfunction.] + + SideEffects [The quotient is returned in parameter quotient.] + + SeeAlso [Cudd_ApaShortDivision] + +******************************************************************************/ +unsigned int +Cudd_ApaIntDivision( + int digits, + DdApaNumber dividend, + unsigned int divisor, + DdApaNumber quotient) +{ + int i; + double partial; + unsigned int remainder = 0; + double ddiv = (double) divisor; + + for (i = 0; i < digits; i++) { + partial = (double) remainder * DD_APA_BASE + dividend[i]; + quotient[i] = (DdApaDigit) (partial / ddiv); + remainder = (unsigned int) (partial - ((double)quotient[i] * ddiv)); + } + + return(remainder); + +} /* end of Cudd_ApaIntDivision */ + + +/**Function******************************************************************** + + Synopsis [Shifts right an arbitrary precision integer by one binary + place.] + + Description [Shifts right an arbitrary precision integer by one + binary place. The most significant binary digit of the result is + taken from parameter in.] + + SideEffects [The result is returned in parameter b.] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_ApaShiftRight( + int digits, + DdApaDigit in, + DdApaNumber a, + DdApaNumber b) +{ + int i; + + for (i = digits - 1; i > 0; i--) { + b[i] = (a[i] >> 1) | ((a[i-1] & 1) << (DD_APA_BITS - 1)); + } + b[0] = (a[0] >> 1) | (in << (DD_APA_BITS - 1)); + +} /* end of Cudd_ApaShiftRight */ + + +/**Function******************************************************************** + + Synopsis [Sets an arbitrary precision integer to a one-digit literal.] + + Description [Sets an arbitrary precision integer to a one-digit literal.] + + SideEffects [The result is returned in parameter number.] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_ApaSetToLiteral( + int digits, + DdApaNumber number, + DdApaDigit literal) +{ + int i; + + for (i = 0; i < digits - 1; i++) + number[i] = 0; + number[digits - 1] = literal; + +} /* end of Cudd_ApaSetToLiteral */ + + +/**Function******************************************************************** + + Synopsis [Sets an arbitrary precision integer to a power of two.] + + Description [Sets an arbitrary precision integer to a power of + two. If the power of two is too large to be represented, the number + is set to 0.] + + SideEffects [The result is returned in parameter number.] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_ApaPowerOfTwo( + int digits, + DdApaNumber number, + int power) +{ + int i; + int index; + + for (i = 0; i < digits; i++) + number[i] = 0; + i = digits - 1 - power / DD_APA_BITS; + if (i < 0) return; + index = power & (DD_APA_BITS - 1); + number[i] = 1 << index; + +} /* end of Cudd_ApaPowerOfTwo */ + + +/**Function******************************************************************** + + Synopsis [Compares two arbitrary precision integers.] + + Description [Compares two arbitrary precision integers. Returns 1 if + the first number is larger; 0 if they are equal; -1 if the second + number is larger.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_ApaCompare( + int digitsFirst, + DdApaNumber first, + int digitsSecond, + DdApaNumber second) +{ + int i; + int firstNZ, secondNZ; + + /* Find first non-zero in both numbers. */ + for (firstNZ = 0; firstNZ < digitsFirst; firstNZ++) + if (first[firstNZ] != 0) break; + for (secondNZ = 0; secondNZ < digitsSecond; secondNZ++) + if (second[secondNZ] != 0) break; + if (digitsFirst - firstNZ > digitsSecond - secondNZ) return(1); + else if (digitsFirst - firstNZ < digitsSecond - secondNZ) return(-1); + for (i = 0; i < digitsFirst - firstNZ; i++) { + if (first[firstNZ + i] > second[secondNZ + i]) return(1); + else if (first[firstNZ + i] < second[secondNZ + i]) return(-1); + } + return(0); + +} /* end of Cudd_ApaCompare */ + + +/**Function******************************************************************** + + Synopsis [Compares the ratios of two arbitrary precision integers to two + unsigned ints.] + + Description [Compares the ratios of two arbitrary precision integers + to two unsigned ints. Returns 1 if the first number is larger; 0 if + they are equal; -1 if the second number is larger.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_ApaCompareRatios( + int digitsFirst, + DdApaNumber firstNum, + unsigned int firstDen, + int digitsSecond, + DdApaNumber secondNum, + unsigned int secondDen) +{ + int result; + DdApaNumber first, second; + unsigned int firstRem, secondRem; + + first = Cudd_NewApaNumber(digitsFirst); + firstRem = Cudd_ApaIntDivision(digitsFirst,firstNum,firstDen,first); + second = Cudd_NewApaNumber(digitsSecond); + secondRem = Cudd_ApaIntDivision(digitsSecond,secondNum,secondDen,second); + result = Cudd_ApaCompare(digitsFirst,first,digitsSecond,second); + FREE(first); + FREE(second); + if (result == 0) { + if ((double)firstRem/firstDen > (double)secondRem/secondDen) + return(1); + else if ((double)firstRem/firstDen < (double)secondRem/secondDen) + return(-1); + } + return(result); + +} /* end of Cudd_ApaCompareRatios */ + + +/**Function******************************************************************** + + Synopsis [Prints an arbitrary precision integer in hexadecimal format.] + + Description [Prints an arbitrary precision integer in hexadecimal format. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_ApaPrintDecimal Cudd_ApaPrintExponential] + +******************************************************************************/ +int +Cudd_ApaPrintHex( + FILE * fp, + int digits, + DdApaNumber number) +{ + int i, result; + + for (i = 0; i < digits; i++) { + result = fprintf(fp,DD_APA_HEXPRINT,number[i]); + if (result == EOF) + return(0); + } + return(1); + +} /* end of Cudd_ApaPrintHex */ + + +/**Function******************************************************************** + + Synopsis [Prints an arbitrary precision integer in decimal format.] + + Description [Prints an arbitrary precision integer in decimal format. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_ApaPrintHex Cudd_ApaPrintExponential] + +******************************************************************************/ +int +Cudd_ApaPrintDecimal( + FILE * fp, + int digits, + DdApaNumber number) +{ + int i, result; + DdApaDigit remainder; + DdApaNumber work; + unsigned char *decimal; + int leadingzero; + int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1; + + work = Cudd_NewApaNumber(digits); + if (work == NULL) + return(0); + decimal = ALLOC(unsigned char, decimalDigits); + if (decimal == NULL) { + FREE(work); + return(0); + } + Cudd_ApaCopy(digits,number,work); + for (i = decimalDigits - 1; i >= 0; i--) { + remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work); + decimal[i] = (unsigned char) remainder; + } + FREE(work); + + leadingzero = 1; + for (i = 0; i < decimalDigits; i++) { + leadingzero = leadingzero && (decimal[i] == 0); + if ((!leadingzero) || (i == (decimalDigits - 1))) { + result = fprintf(fp,"%1d",decimal[i]); + if (result == EOF) { + FREE(decimal); + return(0); + } + } + } + FREE(decimal); + return(1); + +} /* end of Cudd_ApaPrintDecimal */ + + +/**Function******************************************************************** + + Synopsis [Prints an arbitrary precision integer in exponential format.] + + Description [Prints an arbitrary precision integer in exponential format. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_ApaPrintHex Cudd_ApaPrintDecimal] + +******************************************************************************/ +int +Cudd_ApaPrintExponential( + FILE * fp, + int digits, + DdApaNumber number, + int precision) +{ + int i, first, last, result; + DdApaDigit remainder; + DdApaNumber work; + unsigned char *decimal; + int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1; + + work = Cudd_NewApaNumber(digits); + if (work == NULL) + return(0); + decimal = ALLOC(unsigned char, decimalDigits); + if (decimal == NULL) { + FREE(work); + return(0); + } + Cudd_ApaCopy(digits,number,work); + first = decimalDigits - 1; + for (i = decimalDigits - 1; i >= 0; i--) { + remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work); + decimal[i] = (unsigned char) remainder; + if (remainder != 0) first = i; /* keep track of MS non-zero */ + } + FREE(work); + last = ddMin(first + precision, decimalDigits); + + for (i = first; i < last; i++) { + result = fprintf(fp,"%s%1d",i == first+1 ? "." : "", decimal[i]); + if (result == EOF) { + FREE(decimal); + return(0); + } + } + FREE(decimal); + result = fprintf(fp,"e+%d",decimalDigits - first - 1); + if (result == EOF) { + return(0); + } + return(1); + +} /* end of Cudd_ApaPrintExponential */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of minterms of a DD.] + + Description [Counts the number of minterms of a DD. The function is + assumed to depend on nvars variables. The minterm count is + represented as an arbitrary precision unsigned integer, to allow for + any number of variables CUDD supports. Returns a pointer to the + array representing the number of minterms of the function rooted at + node if successful; NULL otherwise.] + + SideEffects [The number of digits of the result is returned in + parameter digits.] + + SeeAlso [Cudd_CountMinterm] + +******************************************************************************/ +DdApaNumber +Cudd_ApaCountMinterm( + DdManager * manager, + DdNode * node, + int nvars, + int * digits) +{ + DdApaNumber max, min; + st_table *table; + DdApaNumber i,count; + + background = manager->background; + zero = Cudd_Not(manager->one); + + *digits = Cudd_ApaNumberOfDigits(nvars+1); + max = Cudd_NewApaNumber(*digits); + if (max == NULL) { + return(NULL); + } + Cudd_ApaPowerOfTwo(*digits,max,nvars); + min = Cudd_NewApaNumber(*digits); + if (min == NULL) { + FREE(max); + return(NULL); + } + Cudd_ApaSetToLiteral(*digits,min,0); + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) { + FREE(max); + FREE(min); + return(NULL); + } + i = cuddApaCountMintermAux(Cudd_Regular(node),*digits,max,min,table); + if (i == NULL) { + FREE(max); + FREE(min); + st_foreach(table, cuddApaStCountfree, NULL); + st_free_table(table); + return(NULL); + } + count = Cudd_NewApaNumber(*digits); + if (count == NULL) { + FREE(max); + FREE(min); + st_foreach(table, cuddApaStCountfree, NULL); + st_free_table(table); + if (Cudd_Regular(node)->ref == 1) FREE(i); + return(NULL); + } + if (Cudd_IsComplement(node)) { + (void) Cudd_ApaSubtract(*digits,max,i,count); + } else { + Cudd_ApaCopy(*digits,i,count); + } + FREE(max); + FREE(min); + st_foreach(table, cuddApaStCountfree, NULL); + st_free_table(table); + if (Cudd_Regular(node)->ref == 1) FREE(i); + return(count); + +} /* end of Cudd_ApaCountMinterm */ + + +/**Function******************************************************************** + + Synopsis [Prints the number of minterms of a BDD or ADD using + arbitrary precision arithmetic.] + + Description [Prints the number of minterms of a BDD or ADD using + arbitrary precision arithmetic. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_ApaPrintMintermExp] + +******************************************************************************/ +int +Cudd_ApaPrintMinterm( + FILE * fp, + DdManager * dd, + DdNode * node, + int nvars) +{ + int digits; + int result; + DdApaNumber count; + + count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); + if (count == NULL) + return(0); + result = Cudd_ApaPrintDecimal(fp,digits,count); + FREE(count); + if (fprintf(fp,"\n") == EOF) { + return(0); + } + return(result); + +} /* end of Cudd_ApaPrintMinterm */ + + +/**Function******************************************************************** + + Synopsis [Prints the number of minterms of a BDD or ADD in exponential + format using arbitrary precision arithmetic.] + + Description [Prints the number of minterms of a BDD or ADD in + exponential format using arbitrary precision arithmetic. Parameter + precision controls the number of signficant digits printed. Returns + 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_ApaPrintMinterm] + +******************************************************************************/ +int +Cudd_ApaPrintMintermExp( + FILE * fp, + DdManager * dd, + DdNode * node, + int nvars, + int precision) +{ + int digits; + int result; + DdApaNumber count; + + count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); + if (count == NULL) + return(0); + result = Cudd_ApaPrintExponential(fp,digits,count,precision); + FREE(count); + if (fprintf(fp,"\n") == EOF) { + return(0); + } + return(result); + +} /* end of Cudd_ApaPrintMintermExp */ + + +/**Function******************************************************************** + + Synopsis [Prints the density of a BDD or ADD using + arbitrary precision arithmetic.] + + Description [Prints the density of a BDD or ADD using + arbitrary precision arithmetic. Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_ApaPrintDensity( + FILE * fp, + DdManager * dd, + DdNode * node, + int nvars) +{ + int digits; + int result; + DdApaNumber count,density; + unsigned int size, remainder, fractional; + + count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); + if (count == NULL) + return(0); + size = Cudd_DagSize(node); + density = Cudd_NewApaNumber(digits); + remainder = Cudd_ApaIntDivision(digits,count,size,density); + result = Cudd_ApaPrintDecimal(fp,digits,density); + FREE(count); + FREE(density); + fractional = (unsigned int)((double)remainder / size * 1000000); + if (fprintf(fp,".%u\n", fractional) == EOF) { + return(0); + } + return(result); + +} /* end of Cudd_ApaPrintDensity */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_ApaCountMinterm.] + + Description [Performs the recursive step of Cudd_ApaCountMinterm. + It is based on the following identity. Let |f| be the + number of minterms of f. Then: + + |f| = (|f0|+|f1|)/2 + + where f0 and f1 are the two cofactors of f. + Uses the identity |f'| = max - |f|. + The procedure expects the argument "node" to be a regular pointer, and + guarantees this condition is met in the recursive calls. + For efficiency, the result of a call is cached only if the node has + a reference count greater than 1. + Returns the number of minterms of the function rooted at node.] + + SideEffects [None] + +******************************************************************************/ +static DdApaNumber +cuddApaCountMintermAux( + DdNode * node, + int digits, + DdApaNumber max, + DdApaNumber min, + st_table * table) +{ + DdNode *Nt, *Ne; + DdApaNumber mint, mint1, mint2; + DdApaDigit carryout; + + if (cuddIsConstant(node)) { + if (node == background || node == zero) { + return(min); + } else { + return(max); + } + } + if (node->ref > 1 && st_lookup(table, node, &mint)) { + return(mint); + } + + Nt = cuddT(node); Ne = cuddE(node); + + mint1 = cuddApaCountMintermAux(Nt, digits, max, min, table); + if (mint1 == NULL) return(NULL); + mint2 = cuddApaCountMintermAux(Cudd_Regular(Ne), digits, max, min, table); + if (mint2 == NULL) { + if (Nt->ref == 1) FREE(mint1); + return(NULL); + } + mint = Cudd_NewApaNumber(digits); + if (mint == NULL) { + if (Nt->ref == 1) FREE(mint1); + if (Cudd_Regular(Ne)->ref == 1) FREE(mint2); + return(NULL); + } + if (Cudd_IsComplement(Ne)) { + (void) Cudd_ApaSubtract(digits,max,mint2,mint); + carryout = Cudd_ApaAdd(digits,mint1,mint,mint); + } else { + carryout = Cudd_ApaAdd(digits,mint1,mint2,mint); + } + Cudd_ApaShiftRight(digits,carryout,mint,mint); + /* If the refernce count of a child is 1, its minterm count + ** hasn't been stored in table. Therefore, it must be explicitly + ** freed here. */ + if (Nt->ref == 1) FREE(mint1); + if (Cudd_Regular(Ne)->ref == 1) FREE(mint2); + + if (node->ref > 1) { + if (st_insert(table, (char *)node, (char *)mint) == ST_OUT_OF_MEM) { + FREE(mint); + return(NULL); + } + } + return(mint); + +} /* end of cuddApaCountMintermAux */ + + +/**Function******************************************************************** + + Synopsis [Frees the memory used to store the minterm counts recorded + in the visited table.] + + Description [Frees the memory used to store the minterm counts + recorded in the visited table. Returns ST_CONTINUE.] + + SideEffects [None] + +******************************************************************************/ +static enum st_retval +cuddApaStCountfree( + char * key, + char * value, + char * arg) +{ + DdApaNumber d; + + d = (DdApaNumber) value; + FREE(d); + return(ST_CONTINUE); + +} /* end of cuddApaStCountfree */ diff --git a/cudd_local/cudd/cuddApprox.c b/cudd_local/cudd/cuddApprox.c new file mode 100644 index 0000000..23f9741 --- /dev/null +++ b/cudd_local/cudd/cuddApprox.c @@ -0,0 +1,2204 @@ +/**CFile*********************************************************************** + + FileName [cuddApprox.c] + + PackageName [cudd] + + Synopsis [Procedures to approximate a given BDD.] + + Description [External procedures provided by this module: + + Internal procedures included in this module: + + Static procedures included in this module: + + ] + + SeeAlso [cuddSubsetHB.c cuddSubsetSP.c cuddGenCof.c] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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.] + +******************************************************************************/ + +#ifdef __STDC__ +#include +#else +#define DBL_MAX_EXP 1024 +#endif +#include "util.h" +#include "cuddInt.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +#define NOTHING 0 +#define REPLACE_T 1 +#define REPLACE_E 2 +#define REPLACE_N 3 +#define REPLACE_TT 4 +#define REPLACE_TE 5 + +#define DONT_CARE 0 +#define CARE 1 +#define TOTAL_CARE 2 +#define CARE_ERROR 3 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/* Data structure to store the information on each node. It keeps the +** number of minterms of the function rooted at this node in terms of +** the number of variables specified by the user; the number of +** minterms of the complement; the impact of the number of minterms of +** this function on the number of minterms of the root function; the +** reference count of the node from within the root function; the +** flag that says whether the node intersects the care set; the flag +** that says whether the node should be replaced and how; the results +** of subsetting in both phases. */ +typedef struct NodeData { + double mintermsP; /* minterms for the regular node */ + double mintermsN; /* minterms for the complemented node */ + int functionRef; /* references from within this function */ + char care; /* node intersects care set */ + char replace; /* replacement decision */ + short int parity; /* 1: even; 2: odd; 3: both */ + DdNode *resultP; /* result for even parity */ + DdNode *resultN; /* result for odd parity */ +} NodeData; + +typedef struct ApproxInfo { + DdNode *one; /* one constant */ + DdNode *zero; /* BDD zero constant */ + NodeData *page; /* per-node information */ + DdHashTable *table; /* hash table to access the per-node info */ + int index; /* index of the current node */ + double max; /* max number of minterms */ + int size; /* how many nodes are left */ + double minterms; /* how many minterms are left */ +} ApproxInfo; + +/* Item of the queue used in the levelized traversal of the BDD. */ +typedef struct GlobalQueueItem { + struct GlobalQueueItem *next; + struct GlobalQueueItem *cnext; + DdNode *node; + double impactP; + double impactN; +} GlobalQueueItem; + +typedef struct LocalQueueItem { + struct LocalQueueItem *next; + struct LocalQueueItem *cnext; + DdNode *node; + int localRef; +} LocalQueueItem; + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddApprox.c,v 1.31 2012/02/05 04:38:07 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void updateParity (DdNode *node, ApproxInfo *info, int newparity); +static NodeData * gatherInfoAux (DdNode *node, ApproxInfo *info, int parity); +static ApproxInfo * gatherInfo (DdManager *dd, DdNode *node, int numVars, int parity); +static int computeSavings (DdManager *dd, DdNode *f, DdNode *skip, ApproxInfo *info, DdLevelQueue *queue); +static int updateRefs (DdManager *dd, DdNode *f, DdNode *skip, ApproxInfo *info, DdLevelQueue *queue); +static int UAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, int safe, double quality); +static DdNode * UAbuildSubset (DdManager *dd, DdNode *node, ApproxInfo *info); +static int RAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality); +static int BAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality1, double quality0); +static DdNode * RAbuildSubset (DdManager *dd, DdNode *node, ApproxInfo *info); +static int BAapplyBias (DdManager *dd, DdNode *f, DdNode *b, ApproxInfo *info, DdHashTable *cache); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Extracts a dense subset from a BDD with Shiple's + underapproximation method.] + + Description [Extracts a dense subset from a BDD. This procedure uses + a variant of Tom Shiple's underapproximation method. The main + difference from the original method is that density is used as cost + function. Returns a pointer to the BDD of the subset if + successful. NULL if the procedure runs out of memory. The parameter + numVars is the maximum number of variables to be used in minterm + calculation. The optimal number should be as close as possible to + the size of the support of f. However, it is safe to pass the value + returned by Cudd_ReadSize for numVars when the number of variables + is under 1023. If numVars is larger than 1023, it will cause + overflow. If a 0 parameter is passed then the procedure will compute + a value which will avoid overflow but will cause underflow with 2046 + variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_UnderApprox( + DdManager * dd /* manager */, + DdNode * f /* function to be subset */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + int safe /* enforce safe approximation */, + double quality /* minimum improvement for accepted changes */) +{ + DdNode *subset; + + do { + dd->reordered = 0; + subset = cuddUnderApprox(dd, f, numVars, threshold, safe, quality); + } while (dd->reordered == 1); + + return(subset); + +} /* end of Cudd_UnderApprox */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense superset from a BDD with Shiple's + underapproximation method.] + + Description [Extracts a dense superset from a BDD. The procedure is + identical to the underapproximation procedure except for the fact that it + works on the complement of the given function. Extracting the subset + of the complement function is equivalent to extracting the superset + of the function. + Returns a pointer to the BDD of the superset if successful. NULL if + intermediate result causes the procedure to run out of memory. The + parameter numVars is the maximum number of variables to be used in + minterm calculation. The optimal number + should be as close as possible to the size of the support of f. + However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is + larger than 1023, it will overflow. If a 0 parameter is passed then + the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_OverApprox( + DdManager * dd /* manager */, + DdNode * f /* function to be superset */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + int safe /* enforce safe approximation */, + double quality /* minimum improvement for accepted changes */) +{ + DdNode *subset, *g; + + g = Cudd_Not(f); + do { + dd->reordered = 0; + subset = cuddUnderApprox(dd, g, numVars, threshold, safe, quality); + } while (dd->reordered == 1); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_OverApprox */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense subset from a BDD with the remapping + underapproximation method.] + + Description [Extracts a dense subset from a BDD. This procedure uses + a remapping technique and density as the cost function. + Returns a pointer to the BDD of the subset if + successful. NULL if the procedure runs out of memory. The parameter + numVars is the maximum number of variables to be used in minterm + calculation. The optimal number should be as close as possible to + the size of the support of f. However, it is safe to pass the value + returned by Cudd_ReadSize for numVars when the number of variables + is under 1023. If numVars is larger than 1023, it will cause + overflow. If a 0 parameter is passed then the procedure will compute + a value which will avoid overflow but will cause underflow with 2046 + variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_UnderApprox Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_RemapUnderApprox( + DdManager * dd /* manager */, + DdNode * f /* function to be subset */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + double quality /* minimum improvement for accepted changes */) +{ + DdNode *subset; + + do { + dd->reordered = 0; + subset = cuddRemapUnderApprox(dd, f, numVars, threshold, quality); + } while (dd->reordered == 1); + + return(subset); + +} /* end of Cudd_RemapUnderApprox */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense superset from a BDD with the remapping + underapproximation method.] + + Description [Extracts a dense superset from a BDD. The procedure is + identical to the underapproximation procedure except for the fact that it + works on the complement of the given function. Extracting the subset + of the complement function is equivalent to extracting the superset + of the function. + Returns a pointer to the BDD of the superset if successful. NULL if + intermediate result causes the procedure to run out of memory. The + parameter numVars is the maximum number of variables to be used in + minterm calculation. The optimal number + should be as close as possible to the size of the support of f. + However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is + larger than 1023, it will overflow. If a 0 parameter is passed then + the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_RemapOverApprox( + DdManager * dd /* manager */, + DdNode * f /* function to be superset */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + double quality /* minimum improvement for accepted changes */) +{ + DdNode *subset, *g; + + g = Cudd_Not(f); + do { + dd->reordered = 0; + subset = cuddRemapUnderApprox(dd, g, numVars, threshold, quality); + } while (dd->reordered == 1); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_RemapOverApprox */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense subset from a BDD with the biased + underapproximation method.] + + Description [Extracts a dense subset from a BDD. This procedure uses + a biased remapping technique and density as the cost function. The bias + is a function. This procedure tries to approximate where the bias is 0 + and preserve the given function where the bias is 1. + Returns a pointer to the BDD of the subset if + successful. NULL if the procedure runs out of memory. The parameter + numVars is the maximum number of variables to be used in minterm + calculation. The optimal number should be as close as possible to + the size of the support of f. However, it is safe to pass the value + returned by Cudd_ReadSize for numVars when the number of variables + is under 1023. If numVars is larger than 1023, it will cause + overflow. If a 0 parameter is passed then the procedure will compute + a value which will avoid overflow but will cause underflow with 2046 + variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_UnderApprox + Cudd_RemapUnderApprox Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_BiasedUnderApprox( + DdManager *dd /* manager */, + DdNode *f /* function to be subset */, + DdNode *b /* bias function */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + double quality1 /* minimum improvement for accepted changes when b=1 */, + double quality0 /* minimum improvement for accepted changes when b=0 */) +{ + DdNode *subset; + + do { + dd->reordered = 0; + subset = cuddBiasedUnderApprox(dd, f, b, numVars, threshold, quality1, + quality0); + } while (dd->reordered == 1); + + return(subset); + +} /* end of Cudd_BiasedUnderApprox */ + + +/**Function******************************************************************** + + Synopsis [Extracts a dense superset from a BDD with the biased + underapproximation method.] + + Description [Extracts a dense superset from a BDD. The procedure is + identical to the underapproximation procedure except for the fact that it + works on the complement of the given function. Extracting the subset + of the complement function is equivalent to extracting the superset + of the function. + Returns a pointer to the BDD of the superset if successful. NULL if + intermediate result causes the procedure to run out of memory. The + parameter numVars is the maximum number of variables to be used in + minterm calculation. The optimal number + should be as close as possible to the size of the support of f. + However, it is safe to pass the value returned by Cudd_ReadSize for + numVars when the number of variables is under 1023. If numVars is + larger than 1023, it will overflow. If a 0 parameter is passed then + the procedure will compute a value which will avoid overflow but + will cause underflow with 2046 variables or more.] + + SideEffects [None] + + SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths + Cudd_RemapOverApprox Cudd_BiasedUnderApprox Cudd_ReadSize] + +******************************************************************************/ +DdNode * +Cudd_BiasedOverApprox( + DdManager *dd /* manager */, + DdNode *f /* function to be superset */, + DdNode *b /* bias function */, + int numVars /* number of variables in the support of f */, + int threshold /* when to stop approximation */, + double quality1 /* minimum improvement for accepted changes when b=1*/, + double quality0 /* minimum improvement for accepted changes when b=0 */) +{ + DdNode *subset, *g; + + g = Cudd_Not(f); + do { + dd->reordered = 0; + subset = cuddBiasedUnderApprox(dd, g, b, numVars, threshold, quality1, + quality0); + } while (dd->reordered == 1); + + return(Cudd_NotCond(subset, (subset != NULL))); + +} /* end of Cudd_BiasedOverApprox */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Applies Tom Shiple's underappoximation algorithm.] + + Description [Applies Tom Shiple's underappoximation algorithm. Proceeds + in three phases: +
    +
  • collect information on each node in the BDD; this is done via DFS. +
  • traverse the BDD in top-down fashion and compute for each node + whether its elimination increases density. +
  • traverse the BDD via DFS and actually perform the elimination. +
+ Returns the approximated BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_UnderApprox] + +******************************************************************************/ +DdNode * +cuddUnderApprox( + DdManager * dd /* DD manager */, + DdNode * f /* current DD */, + int numVars /* maximum number of variables */, + int threshold /* threshold under which approximation stops */, + int safe /* enforce safe approximation */, + double quality /* minimum improvement for accepted changes */) +{ + ApproxInfo *info; + DdNode *subset; + int result; + + if (f == NULL) { + fprintf(dd->err, "Cannot subset, nil object\n"); + return(NULL); + } + + if (Cudd_IsConstant(f)) { + return(f); + } + + /* Create table where node data are accessible via a hash table. */ + info = gatherInfo(dd, f, numVars, safe); + if (info == NULL) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + /* Mark nodes that should be replaced by zero. */ + result = UAmarkNodes(dd, f, info, threshold, safe, quality); + if (result == 0) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + /* Build the result. */ + subset = UAbuildSubset(dd, f, info); +#if 1 + if (subset && info->size < Cudd_DagSize(subset)) + (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", + info->size, Cudd_DagSize(subset)); +#endif + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + +#ifdef DD_DEBUG + if (subset != NULL) { + cuddRef(subset); +#if 0 + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); +#endif + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong subset\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + } + cuddDeref(subset); + } +#endif + return(subset); + +} /* end of cuddUnderApprox */ + + +/**Function******************************************************************** + + Synopsis [Applies the remapping underappoximation algorithm.] + + Description [Applies the remapping underappoximation algorithm. + Proceeds in three phases: +
    +
  • collect information on each node in the BDD; this is done via DFS. +
  • traverse the BDD in top-down fashion and compute for each node + whether remapping increases density. +
  • traverse the BDD via DFS and actually perform the elimination. +
+ Returns the approximated BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_RemapUnderApprox] + +******************************************************************************/ +DdNode * +cuddRemapUnderApprox( + DdManager * dd /* DD manager */, + DdNode * f /* current DD */, + int numVars /* maximum number of variables */, + int threshold /* threshold under which approximation stops */, + double quality /* minimum improvement for accepted changes */) +{ + ApproxInfo *info; + DdNode *subset; + int result; + + if (f == NULL) { + fprintf(dd->err, "Cannot subset, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + if (Cudd_IsConstant(f)) { + return(f); + } + + /* Create table where node data are accessible via a hash table. */ + info = gatherInfo(dd, f, numVars, CUDD_TRUE); + if (info == NULL) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + /* Mark nodes that should be replaced by zero. */ + result = RAmarkNodes(dd, f, info, threshold, quality); + if (result == 0) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + /* Build the result. */ + subset = RAbuildSubset(dd, f, info); +#if 1 + if (subset && info->size < Cudd_DagSize(subset)) + (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", + info->size, Cudd_DagSize(subset)); +#endif + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + +#ifdef DD_DEBUG + if (subset != NULL) { + cuddRef(subset); +#if 0 + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); +#endif + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong subset\n"); + } + cuddDeref(subset); + dd->errorCode = CUDD_INTERNAL_ERROR; + } +#endif + return(subset); + +} /* end of cuddRemapUnderApprox */ + + +/**Function******************************************************************** + + Synopsis [Applies the biased remapping underappoximation algorithm.] + + Description [Applies the biased remapping underappoximation algorithm. + Proceeds in three phases: +
    +
  • collect information on each node in the BDD; this is done via DFS. +
  • traverse the BDD in top-down fashion and compute for each node + whether remapping increases density. +
  • traverse the BDD via DFS and actually perform the elimination. +
+ Returns the approximated BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_BiasedUnderApprox] + +******************************************************************************/ +DdNode * +cuddBiasedUnderApprox( + DdManager *dd /* DD manager */, + DdNode *f /* current DD */, + DdNode *b /* bias function */, + int numVars /* maximum number of variables */, + int threshold /* threshold under which approximation stops */, + double quality1 /* minimum improvement for accepted changes when b=1 */, + double quality0 /* minimum improvement for accepted changes when b=0 */) +{ + ApproxInfo *info; + DdNode *subset; + int result; + DdHashTable *cache; + + if (f == NULL) { + fprintf(dd->err, "Cannot subset, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + if (Cudd_IsConstant(f)) { + return(f); + } + + /* Create table where node data are accessible via a hash table. */ + info = gatherInfo(dd, f, numVars, CUDD_TRUE); + if (info == NULL) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + cache = cuddHashTableInit(dd,2,2); + result = BAapplyBias(dd, Cudd_Regular(f), b, info, cache); + if (result == CARE_ERROR) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + cuddHashTableQuit(cache); + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + cuddHashTableQuit(cache); + + /* Mark nodes that should be replaced by zero. */ + result = BAmarkNodes(dd, f, info, threshold, quality1, quality0); + if (result == 0) { + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + /* Build the result. */ + subset = RAbuildSubset(dd, f, info); +#if 1 + if (subset && info->size < Cudd_DagSize(subset)) + (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", + info->size, Cudd_DagSize(subset)); +#endif + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + +#ifdef DD_DEBUG + if (subset != NULL) { + cuddRef(subset); +#if 0 + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); +#endif + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong subset\n"); + } + cuddDeref(subset); + dd->errorCode = CUDD_INTERNAL_ERROR; + } +#endif + return(subset); + +} /* end of cuddBiasedUnderApprox */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Recursively update the parity of the paths reaching a node.] + + Description [Recursively update the parity of the paths reaching a node. + Assumes that node is regular and propagates the invariant.] + + SideEffects [None] + + SeeAlso [gatherInfoAux] + +******************************************************************************/ +static void +updateParity( + DdNode * node /* function to analyze */, + ApproxInfo * info /* info on BDD */, + int newparity /* new parity for node */) +{ + NodeData *infoN; + DdNode *E; + + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node)) == NULL) + return; + if ((infoN->parity & newparity) != 0) return; + infoN->parity |= (short) newparity; + if (Cudd_IsConstant(node)) return; + updateParity(cuddT(node),info,newparity); + E = cuddE(node); + if (Cudd_IsComplement(E)) { + updateParity(Cudd_Not(E),info,3-newparity); + } else { + updateParity(E,info,newparity); + } + return; + +} /* end of updateParity */ + + +/**Function******************************************************************** + + Synopsis [Recursively counts minterms and computes reference counts + of each node in the BDD.] + + Description [Recursively counts minterms and computes reference + counts of each node in the BDD. Similar to the cuddCountMintermAux + which recursively counts the number of minterms for the dag rooted + at each node in terms of the total number of variables (max). It assumes + that the node pointer passed to it is regular and it maintains the + invariant.] + + SideEffects [None] + + SeeAlso [gatherInfo] + +******************************************************************************/ +static NodeData * +gatherInfoAux( + DdNode * node /* function to analyze */, + ApproxInfo * info /* info on BDD */, + int parity /* gather parity information */) +{ + DdNode *N, *Nt, *Ne; + NodeData *infoN, *infoT, *infoE; + + N = Cudd_Regular(node); + + /* Check whether entry for this node exists. */ + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, N)) != NULL) { + if (parity) { + /* Update parity and propagate. */ + updateParity(N, info, 1 + (int) Cudd_IsComplement(node)); + } + return(infoN); + } + + /* Compute the cofactors. */ + Nt = Cudd_NotCond(cuddT(N), N != node); + Ne = Cudd_NotCond(cuddE(N), N != node); + + infoT = gatherInfoAux(Nt, info, parity); + if (infoT == NULL) return(NULL); + infoE = gatherInfoAux(Ne, info, parity); + if (infoE == NULL) return(NULL); + + infoT->functionRef++; + infoE->functionRef++; + + /* Point to the correct location in the page. */ + infoN = &(info->page[info->index++]); + infoN->parity |= (short) (1 + Cudd_IsComplement(node)); + + infoN->mintermsP = infoT->mintermsP/2; + infoN->mintermsN = infoT->mintermsN/2; + if (Cudd_IsComplement(Ne) ^ Cudd_IsComplement(node)) { + infoN->mintermsP += infoE->mintermsN/2; + infoN->mintermsN += infoE->mintermsP/2; + } else { + infoN->mintermsP += infoE->mintermsP/2; + infoN->mintermsN += infoE->mintermsN/2; + } + + /* Insert entry for the node in the table. */ + if (cuddHashTableGenericInsert(info->table, N, infoN) == 0) { + return(NULL); + } + return(infoN); + +} /* end of gatherInfoAux */ + + +/**Function******************************************************************** + + Synopsis [Gathers information about each node.] + + Description [Counts minterms and computes reference counts of each + node in the BDD. The minterm count is separately computed for the + node and its complement. This is to avoid cancellation + errors. Returns a pointer to the data structure holding the + information gathered if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddUnderApprox gatherInfoAux] + +******************************************************************************/ +static ApproxInfo * +gatherInfo( + DdManager * dd /* manager */, + DdNode * node /* function to be analyzed */, + int numVars /* number of variables node depends on */, + int parity /* gather parity information */) +{ + ApproxInfo * info; + NodeData * infoTop; + + /* If user did not give numVars value, set it to the maximum + ** exponent that the pow function can take. The -1 is due to the + ** discrepancy in the value that pow takes and the value that + ** log gives. + */ + if (numVars == 0) { + numVars = DBL_MAX_EXP - 1; + } + + info = ALLOC(ApproxInfo,1); + if (info == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + info->max = pow(2.0,(double) numVars); + info->one = DD_ONE(dd); + info->zero = Cudd_Not(info->one); + info->size = Cudd_DagSize(node); + /* All the information gathered will be stored in a contiguous + ** piece of memory, which is allocated here. This can be done + ** efficiently because we have counted the number of nodes of the + ** BDD. info->index points to the next available entry in the array + ** that stores the per-node information. */ + info->page = ALLOC(NodeData,info->size); + if (info->page == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(info); + return(NULL); + } + memset(info->page, 0, info->size * sizeof(NodeData)); /* clear all page */ + info->table = cuddHashTableInit(dd,1,info->size); + if (info->table == NULL) { + FREE(info->page); + FREE(info); + return(NULL); + } + /* We visit the DAG in post-order DFS. Hence, the constant node is + ** in first position, and the root of the DAG is in last position. */ + + /* Info for the constant node: Initialize only fields different from 0. */ + if (cuddHashTableGenericInsert(info->table, info->one, info->page) == 0) { + FREE(info->page); + FREE(info); + cuddHashTableGenericQuit(info->table); + return(NULL); + } + info->page[0].mintermsP = info->max; + info->index = 1; + + infoTop = gatherInfoAux(node,info,parity); + if (infoTop == NULL) { + FREE(info->page); + cuddHashTableGenericQuit(info->table); + FREE(info); + return(NULL); + } + if (Cudd_IsComplement(node)) { + info->minterms = infoTop->mintermsN; + } else { + info->minterms = infoTop->mintermsP; + } + + infoTop->functionRef = 1; + return(info); + +} /* end of gatherInfo */ + + +/**Function******************************************************************** + + Synopsis [Counts the nodes that would be eliminated if a given node + were replaced by zero.] + + Description [Counts the nodes that would be eliminated if a given + node were replaced by zero. This procedure uses a queue passed by + the caller for efficiency: since the queue is left empty at the + endof the search, it can be reused as is by the next search. Returns + the count (always striclty positive) if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [UAmarkNodes RAmarkNodes BAmarkNodes] + +******************************************************************************/ +static int +computeSavings( + DdManager * dd, + DdNode * f, + DdNode * skip, + ApproxInfo * info, + DdLevelQueue * queue) +{ + NodeData *infoN; + LocalQueueItem *item; + DdNode *node; + int savings = 0; + + node = Cudd_Regular(f); + skip = Cudd_Regular(skip); + /* Insert the given node in the level queue. Its local reference + ** count is set equal to the function reference count so that the + ** search will continue from it when it is retrieved. */ + item = (LocalQueueItem *) + cuddLevelQueueFirst(queue,node,cuddI(dd,node->index)); + if (item == NULL) + return(0); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node); + item->localRef = infoN->functionRef; + + /* Process the queue. */ + while ((item = (LocalQueueItem *) queue->first) != NULL) { + node = item->node; + if (node != skip) { + infoN = (NodeData *) cuddHashTableGenericLookup(info->table,node); + if (item->localRef == infoN->functionRef) { + /* This node is not shared. */ + DdNode *nodeT, *nodeE; + savings++; + nodeT = cuddT(node); + if (!cuddIsConstant(nodeT)) { + item = (LocalQueueItem *) + cuddLevelQueueEnqueue(queue,nodeT,cuddI(dd,nodeT->index)); + if (item == NULL) return(0); + item->localRef++; + } + nodeE = Cudd_Regular(cuddE(node)); + if (!cuddIsConstant(nodeE)) { + item = (LocalQueueItem *) + cuddLevelQueueEnqueue(queue,nodeE,cuddI(dd,nodeE->index)); + if (item == NULL) return(0); + item->localRef++; + } + } + } + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + } + +#ifdef DD_DEBUG + /* At the end of a local search the queue should be empty. */ + assert(queue->size == 0); +#endif + return(savings); + +} /* end of computeSavings */ + + +/**Function******************************************************************** + + Synopsis [Update function reference counts.] + + Description [Update function reference counts to account for replacement. + Returns the number of nodes saved if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [UAmarkNodes RAmarkNodes BAmarkNodes] + +******************************************************************************/ +static int +updateRefs( + DdManager * dd, + DdNode * f, + DdNode * skip, + ApproxInfo * info, + DdLevelQueue * queue) +{ + NodeData *infoN; + LocalQueueItem *item; + DdNode *node; + int savings = 0; + + node = Cudd_Regular(f); + /* Insert the given node in the level queue. Its function reference + ** count is set equal to 0 so that the search will continue from it + ** when it is retrieved. */ + item = (LocalQueueItem *) cuddLevelQueueFirst(queue,node,cuddI(dd,node->index)); + if (item == NULL) + return(0); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node); + infoN->functionRef = 0; + + if (skip != NULL) { + /* Increase the function reference count of the node to be skipped + ** by 1 to account for the node pointing to it that will be created. */ + skip = Cudd_Regular(skip); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table, skip); + infoN->functionRef++; + } + + /* Process the queue. */ + while ((item = (LocalQueueItem *) queue->first) != NULL) { + node = item->node; + infoN = (NodeData *) cuddHashTableGenericLookup(info->table,node); + if (infoN->functionRef == 0) { + /* This node is not shared or to be be skipped. */ + DdNode *nodeT, *nodeE; + savings++; + nodeT = cuddT(node); + if (!cuddIsConstant(nodeT)) { + item = (LocalQueueItem *) + cuddLevelQueueEnqueue(queue,nodeT,cuddI(dd,nodeT->index)); + if (item == NULL) return(0); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table,nodeT); + infoN->functionRef--; + } + nodeE = Cudd_Regular(cuddE(node)); + if (!cuddIsConstant(nodeE)) { + item = (LocalQueueItem *) + cuddLevelQueueEnqueue(queue,nodeE,cuddI(dd,nodeE->index)); + if (item == NULL) return(0); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table,nodeE); + infoN->functionRef--; + } + } + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + } + +#ifdef DD_DEBUG + /* At the end of a local search the queue should be empty. */ + assert(queue->size == 0); +#endif + return(savings); + +} /* end of updateRefs */ + + +/**Function******************************************************************** + + Synopsis [Marks nodes for replacement by zero.] + + Description [Marks nodes for replacement by zero. Returns 1 if successful; + 0 otherwise.] + + SideEffects [None] + + SeeAlso [cuddUnderApprox] + +******************************************************************************/ +static int +UAmarkNodes( + DdManager * dd /* manager */, + DdNode * f /* function to be analyzed */, + ApproxInfo * info /* info on BDD */, + int threshold /* when to stop approximating */, + int safe /* enforce safe approximation */, + double quality /* minimum improvement for accepted changes */) +{ + DdLevelQueue *queue; + DdLevelQueue *localQueue; + NodeData *infoN; + GlobalQueueItem *item; + DdNode *node; + double numOnset; + double impactP, impactN; + int savings; + +#if 0 + (void) printf("initial size = %d initial minterms = %g\n", + info->size, info->minterms); +#endif + queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size); + if (queue == NULL) { + return(0); + } + localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem), + dd->initSlots); + if (localQueue == NULL) { + cuddLevelQueueQuit(queue); + return(0); + } + node = Cudd_Regular(f); + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); + if (item == NULL) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + if (Cudd_IsComplement(f)) { + item->impactP = 0.0; + item->impactN = 1.0; + } else { + item->impactP = 1.0; + item->impactN = 0.0; + } + while (queue->first != NULL) { + /* If the size of the subset is below the threshold, quit. */ + if (info->size <= threshold) + break; + item = (GlobalQueueItem *) queue->first; + node = item->node; + node = Cudd_Regular(node); + infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node); + if (safe && infoN->parity == 3) { + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + continue; + } + impactP = item->impactP; + impactN = item->impactN; + numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; + savings = computeSavings(dd,node,NULL,info,localQueue); + if (savings == 0) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); +#if 0 + (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", + node, impactP, impactN, numOnset, savings); +#endif + if ((1 - numOnset / info->minterms) > + quality * (1 - (double) savings / info->size)) { + infoN->replace = CUDD_TRUE; + info->size -= savings; + info->minterms -=numOnset; +#if 0 + (void) printf("replace: new size = %d new minterms = %g\n", + info->size, info->minterms); +#endif + savings -= updateRefs(dd,node,NULL,info,localQueue); + assert(savings == 0); + continue; + } + if (!cuddIsConstant(cuddT(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + if (!Cudd_IsConstant(cuddE(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (Cudd_IsComplement(cuddE(node))) { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + } + + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(1); + +} /* end of UAmarkNodes */ + + +/**Function******************************************************************** + + Synopsis [Builds the subset BDD.] + + Description [Builds the subset BDD. Based on the info table, + replaces selected nodes by zero. Returns a pointer to the result if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddUnderApprox] + +******************************************************************************/ +static DdNode * +UAbuildSubset( + DdManager * dd /* DD manager */, + DdNode * node /* current node */, + ApproxInfo * info /* node info */) +{ + + DdNode *Nt, *Ne, *N, *t, *e, *r; + NodeData *infoN; + + if (Cudd_IsConstant(node)) + return(node); + + N = Cudd_Regular(node); + + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, N)) != NULL) { + if (infoN->replace == CUDD_TRUE) { + return(info->zero); + } + if (N == node ) { + if (infoN->resultP != NULL) { + return(infoN->resultP); + } + } else { + if (infoN->resultN != NULL) { + return(infoN->resultN); + } + } + } else { + (void) fprintf(dd->err, + "Something is wrong, ought to be in info table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + + Nt = Cudd_NotCond(cuddT(N), Cudd_IsComplement(node)); + Ne = Cudd_NotCond(cuddE(N), Cudd_IsComplement(node)); + + t = UAbuildSubset(dd, Nt, info); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + + e = UAbuildSubset(dd, Ne, info); + if (e == NULL) { + Cudd_RecursiveDeref(dd,t); + return(NULL); + } + cuddRef(e); + + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + + if (N == node) { + infoN->resultP = r; + } else { + infoN->resultN = r; + } + + return(r); + +} /* end of UAbuildSubset */ + + +/**Function******************************************************************** + + Synopsis [Marks nodes for remapping.] + + Description [Marks nodes for remapping. Returns 1 if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddRemapUnderApprox] + +******************************************************************************/ +static int +RAmarkNodes( + DdManager * dd /* manager */, + DdNode * f /* function to be analyzed */, + ApproxInfo * info /* info on BDD */, + int threshold /* when to stop approximating */, + double quality /* minimum improvement for accepted changes */) +{ + DdLevelQueue *queue; + DdLevelQueue *localQueue; + NodeData *infoN, *infoT, *infoE; + GlobalQueueItem *item; + DdNode *node, *T, *E; + DdNode *shared; /* grandchild shared by the two children of node */ + double numOnset; + double impact, impactP, impactN; + double minterms; + int savings; + int replace; + +#if 0 + (void) fprintf(dd->out,"initial size = %d initial minterms = %g\n", + info->size, info->minterms); +#endif + queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size); + if (queue == NULL) { + return(0); + } + localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem), + dd->initSlots); + if (localQueue == NULL) { + cuddLevelQueueQuit(queue); + return(0); + } + /* Enqueue regular pointer to root and initialize impact. */ + node = Cudd_Regular(f); + item = (GlobalQueueItem *) + cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); + if (item == NULL) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + if (Cudd_IsComplement(f)) { + item->impactP = 0.0; + item->impactN = 1.0; + } else { + item->impactP = 1.0; + item->impactN = 0.0; + } + /* The nodes retrieved here are guaranteed to be non-terminal. + ** The initial node is not terminal because constant nodes are + ** dealt with in the calling procedure. Subsequent nodes are inserted + ** only if they are not terminal. */ + while ((item = (GlobalQueueItem *) queue->first) != NULL) { + /* If the size of the subset is below the threshold, quit. */ + if (info->size <= threshold) + break; + node = item->node; +#ifdef DD_DEBUG + assert(item->impactP >= 0 && item->impactP <= 1.0); + assert(item->impactN >= 0 && item->impactN <= 1.0); + assert(!Cudd_IsComplement(node)); + assert(!Cudd_IsConstant(node)); +#endif + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node)) == NULL) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } +#ifdef DD_DEBUG + assert(infoN->parity >= 1 && infoN->parity <= 3); +#endif + if (infoN->parity == 3) { + /* This node can be reached through paths of different parity. + ** It is not safe to replace it, because remapping will give + ** an incorrect result, while replacement by 0 may cause node + ** splitting. */ + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + continue; + } + T = cuddT(node); + E = cuddE(node); + shared = NULL; + impactP = item->impactP; + impactN = item->impactN; + if (Cudd_bddLeq(dd,T,E)) { + /* Here we know that E is regular. */ +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(E)); +#endif + infoT = (NodeData *) cuddHashTableGenericLookup(info->table, T); + infoE = (NodeData *) cuddHashTableGenericLookup(info->table, E); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoE->mintermsP/2.0 - infoT->mintermsP/2.0; + if (infoE->functionRef == 1 && !cuddIsConstant(E)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; + } else { +#ifdef DD_DEBUG + assert(infoN->parity == 2); +#endif + impact = impactN; + minterms = infoT->mintermsN/2.0 - infoE->mintermsN/2.0; + if (infoT->functionRef == 1 && !cuddIsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; + } + numOnset = impact * minterms; + } else if (Cudd_bddLeq(dd,E,T)) { + /* Here E may be complemented. */ + DdNode *Ereg = Cudd_Regular(E); + infoT = (NodeData *) cuddHashTableGenericLookup(info->table, T); + infoE = (NodeData *) cuddHashTableGenericLookup(info->table, Ereg); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoT->mintermsP/2.0 - + ((E == Ereg) ? infoE->mintermsP : infoE->mintermsN)/2.0; + if (infoT->functionRef == 1 && !cuddIsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; + } else { +#ifdef DD_DEBUG + assert(infoN->parity == 2); +#endif + impact = impactN; + minterms = ((E == Ereg) ? infoE->mintermsN : + infoE->mintermsP)/2.0 - infoT->mintermsN/2.0; + if (infoE->functionRef == 1 && !cuddIsConstant(Ereg)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; + } + numOnset = impact * minterms; + } else { + DdNode *Ereg = Cudd_Regular(E); + DdNode *TT = cuddT(T); + DdNode *ET = Cudd_NotCond(cuddT(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TT == ET) { + shared = TT; + replace = REPLACE_TT; + } else { + DdNode *TE = cuddE(T); + DdNode *EE = Cudd_NotCond(cuddE(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TE == EE) { + shared = TE; + replace = REPLACE_TE; + } else { + replace = REPLACE_N; + } + } + numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; + savings = computeSavings(dd,node,shared,info,localQueue); + if (shared != NULL) { + NodeData *infoS; + infoS = (NodeData *) cuddHashTableGenericLookup(info->table, Cudd_Regular(shared)); + if (Cudd_IsComplement(shared)) { + numOnset -= (infoS->mintermsN * impactP + + infoS->mintermsP * impactN)/2.0; + } else { + numOnset -= (infoS->mintermsP * impactP + + infoS->mintermsN * impactN)/2.0; + } + savings--; + } + } + + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); +#if 0 + if (replace == REPLACE_T || replace == REPLACE_E) + (void) printf("node %p: impact = %g numOnset = %g savings %d\n", + node, impact, numOnset, savings); + else + (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", + node, impactP, impactN, numOnset, savings); +#endif + if ((1 - numOnset / info->minterms) > + quality * (1 - (double) savings / info->size)) { + infoN->replace = (char) replace; + info->size -= savings; + info->minterms -=numOnset; +#if 0 + (void) printf("remap(%d): new size = %d new minterms = %g\n", + replace, info->size, info->minterms); +#endif + if (replace == REPLACE_N) { + savings -= updateRefs(dd,node,NULL,info,localQueue); + } else if (replace == REPLACE_T) { + savings -= updateRefs(dd,node,E,info,localQueue); + } else if (replace == REPLACE_E) { + savings -= updateRefs(dd,node,T,info,localQueue); + } else { +#ifdef DD_DEBUG + assert(replace == REPLACE_TT || replace == REPLACE_TE); +#endif + savings -= updateRefs(dd,node,shared,info,localQueue) - 1; + } + assert(savings == 0); + } else { + replace = NOTHING; + } + if (replace == REPLACE_N) continue; + if ((replace == REPLACE_E || replace == NOTHING) && + !cuddIsConstant(cuddT(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + if (replace == REPLACE_E) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + if ((replace == REPLACE_T || replace == NOTHING) && + !Cudd_IsConstant(cuddE(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (Cudd_IsComplement(cuddE(node))) { + if (replace == REPLACE_T) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } + } else { + if (replace == REPLACE_T) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + } + if ((replace == REPLACE_TT || replace == REPLACE_TE) && + !Cudd_IsConstant(shared)) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(shared), + cuddI(dd,Cudd_Regular(shared)->index)); + if (Cudd_IsComplement(shared)) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactP; + item->impactN += impactN; + } + } + } + + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(1); + +} /* end of RAmarkNodes */ + + +/**Function******************************************************************** + + Synopsis [Marks nodes for remapping.] + + Description [Marks nodes for remapping. Returns 1 if successful; 0 + otherwise.] + + SideEffects [None] + + SeeAlso [cuddBiasedUnderApprox] + +******************************************************************************/ +static int +BAmarkNodes( + DdManager *dd /* manager */, + DdNode *f /* function to be analyzed */, + ApproxInfo *info /* info on BDD */, + int threshold /* when to stop approximating */, + double quality1 /* minimum improvement for accepted changes when b=1 */, + double quality0 /* minimum improvement for accepted changes when b=0 */) +{ + DdLevelQueue *queue; + DdLevelQueue *localQueue; + NodeData *infoN, *infoT, *infoE; + GlobalQueueItem *item; + DdNode *node, *T, *E; + DdNode *shared; /* grandchild shared by the two children of node */ + double numOnset; + double impact, impactP, impactN; + double minterms; + double quality; + int savings; + int replace; + +#if 0 + (void) fprintf(dd->out,"initial size = %d initial minterms = %g\n", + info->size, info->minterms); +#endif + queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size); + if (queue == NULL) { + return(0); + } + localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem), + dd->initSlots); + if (localQueue == NULL) { + cuddLevelQueueQuit(queue); + return(0); + } + /* Enqueue regular pointer to root and initialize impact. */ + node = Cudd_Regular(f); + item = (GlobalQueueItem *) + cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); + if (item == NULL) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + if (Cudd_IsComplement(f)) { + item->impactP = 0.0; + item->impactN = 1.0; + } else { + item->impactP = 1.0; + item->impactN = 0.0; + } + /* The nodes retrieved here are guaranteed to be non-terminal. + ** The initial node is not terminal because constant nodes are + ** dealt with in the calling procedure. Subsequent nodes are inserted + ** only if they are not terminal. */ + while (queue->first != NULL) { + /* If the size of the subset is below the threshold, quit. */ + if (info->size <= threshold) + break; + item = (GlobalQueueItem *) queue->first; + node = item->node; +#ifdef DD_DEBUG + assert(item->impactP >= 0 && item->impactP <= 1.0); + assert(item->impactN >= 0 && item->impactN <= 1.0); + assert(!Cudd_IsComplement(node)); + assert(!Cudd_IsConstant(node)); +#endif + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, node)) == NULL) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + quality = infoN->care ? quality1 : quality0; +#ifdef DD_DEBUG + assert(infoN->parity >= 1 && infoN->parity <= 3); +#endif + if (infoN->parity == 3) { + /* This node can be reached through paths of different parity. + ** It is not safe to replace it, because remapping will give + ** an incorrect result, while replacement by 0 may cause node + ** splitting. */ + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + continue; + } + T = cuddT(node); + E = cuddE(node); + shared = NULL; + impactP = item->impactP; + impactN = item->impactN; + if (Cudd_bddLeq(dd,T,E)) { + /* Here we know that E is regular. */ +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(E)); +#endif + infoT = (NodeData *) cuddHashTableGenericLookup(info->table, T); + infoE = (NodeData *) cuddHashTableGenericLookup(info->table, E); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoE->mintermsP/2.0 - infoT->mintermsP/2.0; + if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; + } else { +#ifdef DD_DEBUG + assert(infoN->parity == 2); +#endif + impact = impactN; + minterms = infoT->mintermsN/2.0 - infoE->mintermsN/2.0; + if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; + } + numOnset = impact * minterms; + } else if (Cudd_bddLeq(dd,E,T)) { + /* Here E may be complemented. */ + DdNode *Ereg = Cudd_Regular(E); + infoT = (NodeData *) cuddHashTableGenericLookup(info->table, T); + infoE = (NodeData *) cuddHashTableGenericLookup(info->table, Ereg); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoT->mintermsP/2.0 - + ((E == Ereg) ? infoE->mintermsP : infoE->mintermsN)/2.0; + if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; + } else { +#ifdef DD_DEBUG + assert(infoN->parity == 2); +#endif + impact = impactN; + minterms = ((E == Ereg) ? infoE->mintermsN : + infoE->mintermsP)/2.0 - infoT->mintermsN/2.0; + if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; + } + numOnset = impact * minterms; + } else { + DdNode *Ereg = Cudd_Regular(E); + DdNode *TT = cuddT(T); + DdNode *ET = Cudd_NotCond(cuddT(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TT == ET) { + shared = TT; + replace = REPLACE_TT; + } else { + DdNode *TE = cuddE(T); + DdNode *EE = Cudd_NotCond(cuddE(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TE == EE) { + shared = TE; + replace = REPLACE_TE; + } else { + replace = REPLACE_N; + } + } + numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; + savings = computeSavings(dd,node,shared,info,localQueue); + if (shared != NULL) { + NodeData *infoS; + infoS = (NodeData *) cuddHashTableGenericLookup(info->table, Cudd_Regular(shared)); + if (Cudd_IsComplement(shared)) { + numOnset -= (infoS->mintermsN * impactP + + infoS->mintermsP * impactN)/2.0; + } else { + numOnset -= (infoS->mintermsP * impactP + + infoS->mintermsN * impactN)/2.0; + } + savings--; + } + } + + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); +#if 0 + if (replace == REPLACE_T || replace == REPLACE_E) + (void) printf("node %p: impact = %g numOnset = %g savings %d\n", + node, impact, numOnset, savings); + else + (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", + node, impactP, impactN, numOnset, savings); +#endif + if ((1 - numOnset / info->minterms) > + quality * (1 - (double) savings / info->size)) { + infoN->replace = (char) replace; + info->size -= savings; + info->minterms -=numOnset; +#if 0 + (void) printf("remap(%d): new size = %d new minterms = %g\n", + replace, info->size, info->minterms); +#endif + if (replace == REPLACE_N) { + savings -= updateRefs(dd,node,NULL,info,localQueue); + } else if (replace == REPLACE_T) { + savings -= updateRefs(dd,node,E,info,localQueue); + } else if (replace == REPLACE_E) { + savings -= updateRefs(dd,node,T,info,localQueue); + } else { +#ifdef DD_DEBUG + assert(replace == REPLACE_TT || replace == REPLACE_TE); +#endif + savings -= updateRefs(dd,node,shared,info,localQueue) - 1; + } + assert(savings == 0); + } else { + replace = NOTHING; + } + if (replace == REPLACE_N) continue; + if ((replace == REPLACE_E || replace == NOTHING) && + !cuddIsConstant(cuddT(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + if (replace == REPLACE_E) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + if ((replace == REPLACE_T || replace == NOTHING) && + !Cudd_IsConstant(cuddE(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (Cudd_IsComplement(cuddE(node))) { + if (replace == REPLACE_T) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } + } else { + if (replace == REPLACE_T) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + } + if ((replace == REPLACE_TT || replace == REPLACE_TE) && + !Cudd_IsConstant(shared)) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(shared), + cuddI(dd,Cudd_Regular(shared)->index)); + if (Cudd_IsComplement(shared)) { + if (replace == REPLACE_T) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } + } else { + if (replace == REPLACE_T) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } + } + } + + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(1); + +} /* end of BAmarkNodes */ + + +/**Function******************************************************************** + + Synopsis [Builds the subset BDD for cuddRemapUnderApprox.] + + Description [Builds the subset BDDfor cuddRemapUnderApprox. Based + on the info table, performs remapping or replacement at selected + nodes. Returns a pointer to the result if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [cuddRemapUnderApprox] + +******************************************************************************/ +static DdNode * +RAbuildSubset( + DdManager * dd /* DD manager */, + DdNode * node /* current node */, + ApproxInfo * info /* node info */) +{ + DdNode *Nt, *Ne, *N, *t, *e, *r; + NodeData *infoN; + + if (Cudd_IsConstant(node)) + return(node); + + N = Cudd_Regular(node); + + Nt = Cudd_NotCond(cuddT(N), Cudd_IsComplement(node)); + Ne = Cudd_NotCond(cuddE(N), Cudd_IsComplement(node)); + + if ((infoN = (NodeData *) cuddHashTableGenericLookup(info->table, N)) != NULL) { + if (N == node ) { + if (infoN->resultP != NULL) { + return(infoN->resultP); + } + } else { + if (infoN->resultN != NULL) { + return(infoN->resultN); + } + } + if (infoN->replace == REPLACE_T) { + r = RAbuildSubset(dd, Ne, info); + return(r); + } else if (infoN->replace == REPLACE_E) { + r = RAbuildSubset(dd, Nt, info); + return(r); + } else if (infoN->replace == REPLACE_N) { + return(info->zero); + } else if (infoN->replace == REPLACE_TT) { + DdNode *Ntt = Cudd_NotCond(cuddT(cuddT(N)), + Cudd_IsComplement(node)); + int index = cuddT(N)->index; + e = info->zero; + t = RAbuildSubset(dd, Ntt, info); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + } + cuddDeref(t); + return(r); + } else if (infoN->replace == REPLACE_TE) { + DdNode *Nte = Cudd_NotCond(cuddE(cuddT(N)), + Cudd_IsComplement(node)); + int index = cuddT(N)->index; + t = info->one; + e = RAbuildSubset(dd, Nte, info); + if (e == NULL) { + return(NULL); + } + cuddRef(e); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + r =Cudd_Not(r); + cuddDeref(e); + return(r); + } + } else { + (void) fprintf(dd->err, + "Something is wrong, ought to be in info table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + + t = RAbuildSubset(dd, Nt, info); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + + e = RAbuildSubset(dd, Ne, info); + if (e == NULL) { + Cudd_RecursiveDeref(dd,t); + return(NULL); + } + cuddRef(e); + + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + + if (N == node) { + infoN->resultP = r; + } else { + infoN->resultN = r; + } + + return(r); + +} /* end of RAbuildSubset */ + + +/**Function******************************************************************** + + Synopsis [Finds don't care nodes.] + + Description [Finds don't care nodes by traversing f and b in parallel. + Returns the care status of the visited f node if successful; CARE_ERROR + otherwise.] + + SideEffects [None] + + SeeAlso [cuddBiasedUnderApprox] + +******************************************************************************/ +static int +BAapplyBias( + DdManager *dd, + DdNode *f, + DdNode *b, + ApproxInfo *info, + DdHashTable *cache) +{ + DdNode *one, *zero, *res; + DdNode *Ft, *Fe, *B, *Bt, *Be; + unsigned int topf, topb; + NodeData *infoF; + int careT, careE; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + if ((infoF = (NodeData *) cuddHashTableGenericLookup(info->table, f)) == NULL) + return(CARE_ERROR); + if (f == one) return(TOTAL_CARE); + if (b == zero) return(infoF->care); + if (infoF->care == TOTAL_CARE) return(TOTAL_CARE); + + if ((f->ref != 1 || Cudd_Regular(b)->ref != 1) && + (res = cuddHashTableLookup2(cache,f,b)) != NULL) { + if (res->ref == 0) { + cache->manager->dead++; + cache->manager->constants.dead++; + } + return(infoF->care); + } + + topf = dd->perm[f->index]; + B = Cudd_Regular(b); + topb = cuddI(dd,B->index); + if (topf <= topb) { + Ft = cuddT(f); Fe = cuddE(f); + } else { + Ft = Fe = f; + } + if (topb <= topf) { + /* We know that b is not constant because f is not. */ + Bt = cuddT(B); Be = cuddE(B); + if (Cudd_IsComplement(b)) { + Bt = Cudd_Not(Bt); + Be = Cudd_Not(Be); + } + } else { + Bt = Be = b; + } + + careT = BAapplyBias(dd, Ft, Bt, info, cache); + if (careT == CARE_ERROR) + return(CARE_ERROR); + careE = BAapplyBias(dd, Cudd_Regular(Fe), Be, info, cache); + if (careE == CARE_ERROR) + return(CARE_ERROR); + if (careT == TOTAL_CARE && careE == TOTAL_CARE) { + infoF->care = TOTAL_CARE; + } else { + infoF->care = CARE; + } + + if (f->ref != 1 || Cudd_Regular(b)->ref != 1) { + ptrint fanout = (ptrint) f->ref * Cudd_Regular(b)->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert2(cache,f,b,one,fanout)) { + return(CARE_ERROR); + } + } + return(infoF->care); + +} /* end of BAapplyBias */ diff --git a/cudd_local/cudd/cuddBddAbs.c b/cudd_local/cudd/cuddBddAbs.c new file mode 100644 index 0000000..a806078 --- /dev/null +++ b/cudd_local/cudd/cuddBddAbs.c @@ -0,0 +1,760 @@ +/**CFile*********************************************************************** + + FileName [cuddBddAbs.c] + + PackageName [cudd] + + Synopsis [Quantification functions for BDDs.] + + Description [External procedures included in this module: +
    +
  • Cudd_bddExistAbstract() +
  • Cudd_bddExistAbstractLimit() +
  • Cudd_bddXorExistAbstract() +
  • Cudd_bddUnivAbstract() +
  • Cudd_bddBooleanDiff() +
  • Cudd_bddVarIsDependent() +
+ Internal procedures included in this module: +
    +
  • cuddBddExistAbstractRecur() +
  • cuddBddXorExistAbstractRecur() +
  • cuddBddBooleanDiffRecur() +
+ Static procedures included in this module: +
    +
  • bddCheckPositiveCube() +
+ ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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: cuddBddAbs.c,v 1.28 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int bddCheckPositiveCube (DdManager *manager, DdNode *cube); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Existentially abstracts all the variables in cube from f.] + + Description [Existentially abstracts all the variables in cube from f. + Returns the abstracted BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddUnivAbstract Cudd_addExistAbstract] + +******************************************************************************/ +DdNode * +Cudd_bddExistAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *res; + + if (bddCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err, + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddBddExistAbstractRecur(manager, f, cube); + } while (manager->reordered == 1); + + return(res); + +} /* end of Cudd_bddExistAbstract */ + + +/**Function******************************************************************** + + Synopsis [Existentially abstracts all the variables in cube from f.] + + Description [Existentially abstracts all the variables in cube from f. + Returns the abstracted BDD if successful; NULL if the intermediate + result blows up or more new nodes than limit are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddExistAbstract] + +******************************************************************************/ +DdNode * +Cudd_bddExistAbstractLimit( + DdManager * manager, + DdNode * f, + DdNode * cube, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = manager->maxLive; + + if (bddCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err, + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + manager->maxLive = (manager->keys - manager->dead) + + (manager->keysZ - manager->deadZ) + limit; + do { + manager->reordered = 0; + res = cuddBddExistAbstractRecur(manager, f, cube); + } while (manager->reordered == 1); + manager->maxLive = saveLimit; + + return(res); + +} /* end of Cudd_bddExistAbstractLimit */ + + +/**Function******************************************************************** + + Synopsis [Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube.] + + Description [Takes the exclusive OR of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. Returns a + pointer to the result is successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddUnivAbstract Cudd_bddExistAbstract Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +Cudd_bddXorExistAbstract( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube) +{ + DdNode *res; + + if (bddCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err, + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddBddXorExistAbstractRecur(manager, f, g, cube); + } while (manager->reordered == 1); + + return(res); + +} /* end of Cudd_bddXorExistAbstract */ + + +/**Function******************************************************************** + + Synopsis [Universally abstracts all the variables in cube from f.] + + Description [Universally abstracts all the variables in cube from f. + Returns the abstracted BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddExistAbstract Cudd_addUnivAbstract] + +******************************************************************************/ +DdNode * +Cudd_bddUnivAbstract( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *res; + + if (bddCheckPositiveCube(manager, cube) == 0) { + (void) fprintf(manager->err, + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + + do { + manager->reordered = 0; + res = cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube); + } while (manager->reordered == 1); + if (res != NULL) res = Cudd_Not(res); + + return(res); + +} /* end of Cudd_bddUnivAbstract */ + + +/**Function******************************************************************** + + Synopsis [Computes the boolean difference of f with respect to x.] + + Description [Computes the boolean difference of f with respect to the + variable with index x. Returns the BDD of the boolean difference if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_bddBooleanDiff( + DdManager * manager, + DdNode * f, + int x) +{ + DdNode *res, *var; + + /* If the variable is not currently in the manager, f cannot + ** depend on it. + */ + if (x >= manager->size) return(Cudd_Not(DD_ONE(manager))); + var = manager->vars[x]; + + do { + manager->reordered = 0; + res = cuddBddBooleanDiffRecur(manager, Cudd_Regular(f), var); + } while (manager->reordered == 1); + + return(res); + +} /* end of Cudd_bddBooleanDiff */ + + +/**Function******************************************************************** + + Synopsis [Checks whether a variable is dependent on others in a + function.] + + Description [Checks whether a variable is dependent on others in a + function. Returns 1 if the variable is dependent; 0 otherwise. No + new nodes are created.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_bddVarIsDependent( + DdManager *dd, /* manager */ + DdNode *f, /* function */ + DdNode *var /* variable */) +{ + DdNode *F, *res, *zero, *ft, *fe; + unsigned topf, level; + DD_CTFP cacheOp; + int retval; + + zero = Cudd_Not(DD_ONE(dd)); + if (Cudd_IsConstant(f)) return(f == zero); + + /* From now on f is not constant. */ + F = Cudd_Regular(f); + topf = (unsigned) dd->perm[F->index]; + level = (unsigned) dd->perm[var->index]; + + /* Check terminal case. If topf > index of var, f does not depend on var. + ** Therefore, var is not dependent in f. */ + if (topf > level) { + return(0); + } + + cacheOp = (DD_CTFP) Cudd_bddVarIsDependent; + res = cuddCacheLookup2(dd,cacheOp,f,var); + if (res != NULL) { + return(res != zero); + } + + /* Compute cofactors. */ + ft = Cudd_NotCond(cuddT(F), f != F); + fe = Cudd_NotCond(cuddE(F), f != F); + + if (topf == level) { + retval = Cudd_bddLeq(dd,ft,Cudd_Not(fe)); + } else { + retval = Cudd_bddVarIsDependent(dd,ft,var) && + Cudd_bddVarIsDependent(dd,fe,var); + } + + cuddCacheInsert2(dd,cacheOp,f,var,Cudd_NotCond(zero,retval)); + + return(retval); + +} /* Cudd_bddVarIsDependent */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive steps of Cudd_bddExistAbstract.] + + Description [Performs the recursive steps of Cudd_bddExistAbstract. + Returns the BDD obtained by abstracting the variables + of cube from f if successful; NULL otherwise. It is also used by + Cudd_bddUnivAbstract.] + + SideEffects [None] + + SeeAlso [Cudd_bddExistAbstract Cudd_bddUnivAbstract] + +******************************************************************************/ +DdNode * +cuddBddExistAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * cube) +{ + DdNode *F, *T, *E, *res, *res1, *res2, *one; + + statLine(manager); + one = DD_ONE(manager); + F = Cudd_Regular(f); + + /* Cube is guaranteed to be a cube at this point. */ + if (cube == one || F == one) { + return(f); + } + /* From now on, f and cube are non-constant. */ + + /* Abstract a variable that does not appear in f. */ + while (manager->perm[F->index] > manager->perm[cube->index]) { + cube = cuddT(cube); + if (cube == one) return(f); + } + + /* Check the cache. */ + if (F->ref != 1 && (res = cuddCacheLookup2(manager, Cudd_bddExistAbstract, f, cube)) != NULL) { + return(res); + } + + /* Compute the cofactors of f. */ + T = cuddT(F); E = cuddE(F); + if (f != F) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + + /* If the two indices are the same, so are their levels. */ + if (F->index == cube->index) { + if (T == one || E == one || T == Cudd_Not(E)) { + return(one); + } + res1 = cuddBddExistAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); + if (res1 == one) { + if (F->ref != 1) + cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, one); + return(one); + } + cuddRef(res1); + res2 = cuddBddExistAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_IterDerefBdd(manager,res1); + return(NULL); + } + cuddRef(res2); + res = cuddBddAndRecur(manager, Cudd_Not(res1), Cudd_Not(res2)); + if (res == NULL) { + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + return(NULL); + } + res = Cudd_Not(res); + cuddRef(res); + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + if (F->ref != 1) + cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res); + cuddDeref(res); + return(res); + } else { /* if (cuddI(manager,F->index) < cuddI(manager,cube->index)) */ + res1 = cuddBddExistAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddBddExistAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_IterDerefBdd(manager, res1); + return(NULL); + } + cuddRef(res2); + /* ITE takes care of possible complementation of res1 and of the + ** case in which res1 == res2. */ + res = cuddBddIteRecur(manager, manager->vars[F->index], res1, res2); + if (res == NULL) { + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + if (F->ref != 1) + cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res); + return(res); + } + +} /* end of cuddBddExistAbstractRecur */ + + +/**Function******************************************************************** + + Synopsis [Takes the exclusive OR of two BDDs and simultaneously abstracts the + variables in cube.] + + Description [Takes the exclusive OR of two BDDs and simultaneously abstracts + the variables in cube. The variables are existentially abstracted. Returns a + pointer to the result is successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddAndAbstract] + +******************************************************************************/ +DdNode * +cuddBddXorExistAbstractRecur( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube) +{ + DdNode *F, *fv, *fnv, *G, *gv, *gnv; + DdNode *one, *zero, *r, *t, *e, *Cube; + unsigned int topf, topg, topcube, top, index; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == g) { + return(zero); + } + if (f == Cudd_Not(g)) { + return(one); + } + if (cube == one) { + return(cuddBddXorRecur(manager, f, g)); + } + if (f == one) { + return(cuddBddExistAbstractRecur(manager, Cudd_Not(g), cube)); + } + if (g == one) { + return(cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube)); + } + if (f == zero) { + return(cuddBddExistAbstractRecur(manager, g, cube)); + } + if (g == zero) { + return(cuddBddExistAbstractRecur(manager, f, cube)); + } + + /* At this point f, g, and cube are not constant. */ + + if (f > g) { /* Try to increase cache efficiency. */ + DdNode *tmp = f; + f = g; + g = tmp; + } + + /* Check cache. */ + r = cuddCacheLookup(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube); + if (r != NULL) { + return(r); + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + F = Cudd_Regular(f); + topf = manager->perm[F->index]; + G = Cudd_Regular(g); + topg = manager->perm[G->index]; + top = ddMin(topf, topg); + topcube = manager->perm[cube->index]; + + if (topcube < top) { + return(cuddBddXorExistAbstractRecur(manager, f, g, cuddT(cube))); + } + /* Now, topcube >= top. */ + + if (topf == top) { + index = F->index; + fv = cuddT(F); + fnv = cuddE(F); + if (Cudd_IsComplement(f)) { + fv = Cudd_Not(fv); + fnv = Cudd_Not(fnv); + } + } else { + index = G->index; + fv = fnv = f; + } + + if (topg == top) { + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } + } else { + gv = gnv = g; + } + + if (topcube == top) { + Cube = cuddT(cube); + } else { + Cube = cube; + } + + t = cuddBddXorExistAbstractRecur(manager, fv, gv, Cube); + if (t == NULL) return(NULL); + + /* Special case: 1 OR anything = 1. Hence, no need to compute + ** the else branch if t is 1. + */ + if (t == one && topcube == top) { + cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, one); + return(one); + } + cuddRef(t); + + e = cuddBddXorExistAbstractRecur(manager, fnv, gnv, Cube); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + cuddRef(e); + + if (topcube == top) { /* abstract */ + r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + cuddRef(r); + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + cuddDeref(r); + } else if (t == e) { + r = t; + cuddDeref(t); + cuddDeref(e); + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + cuddDeref(e); + cuddDeref(t); + } + cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, r); + return (r); + +} /* end of cuddBddXorExistAbstractRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive steps of Cudd_bddBoleanDiff.] + + Description [Performs the recursive steps of Cudd_bddBoleanDiff. + Returns the BDD obtained by XORing the cofactors of f with respect to + var if successful; NULL otherwise. Exploits the fact that dF/dx = + dF'/dx.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddBddBooleanDiffRecur( + DdManager * manager, + DdNode * f, + DdNode * var) +{ + DdNode *T, *E, *res, *res1, *res2; + + statLine(manager); + if (cuddI(manager,f->index) > manager->perm[var->index]) { + /* f does not depend on var. */ + return(Cudd_Not(DD_ONE(manager))); + } + + /* From now on, f is non-constant. */ + + /* If the two indices are the same, so are their levels. */ + if (f->index == var->index) { + res = cuddBddXorRecur(manager, cuddT(f), cuddE(f)); + return(res); + } + + /* From now on, cuddI(manager,f->index) < cuddI(manager,cube->index). */ + + /* Check the cache. */ + res = cuddCacheLookup2(manager, cuddBddBooleanDiffRecur, f, var); + if (res != NULL) { + return(res); + } + + /* Compute the cofactors of f. */ + T = cuddT(f); E = cuddE(f); + + res1 = cuddBddBooleanDiffRecur(manager, T, var); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res2 = cuddBddBooleanDiffRecur(manager, Cudd_Regular(E), var); + if (res2 == NULL) { + Cudd_IterDerefBdd(manager, res1); + return(NULL); + } + cuddRef(res2); + /* ITE takes care of possible complementation of res1 and of the + ** case in which res1 == res2. */ + res = cuddBddIteRecur(manager, manager->vars[f->index], res1, res2); + if (res == NULL) { + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + cuddCacheInsert2(manager, cuddBddBooleanDiffRecur, f, var, res); + return(res); + +} /* end of cuddBddBooleanDiffRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Checks whether cube is an BDD representing the product of + positive literals.] + + Description [Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +bddCheckPositiveCube( + 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) == Cudd_Not(DD_ONE(manager))) { + return(bddCheckPositiveCube(manager, cuddT(cube))); + } + return(0); + +} /* end of bddCheckPositiveCube */ + diff --git a/cudd_local/cudd/cuddBddCorr.c b/cudd_local/cudd/cuddBddCorr.c new file mode 100644 index 0000000..e92d24a --- /dev/null +++ b/cudd_local/cudd/cuddBddCorr.c @@ -0,0 +1,515 @@ +/**CFile*********************************************************************** + + FileName [cuddBddCorr.c] + + PackageName [cudd] + + Synopsis [Correlation between BDDs.] + + Description [External procedures included in this module: +
    +
  • Cudd_bddCorrelation() +
  • Cudd_bddCorrelationWeights() +
+ Static procedures included in this module: +
    +
  • bddCorrelationAux() +
  • bddCorrelationWeightsAux() +
  • CorrelCompare() +
  • CorrelHash() +
  • CorrelCleanUp() +
+ ] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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 */ +/*---------------------------------------------------------------------------*/ + +typedef struct hashEntry { + DdNode *f; + DdNode *g; +} HashEntry; + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddBddCorr.c,v 1.15 2012/02/05 01:07:18 fabio Exp $"; +#endif + +#ifdef CORREL_STATS +static int num_calls; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static double bddCorrelationAux (DdManager *dd, DdNode *f, DdNode *g, st_table *table); +static double bddCorrelationWeightsAux (DdManager *dd, DdNode *f, DdNode *g, double *prob, st_table *table); +static int CorrelCompare (const char *key1, const char *key2); +static int CorrelHash (char *key, int modulus); +static enum st_retval CorrelCleanUp (char *key, char *value, char *arg); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the correlation of f and g.] + + Description [Computes the correlation of f and g. If f == g, their + correlation is 1. If f == g', their correlation is 0. Returns the + fraction of minterms in the ON-set of the EXNOR of f and g. If it + runs out of memory, returns (double)CUDD_OUT_OF_MEM.] + + SideEffects [None] + + SeeAlso [Cudd_bddCorrelationWeights] + +******************************************************************************/ +double +Cudd_bddCorrelation( + DdManager * manager, + DdNode * f, + DdNode * g) +{ + + st_table *table; + double correlation; + +#ifdef CORREL_STATS + num_calls = 0; +#endif + + table = st_init_table(CorrelCompare,CorrelHash); + if (table == NULL) return((double)CUDD_OUT_OF_MEM); + correlation = bddCorrelationAux(manager,f,g,table); + st_foreach(table, CorrelCleanUp, NIL(char)); + st_free_table(table); + return(correlation); + +} /* end of Cudd_bddCorrelation */ + + +/**Function******************************************************************** + + Synopsis [Computes the correlation of f and g for given input + probabilities.] + + Description [Computes the correlation of f and g for given input + probabilities. On input, prob\[i\] is supposed to contain the + probability of the i-th input variable to be 1. + If f == g, their correlation is 1. If f == g', their + correlation is 0. Returns the probability that f and g have the same + value. If it runs out of memory, returns (double)CUDD_OUT_OF_MEM. The + correlation of f and the constant one gives the probability of f.] + + SideEffects [None] + + SeeAlso [Cudd_bddCorrelation] + +******************************************************************************/ +double +Cudd_bddCorrelationWeights( + DdManager * manager, + DdNode * f, + DdNode * g, + double * prob) +{ + + st_table *table; + double correlation; + +#ifdef CORREL_STATS + num_calls = 0; +#endif + + table = st_init_table(CorrelCompare,CorrelHash); + if (table == NULL) return((double)CUDD_OUT_OF_MEM); + correlation = bddCorrelationWeightsAux(manager,f,g,prob,table); + st_foreach(table, CorrelCleanUp, NIL(char)); + st_free_table(table); + return(correlation); + +} /* end of Cudd_bddCorrelationWeights */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddCorrelation.] + + Description [Performs the recursive step of Cudd_bddCorrelation. + Returns the fraction of minterms in the ON-set of the EXNOR of f and + g.] + + SideEffects [None] + + SeeAlso [bddCorrelationWeightsAux] + +******************************************************************************/ +static double +bddCorrelationAux( + DdManager * dd, + DdNode * f, + DdNode * g, + st_table * table) +{ + DdNode *Fv, *Fnv, *G, *Gv, *Gnv; + double min, *pmin, min1, min2, *dummy; + HashEntry *entry; + unsigned int topF, topG; + + statLine(dd); +#ifdef CORREL_STATS + num_calls++; +#endif + + /* Terminal cases: only work for BDDs. */ + if (f == g) return(1.0); + if (f == Cudd_Not(g)) return(0.0); + + /* Standardize call using the following properties: + ** (f EXNOR g) = (g EXNOR f) + ** (f' EXNOR g') = (f EXNOR g). + */ + if (f > g) { + DdNode *tmp = f; + f = g; g = tmp; + } + if (Cudd_IsComplement(f)) { + f = Cudd_Not(f); + g = Cudd_Not(g); + } + /* From now on, f is regular. */ + + entry = ALLOC(HashEntry,1); + if (entry == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); + } + entry->f = f; entry->g = g; + + /* We do not use the fact that + ** correlation(f,g') = 1 - correlation(f,g) + ** to minimize the risk of cancellation. + */ + if (st_lookup(table, entry, &dummy)) { + min = *dummy; + FREE(entry); + return(min); + } + + G = Cudd_Regular(g); + topF = cuddI(dd,f->index); topG = cuddI(dd,G->index); + if (topF <= topG) { Fv = cuddT(f); Fnv = cuddE(f); } else { Fv = Fnv = f; } + if (topG <= topF) { Gv = cuddT(G); Gnv = cuddE(G); } else { Gv = Gnv = G; } + + if (g != G) { + Gv = Cudd_Not(Gv); + Gnv = Cudd_Not(Gnv); + } + + min1 = bddCorrelationAux(dd, Fv, Gv, table) / 2.0; + if (min1 == (double)CUDD_OUT_OF_MEM) { + FREE(entry); + return(CUDD_OUT_OF_MEM); + } + min2 = bddCorrelationAux(dd, Fnv, Gnv, table) / 2.0; + if (min2 == (double)CUDD_OUT_OF_MEM) { + FREE(entry); + return(CUDD_OUT_OF_MEM); + } + min = (min1+min2); + + pmin = ALLOC(double,1); + if (pmin == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); + } + *pmin = min; + + if (st_insert(table,(char *)entry, (char *)pmin) == ST_OUT_OF_MEM) { + FREE(entry); + FREE(pmin); + return((double)CUDD_OUT_OF_MEM); + } + return(min); + +} /* end of bddCorrelationAux */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddCorrelationWeigths.] + + Description [] + + SideEffects [None] + + SeeAlso [bddCorrelationAux] + +******************************************************************************/ +static double +bddCorrelationWeightsAux( + DdManager * dd, + DdNode * f, + DdNode * g, + double * prob, + st_table * table) +{ + DdNode *Fv, *Fnv, *G, *Gv, *Gnv; + double min, *pmin, min1, min2, *dummy; + HashEntry *entry; + int topF, topG, index; + + statLine(dd); +#ifdef CORREL_STATS + num_calls++; +#endif + + /* Terminal cases: only work for BDDs. */ + if (f == g) return(1.0); + if (f == Cudd_Not(g)) return(0.0); + + /* Standardize call using the following properties: + ** (f EXNOR g) = (g EXNOR f) + ** (f' EXNOR g') = (f EXNOR g). + */ + if (f > g) { + DdNode *tmp = f; + f = g; g = tmp; + } + if (Cudd_IsComplement(f)) { + f = Cudd_Not(f); + g = Cudd_Not(g); + } + /* From now on, f is regular. */ + + entry = ALLOC(HashEntry,1); + if (entry == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); + } + entry->f = f; entry->g = g; + + /* We do not use the fact that + ** correlation(f,g') = 1 - correlation(f,g) + ** to minimize the risk of cancellation. + */ + if (st_lookup(table, entry, &dummy)) { + min = *dummy; + FREE(entry); + return(min); + } + + G = Cudd_Regular(g); + topF = cuddI(dd,f->index); topG = cuddI(dd,G->index); + if (topF <= topG) { + Fv = cuddT(f); Fnv = cuddE(f); + index = f->index; + } else { + Fv = Fnv = f; + index = G->index; + } + if (topG <= topF) { Gv = cuddT(G); Gnv = cuddE(G); } else { Gv = Gnv = G; } + + if (g != G) { + Gv = Cudd_Not(Gv); + Gnv = Cudd_Not(Gnv); + } + + min1 = bddCorrelationWeightsAux(dd, Fv, Gv, prob, table) * prob[index]; + if (min1 == (double)CUDD_OUT_OF_MEM) { + FREE(entry); + return((double)CUDD_OUT_OF_MEM); + } + min2 = bddCorrelationWeightsAux(dd, Fnv, Gnv, prob, table) * (1.0 - prob[index]); + if (min2 == (double)CUDD_OUT_OF_MEM) { + FREE(entry); + return((double)CUDD_OUT_OF_MEM); + } + min = (min1+min2); + + pmin = ALLOC(double,1); + if (pmin == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); + } + *pmin = min; + + if (st_insert(table,(char *)entry, (char *)pmin) == ST_OUT_OF_MEM) { + FREE(entry); + FREE(pmin); + return((double)CUDD_OUT_OF_MEM); + } + return(min); + +} /* end of bddCorrelationWeightsAux */ + + +/**Function******************************************************************** + + Synopsis [Compares two hash table entries.] + + Description [Compares two hash table entries. Returns 0 if they are + identical; 1 otherwise.] + + SideEffects [None] + +******************************************************************************/ +static int +CorrelCompare( + const char * key1, + const char * key2) +{ + HashEntry *entry1; + HashEntry *entry2; + + entry1 = (HashEntry *) key1; + entry2 = (HashEntry *) key2; + if (entry1->f != entry2->f || entry1->g != entry2->g) return(1); + + return(0); + +} /* end of CorrelCompare */ + + +/**Function******************************************************************** + + Synopsis [Hashes a hash table entry.] + + Description [Hashes a hash table entry. It is patterned after + st_strhash. Returns a value between 0 and modulus.] + + SideEffects [None] + +******************************************************************************/ +static int +CorrelHash( + char * key, + int modulus) +{ + HashEntry *entry; + int val = 0; + + entry = (HashEntry *) key; +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 + val = ((int) ((long)entry->f))*997 + ((int) ((long)entry->g)); +#else + val = ((int) entry->f)*997 + ((int) entry->g); +#endif + + return ((val < 0) ? -val : val) % modulus; + +} /* end of CorrelHash */ + + +/**Function******************************************************************** + + Synopsis [Frees memory associated with hash table.] + + Description [Frees memory associated with hash table. Returns + ST_CONTINUE.] + + SideEffects [None] + +******************************************************************************/ +static enum st_retval +CorrelCleanUp( + char * key, + char * value, + char * arg) +{ + double *d; + HashEntry *entry; + + entry = (HashEntry *) key; + FREE(entry); + d = (double *)value; + FREE(d); + return ST_CONTINUE; + +} /* end of CorrelCleanUp */ + diff --git a/cudd_local/cudd/cuddBddIte.c b/cudd_local/cudd/cuddBddIte.c new file mode 100644 index 0000000..750a51c --- /dev/null +++ b/cudd_local/cudd/cuddBddIte.c @@ -0,0 +1,1430 @@ +/**CFile*********************************************************************** + + FileName [cuddBddIte.c] + + PackageName [cudd] + + Synopsis [BDD ITE function and satellites.] + + Description [External procedures included in this module: +
    +
  • Cudd_bddIte() +
  • Cudd_bddIteLimit() +
  • Cudd_bddIteConstant() +
  • Cudd_bddIntersect() +
  • Cudd_bddAnd() +
  • Cudd_bddAndLimit() +
  • Cudd_bddOr() +
  • Cudd_bddOrLimit() +
  • Cudd_bddNand() +
  • Cudd_bddNor() +
  • Cudd_bddXor() +
  • Cudd_bddXnor() +
  • Cudd_bddXnorLimit() +
  • Cudd_bddLeq() +
+ Internal procedures included in this module: +
    +
  • cuddBddIteRecur() +
  • cuddBddIntersectRecur() +
  • cuddBddAndRecur() +
  • cuddBddXorRecur() +
+ Static procedures included in this module: +
    +
  • bddVarToConst() +
  • bddVarToCanonical() +
  • bddVarToCanonicalSimple() +
] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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: cuddBddIte.c,v 1.26 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void bddVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *one); +static int bddVarToCanonical (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp); +static int bddVarToCanonicalSimple (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements ITE(f,g,h).] + + Description [Implements ITE(f,g,h). Returns a pointer to the + resulting BDD if successful; NULL if the intermediate result blows + up.] + + SideEffects [None] + + SeeAlso [Cudd_addIte Cudd_bddIteConstant Cudd_bddIntersect] + +******************************************************************************/ +DdNode * +Cudd_bddIte( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddIteRecur(dd,f,g,h); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddIte */ + + +/**Function******************************************************************** + + Synopsis [Implements ITE(f,g,h). Returns + NULL if too many nodes are required.] + + Description [Implements ITE(f,g,h). Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up or more new nodes than limit are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte] + +******************************************************************************/ +DdNode * +Cudd_bddIteLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = dd->maxLive; + + dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit; + do { + dd->reordered = 0; + res = cuddBddIteRecur(dd,f,g,h); + } while (dd->reordered == 1); + dd->maxLive = saveLimit; + return(res); + +} /* end of Cudd_bddIteLimit */ + + +/**Function******************************************************************** + + Synopsis [Implements ITEconstant(f,g,h).] + + Description [Implements ITEconstant(f,g,h). Returns a pointer to the + resulting BDD (which may or may not be constant) or DD_NON_CONSTANT. + No new nodes are created.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_bddIntersect Cudd_bddLeq Cudd_addIteConstant] + +******************************************************************************/ +DdNode * +Cudd_bddIteConstant( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e; + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + int comple; + unsigned int topf, topg, toph, v; + + statLine(dd); + /* Trivial cases. */ + if (f == one) /* ITE(1,G,H) => G */ + return(g); + + if (f == zero) /* ITE(0,G,H) => H */ + return(h); + + /* f now not a constant. */ + bddVarToConst(f, &g, &h, one); /* possibly convert g or h */ + /* to constants */ + + if (g == h) /* ITE(F,G,G) => G */ + return(g); + + if (Cudd_IsConstant(g) && Cudd_IsConstant(h)) + return(DD_NON_CONSTANT); /* ITE(F,1,0) or ITE(F,0,1) */ + /* => DD_NON_CONSTANT */ + + if (g == Cudd_Not(h)) + return(DD_NON_CONSTANT); /* ITE(F,G,G') => DD_NON_CONSTANT */ + /* if F != G and F != G' */ + + comple = bddVarToCanonical(dd, &f, &g, &h, &topf, &topg, &toph); + + /* Cache lookup. */ + r = cuddConstantLookup(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h); + if (r != NULL) { + return(Cudd_NotCond(r,comple && r != DD_NON_CONSTANT)); + } + + v = ddMin(topg, toph); + + /* ITE(F,G,H) = (v,G,H) (non constant) if F = (v,1,0), v < top(G,H). */ + if (topf < v && cuddT(f) == one && cuddE(f) == zero) { + return(DD_NON_CONSTANT); + } + + /* Compute cofactors. */ + if (topf <= v) { + v = ddMin(topf, v); /* v = top_var(F,G,H) */ + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + + if (topg == v) { + Gv = cuddT(g); Gnv = cuddE(g); + } else { + Gv = Gnv = g; + } + + if (toph == v) { + H = Cudd_Regular(h); + Hv = cuddT(H); Hnv = cuddE(H); + if (Cudd_IsComplement(h)) { + Hv = Cudd_Not(Hv); + Hnv = Cudd_Not(Hnv); + } + } else { + Hv = Hnv = h; + } + + /* Recursion. */ + t = Cudd_bddIteConstant(dd, Fv, Gv, Hv); + if (t == DD_NON_CONSTANT || !Cudd_IsConstant(t)) { + cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + e = Cudd_bddIteConstant(dd, Fnv, Gnv, Hnv); + if (e == DD_NON_CONSTANT || !Cudd_IsConstant(e) || t != e) { + cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, t); + return(Cudd_NotCond(t,comple)); + +} /* end of Cudd_bddIteConstant */ + + +/**Function******************************************************************** + + Synopsis [Returns a function included in the intersection of f and g.] + + Description [Computes a function included in the intersection of f and + g. (That is, a witness that the intersection is not empty.) + Cudd_bddIntersect tries to build as few new nodes as possible. If the + only result of interest is whether f and g intersect, + Cudd_bddLeq should be used instead.] + + SideEffects [None] + + SeeAlso [Cudd_bddLeq Cudd_bddIteConstant] + +******************************************************************************/ +DdNode * +Cudd_bddIntersect( + DdManager * dd /* manager */, + DdNode * f /* first operand */, + DdNode * g /* second operand */) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddIntersectRecur(dd,f,g); + } while (dd->reordered == 1); + + return(res); + +} /* end of Cudd_bddIntersect */ + + +/**Function******************************************************************** + + Synopsis [Computes the conjunction of two BDDs f and g.] + + Description [Computes the conjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAndAbstract Cudd_bddIntersect + Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXor Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddAnd( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddAnd */ + + +/**Function******************************************************************** + + Synopsis [Computes the conjunction of two BDDs f and g. Returns + NULL if too many nodes are required.] + + Description [Computes the conjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up or more new nodes than limit are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddAnd] + +******************************************************************************/ +DdNode * +Cudd_bddAndLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = dd->maxLive; + + dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit; + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,f,g); + } while (dd->reordered == 1); + dd->maxLive = saveLimit; + return(res); + +} /* end of Cudd_bddAndLimit */ + + +/**Function******************************************************************** + + Synopsis [Computes the disjunction of two BDDs f and g.] + + Description [Computes the disjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddNand Cudd_bddNor + Cudd_bddXor Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddOr( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); + } while (dd->reordered == 1); + res = Cudd_NotCond(res,res != NULL); + return(res); + +} /* end of Cudd_bddOr */ + + +/**Function******************************************************************** + + Synopsis [Computes the disjunction of two BDDs f and g. Returns + NULL if too many nodes are required.] + + Description [Computes the disjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up or more new nodes than limit are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddOr] + +******************************************************************************/ +DdNode * +Cudd_bddOrLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = dd->maxLive; + + dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit; + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); + } while (dd->reordered == 1); + dd->maxLive = saveLimit; + res = Cudd_NotCond(res,res != NULL); + return(res); + +} /* end of Cudd_bddOrLimit */ + + +/**Function******************************************************************** + + Synopsis [Computes the NAND of two BDDs f and g.] + + Description [Computes the NAND of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNor + Cudd_bddXor Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddNand( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,f,g); + } while (dd->reordered == 1); + res = Cudd_NotCond(res,res != NULL); + return(res); + +} /* end of Cudd_bddNand */ + + +/**Function******************************************************************** + + Synopsis [Computes the NOR of two BDDs f and g.] + + Description [Computes the NOR of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNand + Cudd_bddXor Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddNor( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddNor */ + + +/**Function******************************************************************** + + Synopsis [Computes the exclusive OR of two BDDs f and g.] + + Description [Computes the exclusive OR of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr + Cudd_bddNand Cudd_bddNor Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddXor( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddXorRecur(dd,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddXor */ + + +/**Function******************************************************************** + + Synopsis [Computes the exclusive NOR of two BDDs f and g.] + + Description [Computes the exclusive NOR of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr + Cudd_bddNand Cudd_bddNor Cudd_bddXor] + +******************************************************************************/ +DdNode * +Cudd_bddXnor( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddXorRecur(dd,f,Cudd_Not(g)); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddXnor */ + + +/**Function******************************************************************** + + Synopsis [Computes the exclusive NOR of two BDDs f and g. Returns + NULL if too many nodes are required.] + + Description [Computes the exclusive NOR of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up or more new nodes than limit are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddXnor] + +******************************************************************************/ +DdNode * +Cudd_bddXnorLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = dd->maxLive; + + dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit; + do { + dd->reordered = 0; + res = cuddBddXorRecur(dd,f,Cudd_Not(g)); + } while (dd->reordered == 1); + dd->maxLive = saveLimit; + return(res); + +} /* end of Cudd_bddXnorLimit */ + + +/**Function******************************************************************** + + Synopsis [Determines whether f is less than or equal to g.] + + Description [Returns 1 if f is less than or equal to g; 0 otherwise. + No new nodes are created.] + + SideEffects [None] + + SeeAlso [Cudd_bddIteConstant Cudd_addEvalConst] + +******************************************************************************/ +int +Cudd_bddLeq( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *one, *zero, *tmp, *F, *fv, *fvn, *gv, *gvn; + unsigned int topf, topg, res; + + statLine(dd); + /* Terminal cases and normalization. */ + if (f == g) return(1); + + if (Cudd_IsComplement(g)) { + /* Special case: if f is regular and g is complemented, + ** f(1,...,1) = 1 > 0 = g(1,...,1). + */ + if (!Cudd_IsComplement(f)) return(0); + /* Both are complemented: Swap and complement because + ** f <= g <=> g' <= f' and we want the second argument to be regular. + */ + tmp = g; + g = Cudd_Not(f); + f = Cudd_Not(tmp); + } else if (Cudd_IsComplement(f) && g < f) { + tmp = g; + g = Cudd_Not(f); + f = Cudd_Not(tmp); + } + + /* Now g is regular and, if f is not regular, f < g. */ + one = DD_ONE(dd); + if (g == one) return(1); /* no need to test against zero */ + if (f == one) return(0); /* since at this point g != one */ + if (Cudd_Not(f) == g) return(0); /* because neither is constant */ + zero = Cudd_Not(one); + if (f == zero) return(1); + + /* Here neither f nor g is constant. */ + + /* Check cache. */ + tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_bddLeq,f,g); + if (tmp != NULL) { + return(tmp == one); + } + + /* Compute cofactors. */ + F = Cudd_Regular(f); + topf = dd->perm[F->index]; + topg = dd->perm[g->index]; + if (topf <= topg) { + fv = cuddT(F); fvn = cuddE(F); + if (f != F) { + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); + } + } else { + fv = fvn = f; + } + if (topg <= topf) { + gv = cuddT(g); gvn = cuddE(g); + } else { + gv = gvn = g; + } + + /* Recursive calls. Since we want to maximize the probability of + ** the special case f(1,...,1) > g(1,...,1), we consider the negative + ** cofactors first. Indeed, the complementation parity of the positive + ** cofactors is the same as the one of the parent functions. + */ + res = Cudd_bddLeq(dd,fvn,gvn) && Cudd_bddLeq(dd,fv,gv); + + /* Store result in cache and return. */ + cuddCacheInsert2(dd,(DD_CTFP)Cudd_bddLeq,f,g,(res ? one : zero)); + return(res); + +} /* end of Cudd_bddLeq */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddIte.] + + Description [Implements the recursive step of Cudd_bddIte. Returns a + pointer to the resulting BDD. NULL if the intermediate result blows + up or if reordering occurs.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddBddIteRecur( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * h) +{ + DdNode *one, *zero, *res; + DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e; + unsigned int topf, topg, toph, v; + int index; + int comple; + + statLine(dd); + /* Terminal cases. */ + + /* One variable cases. */ + if (f == (one = DD_ONE(dd))) /* ITE(1,G,H) = G */ + return(g); + + if (f == (zero = Cudd_Not(one))) /* ITE(0,G,H) = H */ + return(h); + + /* From now on, f is known not to be a constant. */ + if (g == one || f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ + if (h == zero) { /* ITE(F,1,0) = F */ + return(f); + } else { + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(h)); + return(Cudd_NotCond(res,res != NULL)); + } + } else if (g == zero || f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */ + if (h == one) { /* ITE(F,0,1) = !F */ + return(Cudd_Not(f)); + } else { + res = cuddBddAndRecur(dd,Cudd_Not(f),h); + return(res); + } + } + if (h == zero || f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ + res = cuddBddAndRecur(dd,f,g); + return(res); + } else if (h == one || f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */ + res = cuddBddAndRecur(dd,f,Cudd_Not(g)); + return(Cudd_NotCond(res,res != NULL)); + } + + /* Check remaining one variable case. */ + if (g == h) { /* ITE(F,G,G) = G */ + return(g); + } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = F <-> G */ + res = cuddBddXorRecur(dd,f,h); + return(res); + } + + /* From here, there are no constants. */ + comple = bddVarToCanonicalSimple(dd, &f, &g, &h, &topf, &topg, &toph); + + /* f & g are now regular pointers */ + + v = ddMin(topg, toph); + + /* A shortcut: ITE(F,G,H) = (v,G,H) if F = (v,1,0), v < top(G,H). */ + if (topf < v && cuddT(f) == one && cuddE(f) == zero) { + r = cuddUniqueInter(dd, (int) f->index, g, h); + return(Cudd_NotCond(r,comple && r != NULL)); + } + + /* Check cache. */ + r = cuddCacheLookup(dd, DD_BDD_ITE_TAG, f, g, h); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + /* Compute cofactors. */ + if (topf <= v) { + v = ddMin(topf, v); /* v = top_var(F,G,H) */ + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + } else { + Fv = Fnv = f; + } + if (topg == v) { + index = g->index; + Gv = cuddT(g); Gnv = cuddE(g); + } else { + Gv = Gnv = g; + } + if (toph == v) { + H = Cudd_Regular(h); + index = H->index; + Hv = cuddT(H); Hnv = cuddE(H); + if (Cudd_IsComplement(h)) { + Hv = Cudd_Not(Hv); + Hnv = Cudd_Not(Hnv); + } + } else { + Hv = Hnv = h; + } + + /* Recursive step. */ + t = cuddBddIteRecur(dd,Fv,Gv,Hv); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddBddIteRecur(dd,Fnv,Gnv,Hnv); + if (e == NULL) { + Cudd_IterDerefBdd(dd,t); + return(NULL); + } + cuddRef(e); + + r = (t == e) ? t : cuddUniqueInter(dd,index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + + cuddCacheInsert(dd, DD_BDD_ITE_TAG, f, g, h, r); + return(Cudd_NotCond(r,comple)); + +} /* end of cuddBddIteRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddIntersect.] + + Description [] + + SideEffects [None] + + SeeAlso [Cudd_bddIntersect] + +******************************************************************************/ +DdNode * +cuddBddIntersectRecur( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + DdNode *F, *G, *t, *e; + DdNode *fv, *fnv, *gv, *gnv; + DdNode *one, *zero; + unsigned int index, topf, topg; + + statLine(dd); + one = DD_ONE(dd); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); + if (f == g || g == one) return(f); + if (f == one) return(g); + + /* At this point f and g are not constant. */ + if (f > g) { DdNode *tmp = f; f = g; g = tmp; } + res = cuddCacheLookup2(dd,Cudd_bddIntersect,f,g); + if (res != NULL) return(res); + + /* Find splitting variable. Here we can skip the use of cuddI, + ** because the operands are known to be non-constant. + */ + F = Cudd_Regular(f); + topf = dd->perm[F->index]; + G = Cudd_Regular(g); + topg = dd->perm[G->index]; + + /* Compute cofactors. */ + if (topf <= topg) { + index = F->index; + fv = cuddT(F); + fnv = cuddE(F); + if (Cudd_IsComplement(f)) { + fv = Cudd_Not(fv); + fnv = Cudd_Not(fnv); + } + } else { + index = G->index; + fv = fnv = f; + } + + if (topg <= topf) { + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } + } else { + gv = gnv = g; + } + + /* Compute partial results. */ + t = cuddBddIntersectRecur(dd,fv,gv); + if (t == NULL) return(NULL); + cuddRef(t); + if (t != zero) { + e = zero; + } else { + e = cuddBddIntersectRecur(dd,fnv,gnv); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + } + cuddRef(e); + + if (t == e) { /* both equal zero */ + res = t; + } else if (Cudd_IsComplement(t)) { + res = cuddUniqueInter(dd,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (res == NULL) { + Cudd_IterDerefBdd(dd, t); + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = cuddUniqueInter(dd,(int)index,t,e); + if (res == NULL) { + Cudd_IterDerefBdd(dd, t); + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + } + cuddDeref(e); + cuddDeref(t); + + cuddCacheInsert2(dd,Cudd_bddIntersect,f,g,res); + + return(res); + +} /* end of cuddBddIntersectRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddAnd.] + + Description [Implements the recursive step of Cudd_bddAnd by taking + the conjunction of two BDDs. Returns a pointer to the result is + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddAnd] + +******************************************************************************/ +DdNode * +cuddBddAndRecur( + DdManager * manager, + DdNode * f, + DdNode * g) +{ + DdNode *F, *fv, *fnv, *G, *gv, *gnv; + DdNode *one, *r, *t, *e; + unsigned int topf, topg, index; + + statLine(manager); + one = DD_ONE(manager); + + /* Terminal cases. */ + F = Cudd_Regular(f); + G = Cudd_Regular(g); + if (F == G) { + if (f == g) return(f); + else return(Cudd_Not(one)); + } + if (F == one) { + if (f == one) return(g); + else return(f); + } + if (G == one) { + if (g == one) return(f); + else return(g); + } + + /* At this point f and g are not constant. */ + if (f > g) { /* Try to increase cache efficiency. */ + DdNode *tmp = f; + f = g; + g = tmp; + F = Cudd_Regular(f); + G = Cudd_Regular(g); + } + + /* Check cache. */ + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup2(manager, Cudd_bddAnd, f, g); + if (r != NULL) return(r); + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + + /* Compute cofactors. */ + if (topf <= topg) { + index = F->index; + fv = cuddT(F); + fnv = cuddE(F); + if (Cudd_IsComplement(f)) { + fv = Cudd_Not(fv); + fnv = Cudd_Not(fnv); + } + } else { + index = G->index; + fv = fnv = f; + } + + if (topg <= topf) { + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } + } else { + gv = gnv = g; + } + + t = cuddBddAndRecur(manager, fv, gv); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddBddAndRecur(manager, fnv, gnv); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + } + cuddDeref(e); + cuddDeref(t); + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert2(manager, Cudd_bddAnd, f, g, r); + return(r); + +} /* end of cuddBddAndRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddXor.] + + Description [Implements the recursive step of Cudd_bddXor by taking + the exclusive OR of two BDDs. Returns a pointer to the result is + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddXor] + +******************************************************************************/ +DdNode * +cuddBddXorRecur( + DdManager * manager, + DdNode * f, + DdNode * g) +{ + DdNode *fv, *fnv, *G, *gv, *gnv; + DdNode *one, *zero, *r, *t, *e; + unsigned int topf, topg, index; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == g) return(zero); + if (f == Cudd_Not(g)) return(one); + if (f > g) { /* Try to increase cache efficiency and simplify tests. */ + DdNode *tmp = f; + f = g; + g = tmp; + } + if (g == zero) return(f); + if (g == one) return(Cudd_Not(f)); + if (Cudd_IsComplement(f)) { + f = Cudd_Not(f); + g = Cudd_Not(g); + } + /* Now the first argument is regular. */ + if (f == one) return(Cudd_Not(g)); + + /* At this point f and g are not constant. */ + + /* Check cache. */ + r = cuddCacheLookup2(manager, Cudd_bddXor, f, g); + if (r != NULL) return(r); + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[f->index]; + G = Cudd_Regular(g); + topg = manager->perm[G->index]; + + /* Compute cofactors. */ + if (topf <= topg) { + index = f->index; + fv = cuddT(f); + fnv = cuddE(f); + } else { + index = G->index; + fv = fnv = f; + } + + if (topg <= topf) { + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } + } else { + gv = gnv = g; + } + + t = cuddBddXorRecur(manager, fv, gv); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddBddXorRecur(manager, fnv, gnv); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + } + cuddDeref(e); + cuddDeref(t); + cuddCacheInsert2(manager, Cudd_bddXor, f, g, r); + return(r); + +} /* end of cuddBddXorRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Replaces variables with constants if possible.] + + Description [This function performs part of the transformation to + standard form by replacing variables with constants if possible.] + + SideEffects [None] + + SeeAlso [bddVarToCanonical bddVarToCanonicalSimple] + +******************************************************************************/ +static void +bddVarToConst( + DdNode * f, + DdNode ** gp, + DdNode ** hp, + DdNode * one) +{ + DdNode *g = *gp; + DdNode *h = *hp; + + if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ + *gp = one; + } else if (f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */ + *gp = Cudd_Not(one); + } + if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ + *hp = Cudd_Not(one); + } else if (f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */ + *hp = one; + } + +} /* end of bddVarToConst */ + + +/**Function******************************************************************** + + Synopsis [Picks unique member from equiv expressions.] + + Description [Reduces 2 variable expressions to canonical form.] + + SideEffects [None] + + SeeAlso [bddVarToConst bddVarToCanonicalSimple] + +******************************************************************************/ +static int +bddVarToCanonical( + DdManager * dd, + DdNode ** fp, + DdNode ** gp, + DdNode ** hp, + unsigned int * topfp, + unsigned int * topgp, + unsigned int * tophp) +{ + register DdNode *F, *G, *H, *r, *f, *g, *h; + register unsigned int topf, topg, toph; + DdNode *one = dd->one; + int comple, change; + + f = *fp; + g = *gp; + h = *hp; + F = Cudd_Regular(f); + G = Cudd_Regular(g); + H = Cudd_Regular(h); + topf = cuddI(dd,F->index); + topg = cuddI(dd,G->index); + toph = cuddI(dd,H->index); + + change = 0; + + if (G == one) { /* ITE(F,c,H) */ + if ((topf > toph) || (topf == toph && f > h)) { + r = h; + h = f; + f = r; /* ITE(F,1,H) = ITE(H,1,F) */ + if (g != one) { /* g == zero */ + f = Cudd_Not(f); /* ITE(F,0,H) = ITE(!H,0,!F) */ + h = Cudd_Not(h); + } + change = 1; + } + } else if (H == one) { /* ITE(F,G,c) */ + if ((topf > topg) || (topf == topg && f > g)) { + r = g; + g = f; + f = r; /* ITE(F,G,0) = ITE(G,F,0) */ + if (h == one) { + f = Cudd_Not(f); /* ITE(F,G,1) = ITE(!G,!F,1) */ + g = Cudd_Not(g); + } + change = 1; + } + } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = ITE(G,F,!F) */ + if ((topf > topg) || (topf == topg && f > g)) { + r = f; + f = g; + g = r; + h = Cudd_Not(r); + change = 1; + } + } + /* adjust pointers so that the first 2 arguments to ITE are regular */ + if (Cudd_IsComplement(f) != 0) { /* ITE(!F,G,H) = ITE(F,H,G) */ + f = Cudd_Not(f); + r = g; + g = h; + h = r; + change = 1; + } + comple = 0; + if (Cudd_IsComplement(g) != 0) { /* ITE(F,!G,H) = !ITE(F,G,!H) */ + g = Cudd_Not(g); + h = Cudd_Not(h); + change = 1; + comple = 1; + } + if (change != 0) { + *fp = f; + *gp = g; + *hp = h; + } + *topfp = cuddI(dd,f->index); + *topgp = cuddI(dd,g->index); + *tophp = cuddI(dd,Cudd_Regular(h)->index); + + return(comple); + +} /* end of bddVarToCanonical */ + + +/**Function******************************************************************** + + Synopsis [Picks unique member from equiv expressions.] + + Description [Makes sure the first two pointers are regular. This + mat require the complementation of the result, which is signaled by + returning 1 instead of 0. This function is simpler than the general + case because it assumes that no two arguments are the same or + complementary, and no argument is constant.] + + SideEffects [None] + + SeeAlso [bddVarToConst bddVarToCanonical] + +******************************************************************************/ +static int +bddVarToCanonicalSimple( + DdManager * dd, + DdNode ** fp, + DdNode ** gp, + DdNode ** hp, + unsigned int * topfp, + unsigned int * topgp, + unsigned int * tophp) +{ + register DdNode *r, *f, *g, *h; + int comple, change; + + f = *fp; + g = *gp; + h = *hp; + + change = 0; + + /* adjust pointers so that the first 2 arguments to ITE are regular */ + if (Cudd_IsComplement(f)) { /* ITE(!F,G,H) = ITE(F,H,G) */ + f = Cudd_Not(f); + r = g; + g = h; + h = r; + change = 1; + } + comple = 0; + if (Cudd_IsComplement(g)) { /* ITE(F,!G,H) = !ITE(F,G,!H) */ + g = Cudd_Not(g); + h = Cudd_Not(h); + change = 1; + comple = 1; + } + if (change) { + *fp = f; + *gp = g; + *hp = h; + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + *topfp = dd->perm[f->index]; + *topgp = dd->perm[g->index]; + *tophp = dd->perm[Cudd_Regular(h)->index]; + + return(comple); + +} /* end of bddVarToCanonicalSimple */ + diff --git a/cudd_local/cudd/cuddBridge.c b/cudd_local/cudd/cuddBridge.c new file mode 100644 index 0000000..a6207b7 --- /dev/null +++ b/cudd_local/cudd/cuddBridge.c @@ -0,0 +1,1016 @@ +/**CFile*********************************************************************** + + FileName [cuddBridge.c] + + PackageName [cudd] + + Synopsis [Translation from BDD to ADD and vice versa and transfer between + different managers.] + + Description [External procedures included in this file: +
    +
  • Cudd_addBddThreshold() +
  • Cudd_addBddStrictThreshold() +
  • Cudd_addBddInterval() +
  • Cudd_addBddIthBit() +
  • Cudd_BddToAdd() +
  • Cudd_addBddPattern() +
  • Cudd_bddTransfer() +
+ Internal procedures included in this file: +
    +
  • cuddBddTransfer() +
  • cuddAddBddDoPattern() +
+ Static procedures included in this file: +
    +
  • addBddDoThreshold() +
  • addBddDoStrictThreshold() +
  • addBddDoInterval() +
  • addBddDoIthBit() +
  • ddBddToAddRecur() +
  • cuddBddTransferRecur() +
+ ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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: cuddBridge.c,v 1.20 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +#ifdef __cplusplus +extern "C" { +#endif + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * addBddDoThreshold (DdManager *dd, DdNode *f, DdNode *val); +static DdNode * addBddDoStrictThreshold (DdManager *dd, DdNode *f, DdNode *val); +static DdNode * addBddDoInterval (DdManager *dd, DdNode *f, DdNode *l, DdNode *u); +static DdNode * addBddDoIthBit (DdManager *dd, DdNode *f, DdNode *index); +static DdNode * ddBddToAddRecur (DdManager *dd, DdNode *B); +static DdNode * cuddBddTransferRecur (DdManager *ddS, DdManager *ddD, DdNode *f, st_table *table); + +/**AutomaticEnd***************************************************************/ + +#ifdef __cplusplus +} +#endif + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Converts an ADD to a BDD.] + + Description [Converts an ADD to a BDD by replacing all + discriminants greater than or equal to value with 1, and all other + discriminants with 0. Returns a pointer to the resulting BDD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd + Cudd_addBddStrictThreshold] + +******************************************************************************/ +DdNode * +Cudd_addBddThreshold( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE value) +{ + DdNode *res; + DdNode *val; + + val = cuddUniqueConst(dd,value); + if (val == NULL) return(NULL); + cuddRef(val); + + do { + dd->reordered = 0; + res = addBddDoThreshold(dd, f, val); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd, val); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, val); + cuddDeref(res); + return(res); + +} /* end of Cudd_addBddThreshold */ + + +/**Function******************************************************************** + + Synopsis [Converts an ADD to a BDD.] + + Description [Converts an ADD to a BDD by replacing all + discriminants STRICTLY greater than value with 1, and all other + discriminants with 0. Returns a pointer to the resulting BDD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd + Cudd_addBddThreshold] + +******************************************************************************/ +DdNode * +Cudd_addBddStrictThreshold( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE value) +{ + DdNode *res; + DdNode *val; + + val = cuddUniqueConst(dd,value); + if (val == NULL) return(NULL); + cuddRef(val); + + do { + dd->reordered = 0; + res = addBddDoStrictThreshold(dd, f, val); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd, val); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, val); + cuddDeref(res); + return(res); + +} /* end of Cudd_addBddStrictThreshold */ + + +/**Function******************************************************************** + + Synopsis [Converts an ADD to a BDD.] + + Description [Converts an ADD to a BDD by replacing all + discriminants greater than or equal to lower and less than or equal to + upper with 1, and all other discriminants with 0. Returns a pointer to + the resulting BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddThreshold Cudd_addBddStrictThreshold + Cudd_addBddPattern Cudd_BddToAdd] + +******************************************************************************/ +DdNode * +Cudd_addBddInterval( + DdManager * dd, + DdNode * f, + CUDD_VALUE_TYPE lower, + CUDD_VALUE_TYPE upper) +{ + DdNode *res; + DdNode *l; + DdNode *u; + + /* Create constant nodes for the interval bounds, so that we can use + ** the global cache. + */ + l = cuddUniqueConst(dd,lower); + if (l == NULL) return(NULL); + cuddRef(l); + u = cuddUniqueConst(dd,upper); + if (u == NULL) { + Cudd_RecursiveDeref(dd,l); + return(NULL); + } + cuddRef(u); + + do { + dd->reordered = 0; + res = addBddDoInterval(dd, f, l, u); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd, l); + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, l); + Cudd_RecursiveDeref(dd, u); + cuddDeref(res); + return(res); + +} /* end of Cudd_addBddInterval */ + + +/**Function******************************************************************** + + Synopsis [Converts an ADD to a BDD by extracting the i-th bit from + the leaves.] + + Description [Converts an ADD to a BDD by replacing all + discriminants whose i-th bit is equal to 1 with 1, and all other + discriminants with 0. The i-th bit refers to the integer + representation of the leaf value. If the value is has a fractional + part, it is ignored. Repeated calls to this procedure allow one to + transform an integer-valued ADD into an array of BDDs, one for each + bit of the leaf values. Returns a pointer to the resulting BDD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd] + +******************************************************************************/ +DdNode * +Cudd_addBddIthBit( + DdManager * dd, + DdNode * f, + int bit) +{ + DdNode *res; + DdNode *index; + + index = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) bit); + if (index == NULL) return(NULL); + cuddRef(index); + + do { + dd->reordered = 0; + res = addBddDoIthBit(dd, f, index); + } while (dd->reordered == 1); + + if (res == NULL) { + Cudd_RecursiveDeref(dd, index); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, index); + cuddDeref(res); + return(res); + +} /* end of Cudd_addBddIthBit */ + + +/**Function******************************************************************** + + Synopsis [Converts a BDD to a 0-1 ADD.] + + Description [Converts a BDD to a 0-1 ADD. Returns a pointer to the + resulting ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addBddPattern Cudd_addBddThreshold Cudd_addBddInterval + Cudd_addBddStrictThreshold] + +******************************************************************************/ +DdNode * +Cudd_BddToAdd( + DdManager * dd, + DdNode * B) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = ddBddToAddRecur(dd, B); + } while (dd->reordered ==1); + return(res); + +} /* end of Cudd_BddToAdd */ + + +/**Function******************************************************************** + + Synopsis [Converts an ADD to a BDD.] + + Description [Converts an ADD to a BDD by replacing all + discriminants different from 0 with 1. Returns a pointer to the + resulting BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_BddToAdd Cudd_addBddThreshold Cudd_addBddInterval + Cudd_addBddStrictThreshold] + +******************************************************************************/ +DdNode * +Cudd_addBddPattern( + DdManager * dd, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddAddBddDoPattern(dd, f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addBddPattern */ + + +/**Function******************************************************************** + + Synopsis [Convert a BDD from a manager to another one.] + + Description [Convert a BDD from a manager to another one. The orders of the + variables in the two managers may be different. Returns a + pointer to the BDD in the destination manager if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +Cudd_bddTransfer( + DdManager * ddSource, + DdManager * ddDestination, + DdNode * f) +{ + DdNode *res; + do { + ddDestination->reordered = 0; + res = cuddBddTransfer(ddSource, ddDestination, f); + } while (ddDestination->reordered == 1); + return(res); + +} /* end of Cudd_bddTransfer */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Convert a BDD from a manager to another one.] + + Description [Convert a BDD from a manager to another one. Returns a + pointer to the BDD in the destination manager if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddTransfer] + +******************************************************************************/ +DdNode * +cuddBddTransfer( + DdManager * ddS, + DdManager * ddD, + DdNode * f) +{ + DdNode *res; + st_table *table = NULL; + st_generator *gen = NULL; + DdNode *key, *value; + + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) goto failure; + res = cuddBddTransferRecur(ddS, ddD, f, table); + if (res != NULL) cuddRef(res); + + /* Dereference all elements in the table and dispose of the table. + ** This must be done also if res is NULL to avoid leaks in case of + ** reordering. */ + gen = st_init_gen(table); + if (gen == NULL) goto failure; + while (st_gen(gen, &key, &value)) { + Cudd_RecursiveDeref(ddD, value); + } + st_free_gen(gen); gen = NULL; + st_free_table(table); table = NULL; + + if (res != NULL) cuddDeref(res); + return(res); + +failure: + /* No need to free gen because it is always NULL here. */ + if (table != NULL) st_free_table(table); + return(NULL); + +} /* end of cuddBddTransfer */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addBddPattern.] + + Description [Performs the recursive step for Cudd_addBddPattern. Returns a + pointer to the resulting BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +cuddAddBddDoPattern( + DdManager * dd, + DdNode * f) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + return(Cudd_NotCond(DD_ONE(dd),f == DD_ZERO(dd))); + } + + /* Check cache. */ + res = cuddCacheLookup1(dd,Cudd_addBddPattern,f); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = cuddAddBddDoPattern(dd,fv); + if (T == NULL) return(NULL); + cuddRef(T); + + E = cuddAddBddDoPattern(dd,fvn); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert1(dd,Cudd_addBddPattern,f,res); + + return(res); + +} /* end of cuddAddBddDoPattern */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addBddThreshold.] + + Description [Performs the recursive step for Cudd_addBddThreshold. + Returns a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [addBddDoStrictThreshold] + +******************************************************************************/ +static DdNode * +addBddDoThreshold( + DdManager * dd, + DdNode * f, + DdNode * val) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(val))); + } + + /* Check cache. */ + res = cuddCacheLookup2(dd,addBddDoThreshold,f,val); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = addBddDoThreshold(dd,fv,val); + if (T == NULL) return(NULL); + cuddRef(T); + + E = addBddDoThreshold(dd,fvn,val); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert2(dd,addBddDoThreshold,f,val,res); + + return(res); + +} /* end of addBddDoThreshold */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addBddStrictThreshold.] + + Description [Performs the recursive step for Cudd_addBddStrictThreshold. + Returns a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [addBddDoThreshold] + +******************************************************************************/ +static DdNode * +addBddDoStrictThreshold( + DdManager * dd, + DdNode * f, + DdNode * val) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + return(Cudd_NotCond(DD_ONE(dd),cuddV(f) <= cuddV(val))); + } + + /* Check cache. */ + res = cuddCacheLookup2(dd,addBddDoStrictThreshold,f,val); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = addBddDoStrictThreshold(dd,fv,val); + if (T == NULL) return(NULL); + cuddRef(T); + + E = addBddDoStrictThreshold(dd,fvn,val); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert2(dd,addBddDoStrictThreshold,f,val,res); + + return(res); + +} /* end of addBddDoStrictThreshold */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addBddInterval.] + + Description [Performs the recursive step for Cudd_addBddInterval. + Returns a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [addBddDoThreshold addBddDoStrictThreshold] + +******************************************************************************/ +static DdNode * +addBddDoInterval( + DdManager * dd, + DdNode * f, + DdNode * l, + DdNode * u) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(l) || cuddV(f) > cuddV(u))); + } + + /* Check cache. */ + res = cuddCacheLookup(dd,DD_ADD_BDD_DO_INTERVAL_TAG,f,l,u); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = addBddDoInterval(dd,fv,l,u); + if (T == NULL) return(NULL); + cuddRef(T); + + E = addBddDoInterval(dd,fvn,l,u); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert(dd,DD_ADD_BDD_DO_INTERVAL_TAG,f,l,u,res); + + return(res); + +} /* end of addBddDoInterval */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_addBddIthBit.] + + Description [Performs the recursive step for Cudd_addBddIthBit. + Returns a pointer to the BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +addBddDoIthBit( + DdManager * dd, + DdNode * f, + DdNode * index) +{ + DdNode *res, *T, *E; + DdNode *fv, *fvn; + int mask, value; + int v; + + statLine(dd); + /* Check terminal case. */ + if (cuddIsConstant(f)) { + mask = 1 << ((int) cuddV(index)); + value = (int) cuddV(f); + return(Cudd_NotCond(DD_ONE(dd),(value & mask) == 0)); + } + + /* Check cache. */ + res = cuddCacheLookup2(dd,addBddDoIthBit,f,index); + if (res != NULL) return(res); + + /* Recursive step. */ + v = f->index; + fv = cuddT(f); fvn = cuddE(f); + + T = addBddDoIthBit(dd,fv,index); + if (T == NULL) return(NULL); + cuddRef(T); + + E = addBddDoIthBit(dd,fvn,index); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); + } else { + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + } + cuddDeref(T); + cuddDeref(E); + + /* Store result. */ + cuddCacheInsert2(dd,addBddDoIthBit,f,index,res); + + return(res); + +} /* end of addBddDoIthBit */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step for Cudd_BddToAdd.] + + Description [Performs the recursive step for Cudd_BddToAdd. Returns a + pointer to the resulting ADD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +ddBddToAddRecur( + DdManager * dd, + DdNode * B) +{ + DdNode *one; + DdNode *res, *res1, *T, *E, *Bt, *Be; + int complement = 0; + + statLine(dd); + one = DD_ONE(dd); + + if (Cudd_IsConstant(B)) { + if (B == one) { + res = one; + } else { + res = DD_ZERO(dd); + } + return(res); + } + /* Check visited table */ + res = cuddCacheLookup1(dd,ddBddToAddRecur,B); + if (res != NULL) return(res); + + if (Cudd_IsComplement(B)) { + complement = 1; + Bt = cuddT(Cudd_Regular(B)); + Be = cuddE(Cudd_Regular(B)); + } else { + Bt = cuddT(B); + Be = cuddE(B); + } + + T = ddBddToAddRecur(dd, Bt); + if (T == NULL) return(NULL); + cuddRef(T); + + E = ddBddToAddRecur(dd, Be); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + + /* No need to check for T == E, because it is guaranteed not to happen. */ + res = cuddUniqueInter(dd, (int) Cudd_Regular(B)->index, T, E); + if (res == NULL) { + Cudd_RecursiveDeref(dd ,T); + Cudd_RecursiveDeref(dd ,E); + return(NULL); + } + cuddDeref(T); + cuddDeref(E); + + if (complement) { + cuddRef(res); + res1 = cuddAddCmplRecur(dd, res); + if (res1 == NULL) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(res1); + Cudd_RecursiveDeref(dd, res); + res = res1; + cuddDeref(res); + } + + /* Store result. */ + cuddCacheInsert1(dd,ddBddToAddRecur,B,res); + + return(res); + +} /* end of ddBddToAddRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddTransfer.] + + Description [Performs the recursive step of Cudd_bddTransfer. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddBddTransfer] + +******************************************************************************/ +static DdNode * +cuddBddTransferRecur( + DdManager * ddS, + DdManager * ddD, + DdNode * f, + st_table * table) +{ + DdNode *ft, *fe, *t, *e, *var, *res; + DdNode *one, *zero; + int index; + int comple = 0; + + statLine(ddD); + one = DD_ONE(ddD); + comple = Cudd_IsComplement(f); + + /* Trivial cases. */ + if (Cudd_IsConstant(f)) return(Cudd_NotCond(one, comple)); + + /* Make canonical to increase the utilization of the cache. */ + f = Cudd_NotCond(f,comple); + /* Now f is a regular pointer to a non-constant node. */ + + /* Check the cache. */ + if (st_lookup(table, f, &res)) + return(Cudd_NotCond(res,comple)); + + /* Recursive step. */ + index = f->index; + ft = cuddT(f); fe = cuddE(f); + + t = cuddBddTransferRecur(ddS, ddD, ft, table); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + + e = cuddBddTransferRecur(ddS, ddD, fe, table); + if (e == NULL) { + Cudd_RecursiveDeref(ddD, t); + return(NULL); + } + cuddRef(e); + + zero = Cudd_Not(one); + var = cuddUniqueInter(ddD,index,one,zero); + if (var == NULL) { + Cudd_RecursiveDeref(ddD, t); + Cudd_RecursiveDeref(ddD, e); + return(NULL); + } + res = cuddBddIteRecur(ddD,var,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(ddD, t); + Cudd_RecursiveDeref(ddD, e); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(ddD, t); + Cudd_RecursiveDeref(ddD, e); + + if (st_add_direct(table, (char *) f, (char *) res) == ST_OUT_OF_MEM) { + Cudd_RecursiveDeref(ddD, res); + return(NULL); + } + return(Cudd_NotCond(res,comple)); + +} /* end of cuddBddTransferRecur */ + diff --git a/cudd_local/cudd/cuddCache.c b/cudd_local/cudd/cuddCache.c new file mode 100644 index 0000000..bf98c69 --- /dev/null +++ b/cudd_local/cudd/cuddCache.c @@ -0,0 +1,1053 @@ +/**CFile*********************************************************************** + + FileName [cuddCache.c] + + PackageName [cudd] + + Synopsis [Functions for cache insertion and lookup.] + + Description [Internal procedures included in this module: +
    +
  • cuddInitCache() +
  • cuddCacheInsert() +
  • cuddCacheInsert2() +
  • cuddCacheLookup() +
  • cuddCacheLookupZdd() +
  • cuddCacheLookup2() +
  • cuddCacheLookup2Zdd() +
  • cuddConstantLookup() +
  • cuddCacheProfile() +
  • cuddCacheResize() +
  • cuddCacheFlush() +
  • cuddComputeFloorLog2() +
+ Static procedures included in this module: +
    +
] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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 */ +/*---------------------------------------------------------------------------*/ + +#ifdef DD_CACHE_PROFILE +#define DD_HYSTO_BINS 8 +#endif + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddCache.c,v 1.36 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Initializes the computed table.] + + Description [Initializes the computed table. It is called by + Cudd_Init. Returns 1 in case of success; 0 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Init] + +******************************************************************************/ +int +cuddInitCache( + DdManager * unique /* unique table */, + unsigned int cacheSize /* initial size of the cache */, + unsigned int maxCacheSize /* cache size beyond which no resizing occurs */) +{ + int i; + unsigned int logSize; +#ifndef DD_CACHE_PROFILE + DdNodePtr *mem; + ptruint offset; +#endif + + /* Round cacheSize to largest power of 2 not greater than the requested + ** initial cache size. */ + logSize = cuddComputeFloorLog2(ddMax(cacheSize,unique->slots/2)); + cacheSize = 1 << logSize; + unique->acache = ALLOC(DdCache,cacheSize+1); + if (unique->acache == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + /* If the size of the cache entry is a power of 2, we want to + ** enforce alignment to that power of two. This happens when + ** DD_CACHE_PROFILE is not defined. */ +#ifdef DD_CACHE_PROFILE + unique->cache = unique->acache; + unique->memused += (cacheSize) * sizeof(DdCache); +#else + mem = (DdNodePtr *) unique->acache; + offset = (ptruint) mem & (sizeof(DdCache) - 1); + mem += (sizeof(DdCache) - offset) / sizeof(DdNodePtr); + unique->cache = (DdCache *) mem; + assert(((ptruint) unique->cache & (sizeof(DdCache) - 1)) == 0); + unique->memused += (cacheSize+1) * sizeof(DdCache); +#endif + unique->cacheSlots = cacheSize; + unique->cacheShift = sizeof(int) * 8 - logSize; + unique->maxCacheHard = maxCacheSize; + /* If cacheSlack is non-negative, we can resize. */ + unique->cacheSlack = (int) ddMin(maxCacheSize, + DD_MAX_CACHE_TO_SLOTS_RATIO*unique->slots) - + 2 * (int) cacheSize; + Cudd_SetMinHit(unique,DD_MIN_HIT); + /* Initialize to avoid division by 0 and immediate resizing. */ + unique->cacheMisses = (double) (int) (cacheSize * unique->minHit + 1); + unique->cacheHits = 0; + unique->totCachehits = 0; + /* The sum of cacheMisses and totCacheMisses is always correct, + ** even though cacheMisses is larger than it should for the reasons + ** explained above. */ + unique->totCacheMisses = -unique->cacheMisses; + unique->cachecollisions = 0; + unique->cacheinserts = 0; + unique->cacheLastInserts = 0; + unique->cachedeletions = 0; + + /* Initialize the cache */ + for (i = 0; (unsigned) i < cacheSize; i++) { + unique->cache[i].h = 0; /* unused slots */ + unique->cache[i].data = NULL; /* invalid entry */ +#ifdef DD_CACHE_PROFILE + unique->cache[i].count = 0; +#endif + } + + return(1); + +} /* end of cuddInitCache */ + + +/**Function******************************************************************** + + Synopsis [Inserts a result in the cache for a function with three + operands.] + + Description [Inserts a result in the cache for a function with three + operands. The operator tag (see cuddInt.h for details) is split and stored + into unused bits of the first two pointers.] + + SideEffects [None] + + SeeAlso [cuddCacheInsert2 cuddCacheInsert1] + +******************************************************************************/ +void +cuddCacheInsert( + DdManager * table, + ptruint op, + DdNode * f, + DdNode * g, + DdNode * h, + DdNode * data) +{ + int posn; + register DdCache *entry; + ptruint uf, ug, uh; + + uf = (ptruint) f | (op & 0xe); + ug = (ptruint) g | (op >> 4); + uh = (ptruint) h; + + posn = ddCHash2(uh,uf,ug,table->cacheShift); + entry = &table->cache[posn]; + + table->cachecollisions += entry->data != NULL; + table->cacheinserts++; + + entry->f = (DdNode *) uf; + entry->g = (DdNode *) ug; + entry->h = uh; + entry->data = data; +#ifdef DD_CACHE_PROFILE + entry->count++; +#endif + +} /* end of cuddCacheInsert */ + + +/**Function******************************************************************** + + Synopsis [Inserts a result in the cache for a function with two + operands.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddCacheInsert cuddCacheInsert1] + +******************************************************************************/ +void +cuddCacheInsert2( + DdManager * table, + DD_CTFP op, + DdNode * f, + DdNode * g, + DdNode * data) +{ + int posn; + register DdCache *entry; + + posn = ddCHash2(op,f,g,table->cacheShift); + entry = &table->cache[posn]; + + if (entry->data != NULL) { + table->cachecollisions++; + } + table->cacheinserts++; + + entry->f = f; + entry->g = g; + entry->h = (ptruint) op; + entry->data = data; +#ifdef DD_CACHE_PROFILE + entry->count++; +#endif + +} /* end of cuddCacheInsert2 */ + + +/**Function******************************************************************** + + Synopsis [Inserts a result in the cache for a function with two + operands.] + + Description [] + + SideEffects [None] + + SeeAlso [cuddCacheInsert cuddCacheInsert2] + +******************************************************************************/ +void +cuddCacheInsert1( + DdManager * table, + DD_CTFP1 op, + DdNode * f, + DdNode * data) +{ + int posn; + register DdCache *entry; + + posn = ddCHash2(op,f,f,table->cacheShift); + entry = &table->cache[posn]; + + if (entry->data != NULL) { + table->cachecollisions++; + } + table->cacheinserts++; + + entry->f = f; + entry->g = f; + entry->h = (ptruint) op; + entry->data = data; +#ifdef DD_CACHE_PROFILE + entry->count++; +#endif + +} /* end of cuddCacheInsert1 */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f, + g, and h.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookup2 cuddCacheLookup1] + +******************************************************************************/ +DdNode * +cuddCacheLookup( + DdManager * table, + ptruint op, + DdNode * f, + DdNode * g, + DdNode * h) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + ptruint uf, ug, uh; + + uf = (ptruint) f | (op & 0xe); + ug = (ptruint) g | (op >> 4); + uh = (ptruint) h; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(uh,uf,ug,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==(DdNodePtr)uf && en->g==(DdNodePtr)ug && + en->h==uh) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaim(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookup */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f, + g, and h.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookup2Zdd cuddCacheLookup1Zdd] + +******************************************************************************/ +DdNode * +cuddCacheLookupZdd( + DdManager * table, + ptruint op, + DdNode * f, + DdNode * g, + DdNode * h) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + ptruint uf, ug, uh; + + uf = (ptruint) f | (op & 0xe); + ug = (ptruint) g | (op >> 4); + uh = (ptruint) h; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(uh,uf,ug,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==(DdNodePtr)uf && en->g==(DdNodePtr)ug && + en->h==uh) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaimZdd(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookupZdd */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f + and g.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookup cuddCacheLookup1] + +******************************************************************************/ +DdNode * +cuddCacheLookup2( + DdManager * table, + DD_CTFP op, + DdNode * f, + DdNode * g) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(op,f,g,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==f && en->g==g && en->h==(ptruint)op) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaim(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookup2 */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookup cuddCacheLookup2] + +******************************************************************************/ +DdNode * +cuddCacheLookup1( + DdManager * table, + DD_CTFP1 op, + DdNode * f) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(op,f,f,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==f && en->h==(ptruint)op) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaim(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookup1 */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f + and g.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookupZdd cuddCacheLookup1Zdd] + +******************************************************************************/ +DdNode * +cuddCacheLookup2Zdd( + DdManager * table, + DD_CTFP op, + DdNode * f, + DdNode * g) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(op,f,g,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==f && en->g==g && en->h==(ptruint)op) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaimZdd(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookup2Zdd */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f.] + + Description [Returns the result if found; it returns NULL if no + result is found.] + + SideEffects [None] + + SeeAlso [cuddCacheLookupZdd cuddCacheLookup2Zdd] + +******************************************************************************/ +DdNode * +cuddCacheLookup1Zdd( + DdManager * table, + DD_CTFP1 op, + DdNode * f) +{ + int posn; + DdCache *en,*cache; + DdNode *data; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + + posn = ddCHash2(op,f,f,table->cacheShift); + en = &cache[posn]; + if (en->data != NULL && en->f==f && en->h==(ptruint)op) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaimZdd(table,data); + } + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddCacheLookup1Zdd */ + + +/**Function******************************************************************** + + Synopsis [Looks up in the cache for the result of op applied to f, + g, and h.] + + Description [Looks up in the cache for the result of op applied to f, + g, and h. Assumes that the calling procedure (e.g., + Cudd_bddIteConstant) is only interested in whether the result is + constant or not. Returns the result if found (possibly + DD_NON_CONSTANT); otherwise it returns NULL.] + + SideEffects [None] + + SeeAlso [cuddCacheLookup] + +******************************************************************************/ +DdNode * +cuddConstantLookup( + DdManager * table, + ptruint op, + DdNode * f, + DdNode * g, + DdNode * h) +{ + int posn; + DdCache *en,*cache; + ptruint uf, ug, uh; + + uf = (ptruint) f | (op & 0xe); + ug = (ptruint) g | (op >> 4); + uh = (ptruint) h; + + cache = table->cache; +#ifdef DD_DEBUG + if (cache == NULL) { + return(NULL); + } +#endif + posn = ddCHash2(uh,uf,ug,table->cacheShift); + en = &cache[posn]; + + /* We do not reclaim here because the result should not be + * referenced, but only tested for being a constant. + */ + if (en->data != NULL && + en->f == (DdNodePtr)uf && en->g == (DdNodePtr)ug && en->h == uh) { + table->cacheHits++; + return(en->data); + } + + /* Cache miss: decide whether to resize. */ + table->cacheMisses++; + + if (table->cacheSlack >= 0 && + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); + } + + return(NULL); + +} /* end of cuddConstantLookup */ + + +/**Function******************************************************************** + + Synopsis [Computes and prints a profile of the cache usage.] + + Description [Computes and prints a profile of the cache usage. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddCacheProfile( + DdManager * table, + FILE * fp) +{ + DdCache *cache = table->cache; + int slots = table->cacheSlots; + int nzeroes = 0; + int i, retval; + double exUsed; + +#ifdef DD_CACHE_PROFILE + double count, mean, meansq, stddev, expected; + long max, min; + int imax, imin; + double *hystogramQ, *hystogramR; /* histograms by quotient and remainder */ + int nbins = DD_HYSTO_BINS; + int bin; + long thiscount; + double totalcount, exStddev; + + meansq = mean = expected = 0.0; + max = min = (long) cache[0].count; + imax = imin = 0; + totalcount = 0.0; + + hystogramQ = ALLOC(double, nbins); + if (hystogramQ == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + hystogramR = ALLOC(double, nbins); + if (hystogramR == NULL) { + FREE(hystogramQ); + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < nbins; i++) { + hystogramQ[i] = 0; + hystogramR[i] = 0; + } + + for (i = 0; i < slots; i++) { + thiscount = (long) cache[i].count; + if (thiscount > max) { + max = thiscount; + imax = i; + } + if (thiscount < min) { + min = thiscount; + imin = i; + } + if (thiscount == 0) { + nzeroes++; + } + count = (double) thiscount; + mean += count; + meansq += count * count; + totalcount += count; + expected += count * (double) i; + bin = (i * nbins) / slots; + hystogramQ[bin] += (double) thiscount; + bin = i % nbins; + hystogramR[bin] += (double) thiscount; + } + mean /= (double) slots; + meansq /= (double) slots; + + /* Compute the standard deviation from both the data and the + ** theoretical model for a random distribution. */ + stddev = sqrt(meansq - mean*mean); + exStddev = sqrt((1 - 1/(double) slots) * totalcount / (double) slots); + + retval = fprintf(fp,"Cache average accesses = %g\n", mean); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache access standard deviation = %g ", stddev); + if (retval == EOF) return(0); + retval = fprintf(fp,"(expected = %g)\n", exStddev); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache max accesses = %ld for slot %d\n", max, imax); + if (retval == EOF) return(0); + retval = fprintf(fp,"Cache min accesses = %ld for slot %d\n", min, imin); + if (retval == EOF) return(0); + exUsed = 100.0 * (1.0 - exp(-totalcount / (double) slots)); + retval = fprintf(fp,"Cache used slots = %.2f%% (expected %.2f%%)\n", + 100.0 - (double) nzeroes * 100.0 / (double) slots, + exUsed); + if (retval == EOF) return(0); + + if (totalcount > 0) { + expected /= totalcount; + retval = fprintf(fp,"Cache access hystogram for %d bins", nbins); + if (retval == EOF) return(0); + retval = fprintf(fp," (expected bin value = %g)\nBy quotient:", + expected); + if (retval == EOF) return(0); + for (i = nbins - 1; i>=0; i--) { + retval = fprintf(fp," %.0f", hystogramQ[i]); + if (retval == EOF) return(0); + } + retval = fprintf(fp,"\nBy residue: "); + if (retval == EOF) return(0); + for (i = nbins - 1; i>=0; i--) { + retval = fprintf(fp," %.0f", hystogramR[i]); + if (retval == EOF) return(0); + } + retval = fprintf(fp,"\n"); + if (retval == EOF) return(0); + } + + FREE(hystogramQ); + FREE(hystogramR); +#else + for (i = 0; i < slots; i++) { + nzeroes += cache[i].h == 0; + } + exUsed = 100.0 * + (1.0 - exp(-(table->cacheinserts - table->cacheLastInserts) / + (double) slots)); + retval = fprintf(fp,"Cache used slots = %.2f%% (expected %.2f%%)\n", + 100.0 - (double) nzeroes * 100.0 / (double) slots, + exUsed); + if (retval == EOF) return(0); +#endif + return(1); + +} /* end of cuddCacheProfile */ + + +/**Function******************************************************************** + + Synopsis [Resizes the cache.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddCacheResize( + DdManager * table) +{ + DdCache *cache, *oldcache, *oldacache, *entry, *old; + int i; + int posn, shift; + unsigned int slots, oldslots; + double offset; + int moved = 0; + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; +#ifndef DD_CACHE_PROFILE + ptruint misalignment; + DdNodePtr *mem; +#endif + + oldcache = table->cache; + oldacache = table->acache; + oldslots = table->cacheSlots; + slots = table->cacheSlots = oldslots << 1; + +#ifdef DD_VERBOSE + (void) fprintf(table->err,"Resizing the cache from %d to %d entries\n", + oldslots, slots); + (void) fprintf(table->err, + "\thits = %g\tmisses = %g\thit ratio = %5.3f\n", + table->cacheHits, table->cacheMisses, + table->cacheHits / (table->cacheHits + table->cacheMisses)); +#endif + + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + table->acache = cache = ALLOC(DdCache,slots+1); + MMoutOfMemory = saveHandler; + /* If we fail to allocate the new table we just give up. */ + if (cache == NULL) { +#ifdef DD_VERBOSE + (void) fprintf(table->err,"Resizing failed. Giving up.\n"); +#endif + table->cacheSlots = oldslots; + table->acache = oldacache; + /* Do not try to resize again. */ + table->maxCacheHard = oldslots - 1; + table->cacheSlack = - (int) (oldslots + 1); + return; + } + /* If the size of the cache entry is a power of 2, we want to + ** enforce alignment to that power of two. This happens when + ** DD_CACHE_PROFILE is not defined. */ +#ifdef DD_CACHE_PROFILE + table->cache = cache; +#else + mem = (DdNodePtr *) cache; + misalignment = (ptruint) mem & (sizeof(DdCache) - 1); + mem += (sizeof(DdCache) - misalignment) / sizeof(DdNodePtr); + table->cache = cache = (DdCache *) mem; + assert(((ptruint) table->cache & (sizeof(DdCache) - 1)) == 0); +#endif + shift = --(table->cacheShift); + table->memused += (slots - oldslots) * sizeof(DdCache); + table->cacheSlack -= slots; /* need these many slots to double again */ + + /* Clear new cache. */ + for (i = 0; (unsigned) i < slots; i++) { + cache[i].data = NULL; + cache[i].h = 0; +#ifdef DD_CACHE_PROFILE + cache[i].count = 0; +#endif + } + + /* Copy from old cache to new one. */ + for (i = 0; (unsigned) i < oldslots; i++) { + old = &oldcache[i]; + if (old->data != NULL) { + posn = ddCHash2(old->h,old->f,old->g,shift); + entry = &cache[posn]; + entry->f = old->f; + entry->g = old->g; + entry->h = old->h; + entry->data = old->data; +#ifdef DD_CACHE_PROFILE + entry->count = 1; +#endif + moved++; + } + } + + FREE(oldacache); + + /* Reinitialize measurements so as to avoid division by 0 and + ** immediate resizing. + */ + offset = (double) (int) (slots * table->minHit + 1); + table->totCacheMisses += table->cacheMisses - offset; + table->cacheMisses = offset; + table->totCachehits += table->cacheHits; + table->cacheHits = 0; + table->cacheLastInserts = table->cacheinserts - (double) moved; + +} /* end of cuddCacheResize */ + + +/**Function******************************************************************** + + Synopsis [Flushes the cache.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddCacheFlush( + DdManager * table) +{ + int i, slots; + DdCache *cache; + + slots = table->cacheSlots; + cache = table->cache; + for (i = 0; i < slots; i++) { + table->cachedeletions += cache[i].data != NULL; + cache[i].data = NULL; + } + table->cacheLastInserts = table->cacheinserts; + + return; + +} /* end of cuddCacheFlush */ + + +/**Function******************************************************************** + + Synopsis [Returns the floor of the logarithm to the base 2.] + + Description [Returns the floor of the logarithm to the base 2. + The input value is assumed to be greater than 0.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddComputeFloorLog2( + unsigned int value) +{ + int floorLog = 0; +#ifdef DD_DEBUG + assert(value > 0); +#endif + while (value > 1) { + floorLog++; + value >>= 1; + } + return(floorLog); + +} /* end of cuddComputeFloorLog2 */ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ diff --git a/cudd_local/cudd/cuddCheck.c b/cudd_local/cudd/cuddCheck.c new file mode 100644 index 0000000..424aaba --- /dev/null +++ b/cudd_local/cudd/cuddCheck.c @@ -0,0 +1,885 @@ +/**CFile*********************************************************************** + + FileName [cuddCheck.c] + + PackageName [cudd] + + Synopsis [Functions to check consistency of data structures.] + + Description [External procedures included in this module: +
    +
  • Cudd_DebugCheck() +
  • Cudd_CheckKeys() +
+ Internal procedures included in this module: +
    +
  • cuddHeapProfile() +
  • cuddPrintNode() +
  • cuddPrintVarGroups() +
+ Static procedures included in this module: +
    +
  • debugFindParent() +
+ ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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: cuddCheck.c,v 1.37 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static void debugFindParent (DdManager *table, DdNode *node); +#if 0 +static void debugCheckParent (DdManager *table, DdNode *node); +#endif + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Checks for inconsistencies in the DD heap.] + + Description [Checks for inconsistencies in the DD heap: +
    +
  • node has illegal index +
  • live node has dead children +
  • node has illegal Then or Else pointers +
  • BDD/ADD node has identical children +
  • ZDD node has zero then child +
  • wrong number of total nodes +
  • wrong number of dead nodes +
  • ref count error at node +
+ Returns 0 if no inconsistencies are found; DD_OUT_OF_MEM if there is + not enough memory; 1 otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_CheckKeys] + +******************************************************************************/ +int +Cudd_DebugCheck( + DdManager * table) +{ + unsigned int i; + int j,count; + int slots; + DdNodePtr *nodelist; + DdNode *f; + DdNode *sentinel = &(table->sentinel); + st_table *edgeTable; /* stores internal ref count for each node */ + st_generator *gen; + int flag = 0; + int totalNode; + int deadNode; + int index; + int shift; + + edgeTable = st_init_table(st_ptrcmp,st_ptrhash); + if (edgeTable == NULL) return(CUDD_OUT_OF_MEM); + + /* Check the BDD/ADD subtables. */ + for (i = 0; i < (unsigned) table->size; i++) { + index = table->invperm[i]; + if (i != (unsigned) table->perm[index]) { + (void) fprintf(table->err, + "Permutation corrupted: invperm[%u] = %d\t perm[%d] = %d\n", + i, index, index, table->perm[index]); + } + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + shift = table->subtables[i].shift; + + totalNode = 0; + deadNode = 0; + for (j = 0; j < slots; j++) { /* for each subtable slot */ + f = nodelist[j]; + while (f != sentinel) { + totalNode++; + if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) { + if ((int) f->index != index) { + (void) fprintf(table->err, + "Error: node has illegal index\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if ((unsigned) cuddI(table,cuddT(f)->index) <= i || + (unsigned) cuddI(table,Cudd_Regular(cuddE(f))->index) + <= i) { + (void) fprintf(table->err, + "Error: node has illegal children\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (Cudd_Regular(cuddT(f)) != cuddT(f)) { + (void) fprintf(table->err, + "Error: node has illegal form\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (cuddT(f) == cuddE(f)) { + (void) fprintf(table->err, + "Error: node has identical children\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (cuddT(f)->ref == 0 || Cudd_Regular(cuddE(f))->ref == 0) { + (void) fprintf(table->err, + "Error: live node has dead children\n"); + cuddPrintNode(f,table->err); + flag =1; + } + if (ddHash(cuddT(f),cuddE(f),shift) != j) { + (void) fprintf(table->err, "Error: misplaced node\n"); + cuddPrintNode(f,table->err); + flag =1; + } + /* Increment the internal reference count for the + ** then child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)cuddT(f),&count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)cuddT(f), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + return(CUDD_OUT_OF_MEM); + } + + /* Increment the internal reference count for the + ** else child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)Cudd_Regular(cuddE(f)), + &count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)Cudd_Regular(cuddE(f)), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + return(CUDD_OUT_OF_MEM); + } + } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) { + deadNode++; +#if 0 + debugCheckParent(table,f); +#endif + } else { + fprintf(table->err, + "Error: node has illegal Then or Else pointers\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + + f = f->next; + } /* for each element of the collision list */ + } /* for each subtable slot */ + + if ((unsigned) totalNode != table->subtables[i].keys) { + fprintf(table->err,"Error: wrong number of total nodes\n"); + flag = 1; + } + if ((unsigned) deadNode != table->subtables[i].dead) { + fprintf(table->err,"Error: wrong number of dead nodes\n"); + flag = 1; + } + } /* for each BDD/ADD subtable */ + + /* Check the ZDD subtables. */ + for (i = 0; i < (unsigned) table->sizeZ; i++) { + index = table->invpermZ[i]; + if (i != (unsigned) table->permZ[index]) { + (void) fprintf(table->err, + "Permutation corrupted: invpermZ[%u] = %d\t permZ[%d] = %d in ZDD\n", + i, index, index, table->permZ[index]); + } + nodelist = table->subtableZ[i].nodelist; + slots = table->subtableZ[i].slots; + + totalNode = 0; + deadNode = 0; + for (j = 0; j < slots; j++) { /* for each subtable slot */ + f = nodelist[j]; + while (f != NULL) { + totalNode++; + if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) { + if ((int) f->index != index) { + (void) fprintf(table->err, + "Error: ZDD node has illegal index\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (Cudd_IsComplement(cuddT(f)) || + Cudd_IsComplement(cuddE(f))) { + (void) fprintf(table->err, + "Error: ZDD node has complemented children\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if ((unsigned) cuddIZ(table,cuddT(f)->index) <= i || + (unsigned) cuddIZ(table,cuddE(f)->index) <= i) { + (void) fprintf(table->err, + "Error: ZDD node has illegal children\n"); + cuddPrintNode(f,table->err); + cuddPrintNode(cuddT(f),table->err); + cuddPrintNode(cuddE(f),table->err); + flag = 1; + } + if (cuddT(f) == DD_ZERO(table)) { + (void) fprintf(table->err, + "Error: ZDD node has zero then child\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (cuddT(f)->ref == 0 || cuddE(f)->ref == 0) { + (void) fprintf(table->err, + "Error: ZDD live node has dead children\n"); + cuddPrintNode(f,table->err); + flag =1; + } + /* Increment the internal reference count for the + ** then child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)cuddT(f),&count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)cuddT(f), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + return(CUDD_OUT_OF_MEM); + } + + /* Increment the internal reference count for the + ** else child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)cuddE(f),&count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)cuddE(f), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + table->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); + } + } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) { + deadNode++; +#if 0 + debugCheckParent(table,f); +#endif + } else { + fprintf(table->err, + "Error: ZDD node has illegal Then or Else pointers\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + + f = f->next; + } /* for each element of the collision list */ + } /* for each subtable slot */ + + if ((unsigned) totalNode != table->subtableZ[i].keys) { + fprintf(table->err, + "Error: wrong number of total nodes in ZDD\n"); + flag = 1; + } + if ((unsigned) deadNode != table->subtableZ[i].dead) { + fprintf(table->err, + "Error: wrong number of dead nodes in ZDD\n"); + flag = 1; + } + } /* for each ZDD subtable */ + + /* Check the constant table. */ + nodelist = table->constants.nodelist; + slots = table->constants.slots; + + totalNode = 0; + deadNode = 0; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != NULL) { + totalNode++; + if (f->ref != 0) { + if (f->index != CUDD_CONST_INDEX) { + fprintf(table->err,"Error: node has illegal index\n"); +#if SIZEOF_VOID_P == 8 + fprintf(table->err, + " node 0x%lx, id = %u, ref = %u, value = %g\n", + (ptruint)f,f->index,f->ref,cuddV(f)); +#else + fprintf(table->err, + " node 0x%x, id = %hu, ref = %hu, value = %g\n", + (ptruint)f,f->index,f->ref,cuddV(f)); +#endif + flag = 1; + } + } else { + deadNode++; + } + f = f->next; + } + } + if ((unsigned) totalNode != table->constants.keys) { + (void) fprintf(table->err, + "Error: wrong number of total nodes in constants\n"); + flag = 1; + } + if ((unsigned) deadNode != table->constants.dead) { + (void) fprintf(table->err, + "Error: wrong number of dead nodes in constants\n"); + flag = 1; + } + gen = st_init_gen(edgeTable); + while (st_gen(gen, &f, &count)) { + if (count > (int)(f->ref) && f->ref != DD_MAXREF) { +#if SIZEOF_VOID_P == 8 + fprintf(table->err,"ref count error at node 0x%lx, count = %d, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n",(ptruint)f,count,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#else + fprintf(table->err,"ref count error at node 0x%x, count = %d, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n",(ptruint)f,count,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#endif + debugFindParent(table,f); + flag = 1; + } + } + st_free_gen(gen); + st_free_table(edgeTable); + + return (flag); + +} /* end of Cudd_DebugCheck */ + + +/**Function******************************************************************** + + Synopsis [Checks for several conditions that should not occur.] + + Description [Checks for the following conditions: +
    +
  • Wrong sizes of subtables. +
  • Wrong number of keys found in unique subtable. +
  • Wrong number of dead found in unique subtable. +
  • Wrong number of keys found in the constant table +
  • Wrong number of dead found in the constant table +
  • Wrong number of total slots found +
  • Wrong number of maximum keys found +
  • Wrong number of total dead found +
+ Reports the average length of non-empty lists. Returns the number of + subtables for which the number of keys is wrong.] + + SideEffects [None] + + SeeAlso [Cudd_DebugCheck] + +******************************************************************************/ +int +Cudd_CheckKeys( + DdManager * table) +{ + int size; + int i,j; + DdNodePtr *nodelist; + DdNode *node; + DdNode *sentinel = &(table->sentinel); + DdSubtable *subtable; + int keys; + int dead; + int count = 0; + int totalKeys = 0; + int totalSlots = 0; + int totalDead = 0; + int nonEmpty = 0; + unsigned int slots; + int logSlots; + int shift; + + size = table->size; + + for (i = 0; i < size; i++) { + subtable = &(table->subtables[i]); + nodelist = subtable->nodelist; + keys = subtable->keys; + dead = subtable->dead; + totalKeys += keys; + slots = subtable->slots; + shift = subtable->shift; + logSlots = sizeof(int) * 8 - shift; + if (((slots >> logSlots) << logSlots) != slots) { + (void) fprintf(table->err, + "Unique table %d is not the right power of 2\n", i); + (void) fprintf(table->err, + " slots = %u shift = %d\n", slots, shift); + } + totalSlots += slots; + totalDead += dead; + for (j = 0; (unsigned) j < slots; j++) { + node = nodelist[j]; + if (node != sentinel) { + nonEmpty++; + } + while (node != sentinel) { + keys--; + if (node->ref == 0) { + dead--; + } + node = node->next; + } + } + if (keys != 0) { + (void) fprintf(table->err, "Wrong number of keys found \ +in unique table %d (difference=%d)\n", i, keys); + count++; + } + if (dead != 0) { + (void) fprintf(table->err, "Wrong number of dead found \ +in unique table no. %d (difference=%d)\n", i, dead); + } + } /* for each BDD/ADD subtable */ + + /* Check the ZDD subtables. */ + size = table->sizeZ; + + for (i = 0; i < size; i++) { + subtable = &(table->subtableZ[i]); + nodelist = subtable->nodelist; + keys = subtable->keys; + dead = subtable->dead; + totalKeys += keys; + totalSlots += subtable->slots; + totalDead += dead; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != NULL) { + nonEmpty++; + } + while (node != NULL) { + keys--; + if (node->ref == 0) { + dead--; + } + node = node->next; + } + } + if (keys != 0) { + (void) fprintf(table->err, "Wrong number of keys found \ +in ZDD unique table no. %d (difference=%d)\n", i, keys); + count++; + } + if (dead != 0) { + (void) fprintf(table->err, "Wrong number of dead found \ +in ZDD unique table no. %d (difference=%d)\n", i, dead); + } + } /* for each ZDD subtable */ + + /* Check the constant table. */ + subtable = &(table->constants); + nodelist = subtable->nodelist; + keys = subtable->keys; + dead = subtable->dead; + totalKeys += keys; + totalSlots += subtable->slots; + totalDead += dead; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != NULL) { + nonEmpty++; + } + while (node != NULL) { + keys--; + if (node->ref == 0) { + dead--; + } + node = node->next; + } + } + if (keys != 0) { + (void) fprintf(table->err, "Wrong number of keys found \ +in the constant table (difference=%d)\n", keys); + count++; + } + if (dead != 0) { + (void) fprintf(table->err, "Wrong number of dead found \ +in the constant table (difference=%d)\n", dead); + } + if ((unsigned) totalKeys != table->keys + table->keysZ) { + (void) fprintf(table->err, "Wrong number of total keys found \ +(difference=%d)\n", (int) (totalKeys-table->keys)); + } + if ((unsigned) totalSlots != table->slots) { + (void) fprintf(table->err, "Wrong number of total slots found \ +(difference=%d)\n", (int) (totalSlots-table->slots)); + } + if (table->minDead != (unsigned) (table->gcFrac * table->slots)) { + (void) fprintf(table->err, "Wrong number of minimum dead found \ +(%u vs. %u)\n", table->minDead, + (unsigned) (table->gcFrac * (double) table->slots)); + } + if ((unsigned) totalDead != table->dead + table->deadZ) { + (void) fprintf(table->err, "Wrong number of total dead found \ +(difference=%d)\n", (int) (totalDead-table->dead)); + } + (void) fprintf(table->out,"Average length of non-empty lists = %g\n", + (double) table->keys / (double) nonEmpty); + + return(count); + +} /* end of Cudd_CheckKeys */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Prints information about the heap.] + + Description [Prints to the manager's stdout the number of live nodes for each + level of the DD heap that contains at least one live node. It also + prints a summary containing: +
    +
  • total number of tables; +
  • number of tables with live nodes; +
  • table with the largest number of live nodes; +
  • number of nodes in that table. +
+ If more than one table contains the maximum number of live nodes, + only the one of lowest index is reported. Returns 1 in case of success + and 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddHeapProfile( + DdManager * dd) +{ + int ntables = dd->size; + DdSubtable *subtables = dd->subtables; + int i, /* loop index */ + nodes, /* live nodes in i-th layer */ + retval, /* return value of fprintf */ + largest = -1, /* index of the table with most live nodes */ + maxnodes = -1, /* maximum number of live nodes in a table */ + nonempty = 0; /* number of tables with live nodes */ + + /* Print header. */ +#if SIZEOF_VOID_P == 8 + retval = fprintf(dd->out,"*** DD heap profile for 0x%lx ***\n", + (ptruint) dd); +#else + retval = fprintf(dd->out,"*** DD heap profile for 0x%x ***\n", + (ptruint) dd); +#endif + if (retval == EOF) return 0; + + /* Print number of live nodes for each nonempty table. */ + for (i=0; iout,"%5d: %5d nodes\n", i, nodes); + if (retval == EOF) return 0; + if (nodes > maxnodes) { + maxnodes = nodes; + largest = i; + } + } + } + + nodes = dd->constants.keys - dd->constants.dead; + if (nodes) { + nonempty++; + retval = fprintf(dd->out,"const: %5d nodes\n", nodes); + if (retval == EOF) return 0; + if (nodes > maxnodes) { + maxnodes = nodes; + largest = CUDD_CONST_INDEX; + } + } + + /* Print summary. */ + retval = fprintf(dd->out,"Summary: %d tables, %d non-empty, largest: %d ", + ntables+1, nonempty, largest); + if (retval == EOF) return 0; + retval = fprintf(dd->out,"(with %d nodes)\n", maxnodes); + if (retval == EOF) return 0; + + return(1); + +} /* end of cuddHeapProfile */ + + +/**Function******************************************************************** + + Synopsis [Prints out information on a node.] + + Description [Prints out information on a node.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddPrintNode( + DdNode * f, + FILE *fp) +{ + f = Cudd_Regular(f); +#if SIZEOF_VOID_P == 8 + (void) fprintf(fp," node 0x%lx, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n",(ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#else + (void) fprintf(fp," node 0x%x, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n",(ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#endif + +} /* end of cuddPrintNode */ + + + +/**Function******************************************************************** + + Synopsis [Prints the variable groups as a parenthesized list.] + + Description [Prints the variable groups as a parenthesized list. + For each group the level range that it represents is printed. After + each group, the group's flags are printed, preceded by a `|'. For + each flag (except MTR_TERMINAL) a character is printed. +
    +
  • F: MTR_FIXED +
  • N: MTR_NEWNODE +
  • S: MTR_SOFT +
+ The second argument, silent, if different from 0, causes + Cudd_PrintVarGroups to only check the syntax of the group tree.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddPrintVarGroups( + DdManager * dd /* manager */, + MtrNode * root /* root of the group tree */, + int zdd /* 0: BDD; 1: ZDD */, + int silent /* flag to check tree syntax only */) +{ + MtrNode *node; + int level; + + assert(root != NULL); + assert(root->younger == NULL || root->younger->elder == root); + assert(root->elder == NULL || root->elder->younger == root); + if (zdd) { + level = dd->permZ[root->index]; + } else { + level = dd->perm[root->index]; + } + if (!silent) (void) printf("(%d",level); + if (MTR_TEST(root,MTR_TERMINAL) || root->child == NULL) { + if (!silent) (void) printf(","); + } else { + node = root->child; + while (node != NULL) { + assert(node->low >= root->low && (int) (node->low + node->size) <= (int) (root->low + root->size)); + assert(node->parent == root); + cuddPrintVarGroups(dd,node,zdd,silent); + node = node->younger; + } + } + if (!silent) { + (void) printf("%d", (int) (level + root->size - 1)); + if (root->flags != MTR_DEFAULT) { + (void) printf("|"); + if (MTR_TEST(root,MTR_FIXED)) (void) printf("F"); + if (MTR_TEST(root,MTR_NEWNODE)) (void) printf("N"); + if (MTR_TEST(root,MTR_SOFT)) (void) printf("S"); + } + (void) printf(")"); + if (root->parent == NULL) (void) printf("\n"); + } + assert((root->flags &~(MTR_TERMINAL | MTR_SOFT | MTR_FIXED | MTR_NEWNODE)) == 0); + return; + +} /* end of cuddPrintVarGroups */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Searches the subtables above node for its parents.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +debugFindParent( + DdManager * table, + DdNode * node) +{ + int i,j; + int slots; + DdNodePtr *nodelist; + DdNode *f; + + for (i = 0; i < cuddI(table,node->index); i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + + for (j=0;jout,"parent is at 0x%lx, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n", + (ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#else + (void) fprintf(table->out,"parent is at 0x%x, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n", + (ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); +#endif + } + f = f->next; + } + } + } + +} /* end of debugFindParent */ + + +#if 0 +/**Function******************************************************************** + + Synopsis [Reports an error if a (dead) node has a non-dead parent.] + + Description [Searches all the subtables above node. Very expensive. + The same check is now implemented more efficiently in ddDebugCheck.] + + SideEffects [None] + + SeeAlso [debugFindParent] + +******************************************************************************/ +static void +debugCheckParent( + DdManager * table, + DdNode * node) +{ + int i,j; + int slots; + DdNode **nodelist,*f; + + for (i = 0; i < cuddI(table,node->index); i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + + for (j=0;jref != 0) { + (void) fprintf(table->err, + "error with zero ref count\n"); + (void) fprintf(table->err,"parent is 0x%x, id = %u, ref = %u, then = 0x%x, else = 0x%x\n",f,f->index,f->ref,cuddT(f),cuddE(f)); + (void) fprintf(table->err,"child is 0x%x, id = %u, ref = %u, then = 0x%x, else = 0x%x\n",node,node->index,node->ref,cuddT(node),cuddE(node)); + } + f = f->next; + } + } + } +} +#endif diff --git a/cudd_local/cudd/cuddClip.c b/cudd_local/cudd/cuddClip.c new file mode 100644 index 0000000..2993254 --- /dev/null +++ b/cudd_local/cudd/cuddClip.c @@ -0,0 +1,558 @@ +/**CFile*********************************************************************** + + FileName [cuddClip.c] + + PackageName [cudd] + + Synopsis [Clipping functions.] + + Description [External procedures included in this module: +
    +
  • Cudd_bddClippingAnd() +
  • Cudd_bddClippingAndAbstract() +
+ Internal procedures included in this module: +
    +
  • cuddBddClippingAnd() +
  • cuddBddClippingAndAbstract() +
+ Static procedures included in this module: +
    +
  • cuddBddClippingAndRecur() +
  • cuddBddClipAndAbsRecur() +
+ + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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: cuddClip.c,v 1.9 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * cuddBddClippingAndRecur (DdManager *manager, DdNode *f, DdNode *g, int distance, int direction); +static DdNode * cuddBddClipAndAbsRecur (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, int distance, int direction); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Approximates the conjunction of two BDDs f and g.] + + Description [Approximates the conjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddAnd] + +******************************************************************************/ +DdNode * +Cudd_bddClippingAnd( + DdManager * dd /* manager */, + DdNode * f /* first conjunct */, + DdNode * g /* second conjunct */, + int maxDepth /* maximum recursion depth */, + int direction /* under (0) or over (1) approximation */) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddClippingAnd(dd,f,g,maxDepth,direction); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddClippingAnd */ + + +/**Function******************************************************************** + + Synopsis [Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube.] + + Description [Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. The variables are + existentially abstracted. Returns a pointer to the resulting BDD if + successful; NULL if the intermediate result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddAndAbstract Cudd_bddClippingAnd] + +******************************************************************************/ +DdNode * +Cudd_bddClippingAndAbstract( + DdManager * dd /* manager */, + DdNode * f /* first conjunct */, + DdNode * g /* second conjunct */, + DdNode * cube /* cube of variables to be abstracted */, + int maxDepth /* maximum recursion depth */, + int direction /* under (0) or over (1) approximation */) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddClippingAndAbstract(dd,f,g,cube,maxDepth,direction); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddClippingAndAbstract */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Approximates the conjunction of two BDDs f and g.] + + Description [Approximates the conjunction of two BDDs f and g. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddClippingAnd] + +******************************************************************************/ +DdNode * +cuddBddClippingAnd( + DdManager * dd /* manager */, + DdNode * f /* first conjunct */, + DdNode * g /* second conjunct */, + int maxDepth /* maximum recursion depth */, + int direction /* under (0) or over (1) approximation */) +{ + DdNode *res; + + res = cuddBddClippingAndRecur(dd,f,g,maxDepth,direction); + + return(res); + +} /* end of cuddBddClippingAnd */ + + +/**Function******************************************************************** + + Synopsis [Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube.] + + Description [Approximates the conjunction of two BDDs f and g and + simultaneously abstracts the variables in cube. Returns a + pointer to the resulting BDD if successful; NULL if the intermediate + result blows up.] + + SideEffects [None] + + SeeAlso [Cudd_bddClippingAndAbstract] + +******************************************************************************/ +DdNode * +cuddBddClippingAndAbstract( + DdManager * dd /* manager */, + DdNode * f /* first conjunct */, + DdNode * g /* second conjunct */, + DdNode * cube /* cube of variables to be abstracted */, + int maxDepth /* maximum recursion depth */, + int direction /* under (0) or over (1) approximation */) +{ + DdNode *res; + + res = cuddBddClipAndAbsRecur(dd,f,g,cube,maxDepth,direction); + + return(res); + +} /* end of cuddBddClippingAndAbstract */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddClippingAnd.] + + Description [Implements the recursive step of Cudd_bddClippingAnd by taking + the conjunction of two BDDs. Returns a pointer to the result is + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [cuddBddClippingAnd] + +******************************************************************************/ +static DdNode * +cuddBddClippingAndRecur( + DdManager * manager, + DdNode * f, + DdNode * g, + int distance, + int direction) +{ + DdNode *F, *ft, *fe, *G, *gt, *ge; + DdNode *one, *zero, *r, *t, *e; + unsigned int topf, topg, index; + DD_CTFP cacheOp; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); + if (f == g || g == one) return(f); + if (f == one) return(g); + if (distance == 0) { + /* One last attempt at returning the right result. We sort of + ** cheat by calling Cudd_bddLeq. */ + if (Cudd_bddLeq(manager,f,g)) return(f); + if (Cudd_bddLeq(manager,g,f)) return(g); + if (direction == 1) { + if (Cudd_bddLeq(manager,f,Cudd_Not(g)) || + Cudd_bddLeq(manager,g,Cudd_Not(f))) return(zero); + } + return(Cudd_NotCond(one,(direction == 0))); + } + + /* At this point f and g are not constant. */ + distance--; + + /* Check cache. Try to increase cache efficiency by sorting the + ** pointers. */ + if (f > g) { + DdNode *tmp = f; + f = g; g = tmp; + } + F = Cudd_Regular(f); + G = Cudd_Regular(g); + cacheOp = (DD_CTFP) + (direction ? Cudd_bddClippingAnd : cuddBddClippingAnd); + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup2(manager, cacheOp, f, g); + if (r != NULL) return(r); + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + + /* Compute cofactors. */ + if (topf <= topg) { + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } + } else { + index = G->index; + ft = fe = f; + } + + if (topg <= topf) { + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } + } else { + gt = ge = g; + } + + t = cuddBddClippingAndRecur(manager, ft, gt, distance, direction); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddBddClippingAndRecur(manager, fe, ge, distance, direction); + if (e == NULL) { + Cudd_RecursiveDeref(manager, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + } + } + cuddDeref(e); + cuddDeref(t); + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert2(manager, cacheOp, f, g, r); + return(r); + +} /* end of cuddBddClippingAndRecur */ + + +/**Function******************************************************************** + + Synopsis [Approximates the AND of two BDDs and simultaneously abstracts the + variables in cube.] + + Description [Approximates the AND of two BDDs and simultaneously + abstracts the variables in cube. The variables are existentially + abstracted. Returns a pointer to the result is successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddClippingAndAbstract] + +******************************************************************************/ +static DdNode * +cuddBddClipAndAbsRecur( + DdManager * manager, + DdNode * f, + DdNode * g, + DdNode * cube, + int distance, + int direction) +{ + DdNode *F, *ft, *fe, *G, *gt, *ge; + DdNode *one, *zero, *r, *t, *e, *Cube; + unsigned int topf, topg, topcube, top, index; + ptruint cacheTag; + + statLine(manager); + one = DD_ONE(manager); + zero = Cudd_Not(one); + + /* Terminal cases. */ + if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); + if (f == one && g == one) return(one); + if (cube == one) { + return(cuddBddClippingAndRecur(manager, f, g, distance, direction)); + } + if (f == one || f == g) { + return (cuddBddExistAbstractRecur(manager, g, cube)); + } + if (g == one) { + return (cuddBddExistAbstractRecur(manager, f, cube)); + } + if (distance == 0) return(Cudd_NotCond(one,(direction == 0))); + + /* At this point f, g, and cube are not constant. */ + distance--; + + /* Check cache. */ + if (f > g) { /* Try to increase cache efficiency. */ + DdNode *tmp = f; + f = g; g = tmp; + } + F = Cudd_Regular(f); + G = Cudd_Regular(g); + cacheTag = direction ? DD_BDD_CLIPPING_AND_ABSTRACT_UP_TAG : + DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG; + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup(manager, cacheTag, + f, g, cube); + if (r != NULL) { + return(r); + } + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + top = ddMin(topf, topg); + topcube = manager->perm[cube->index]; + + if (topcube < top) { + return(cuddBddClipAndAbsRecur(manager, f, g, cuddT(cube), + distance, direction)); + } + /* Now, topcube >= top. */ + + if (topf == top) { + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } + } else { + index = G->index; + ft = fe = f; + } + + if (topg == top) { + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } + } else { + gt = ge = g; + } + + if (topcube == top) { + Cube = cuddT(cube); + } else { + Cube = cube; + } + + t = cuddBddClipAndAbsRecur(manager, ft, gt, Cube, distance, direction); + if (t == NULL) return(NULL); + + /* Special case: 1 OR anything = 1. Hence, no need to compute + ** the else branch if t is 1. + */ + if (t == one && topcube == top) { + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert(manager, cacheTag, f, g, cube, one); + return(one); + } + cuddRef(t); + + e = cuddBddClipAndAbsRecur(manager, fe, ge, Cube, distance, direction); + if (e == NULL) { + Cudd_RecursiveDeref(manager, t); + return(NULL); + } + cuddRef(e); + + if (topcube == top) { /* abstract */ + r = cuddBddClippingAndRecur(manager, Cudd_Not(t), Cudd_Not(e), + distance, (direction == 0)); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + r = Cudd_Not(r); + cuddRef(r); + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + cuddDeref(r); + } else if (t == e) { + r = t; + cuddDeref(t); + cuddDeref(e); + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + } + cuddDeref(e); + cuddDeref(t); + } + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert(manager, cacheTag, f, g, cube, r); + return (r); + +} /* end of cuddBddClipAndAbsRecur */ + diff --git a/cudd_local/cudd/cuddCof.c b/cudd_local/cudd/cuddCof.c new file mode 100644 index 0000000..cff47b2 --- /dev/null +++ b/cudd_local/cudd/cuddCof.c @@ -0,0 +1,327 @@ +/**CFile*********************************************************************** + + FileName [cuddCof.c] + + PackageName [cudd] + + Synopsis [Cofactoring functions.] + + Description [External procedures included in this module: +
    +
  • Cudd_Cofactor() +
  • Cudd_CheckCube() +
+ Internal procedures included in this module: +
    +
  • cuddGetBranches() +
  • cuddCofactorRecur() +
+ ] + + SeeAlso [] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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: cuddCof.c,v 1.11 2012/02/05 01:07:18 fabio Exp $"; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the cofactor of f with respect to g.] + + Description [Computes the cofactor of f with respect to g; g must be + the BDD or the ADD of a cube. Returns a pointer to the cofactor if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddConstrain Cudd_bddRestrict] + +******************************************************************************/ +DdNode * +Cudd_Cofactor( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res,*zero; + + zero = Cudd_Not(DD_ONE(dd)); + if (g == zero || g == DD_ZERO(dd)) { + (void) fprintf(dd->err,"Cudd_Cofactor: Invalid restriction 1\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + do { + dd->reordered = 0; + res = cuddCofactorRecur(dd,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_Cofactor */ + + +/**Function******************************************************************** + + Synopsis [Checks whether g is the BDD of a cube.] + + Description [Checks whether g is the BDD of a cube. Returns 1 in case + of success; 0 otherwise. The constant 1 is a valid cube, but all other + constant functions cause cuddCheckCube to return 0.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +Cudd_CheckCube( + DdManager * dd, + DdNode * g) +{ + DdNode *g1,*g0,*one,*zero; + + one = DD_ONE(dd); + if (g == one) return(1); + if (Cudd_IsConstant(g)) return(0); + + zero = Cudd_Not(one); + cuddGetBranches(g,&g1,&g0); + + if (g0 == zero) { + return(Cudd_CheckCube(dd, g1)); + } + if (g1 == zero) { + return(Cudd_CheckCube(dd, g0)); + } + return(0); + +} /* end of Cudd_CheckCube */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the children of g.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +cuddGetBranches( + DdNode * g, + DdNode ** g1, + DdNode ** g0) +{ + DdNode *G = Cudd_Regular(g); + + *g1 = cuddT(G); + *g0 = cuddE(G); + if (Cudd_IsComplement(g)) { + *g1 = Cudd_Not(*g1); + *g0 = Cudd_Not(*g0); + } + +} /* end of cuddGetBranches */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_Cofactor.] + + Description [Performs the recursive step of Cudd_Cofactor. Returns a + pointer to the cofactor if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_Cofactor] + +******************************************************************************/ +DdNode * +cuddCofactorRecur( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *one,*zero,*F,*G,*g1,*g0,*f1,*f0,*t,*e,*r; + unsigned int topf,topg; + int comple; + + statLine(dd); + F = Cudd_Regular(f); + if (cuddIsConstant(F)) return(f); + + one = DD_ONE(dd); + + /* The invariant g != 0 is true on entry to this procedure and is + ** recursively maintained by it. Therefore it suffices to test g + ** against one to make sure it is not constant. + */ + if (g == one) return(f); + /* From now on, f and g are known not to be constants. */ + + comple = f != F; + r = cuddCacheLookup2(dd,Cudd_Cofactor,F,g); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + topf = dd->perm[F->index]; + G = Cudd_Regular(g); + topg = dd->perm[G->index]; + + /* We take the cofactors of F because we are going to rely on + ** the fact that the cofactors of the complement are the complements + ** of the cofactors to better utilize the cache. Variable comple + ** remembers whether we have to complement the result or not. + */ + if (topf <= topg) { + f1 = cuddT(F); f0 = cuddE(F); + } else { + f1 = f0 = F; + } + if (topg <= topf) { + g1 = cuddT(G); g0 = cuddE(G); + if (g != G) { g1 = Cudd_Not(g1); g0 = Cudd_Not(g0); } + } else { + g1 = g0 = g; + } + + zero = Cudd_Not(one); + if (topf >= topg) { + if (g0 == zero || g0 == DD_ZERO(dd)) { + r = cuddCofactorRecur(dd, f1, g1); + } else if (g1 == zero || g1 == DD_ZERO(dd)) { + r = cuddCofactorRecur(dd, f0, g0); + } else { + (void) fprintf(dd->out, + "Cudd_Cofactor: Invalid restriction 2\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + if (r == NULL) return(NULL); + } else /* if (topf < topg) */ { + t = cuddCofactorRecur(dd, f1, g); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddCofactorRecur(dd, f0, g); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(dd,(int)F->index,Cudd_Not(t),Cudd_Not(e)); + if (r != NULL) + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(dd,(int)F->index,t,e); + } + if (r == NULL) { + Cudd_RecursiveDeref(dd ,e); + Cudd_RecursiveDeref(dd ,t); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert2(dd,Cudd_Cofactor,F,g,r); + + return(Cudd_NotCond(r,comple)); + +} /* end of cuddCofactorRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/cudd_local/cudd/cuddCompose.c b/cudd_local/cudd/cuddCompose.c new file mode 100644 index 0000000..eea044f --- /dev/null +++ b/cudd_local/cudd/cuddCompose.c @@ -0,0 +1,1749 @@ +/**CFile*********************************************************************** + + FileName [cuddCompose.c] + + PackageName [cudd] + + Synopsis [Functional composition and variable permutation of DDs.] + + Description [External procedures included in this module: +
    +
  • Cudd_bddCompose() +
  • Cudd_addCompose() +
  • Cudd_addPermute() +
  • Cudd_addSwapVariables() +
  • Cudd_bddPermute() +
  • Cudd_bddVarMap() +
  • Cudd_SetVarMap() +
  • Cudd_bddSwapVariables() +
  • Cudd_bddAdjPermuteX() +
  • Cudd_addVectorCompose() +
  • Cudd_addGeneralVectorCompose() +
  • Cudd_addNonSimCompose() +
  • Cudd_bddVectorCompose() +
+ Internal procedures included in this module: +
    +
  • cuddBddComposeRecur() +
  • cuddAddComposeRecur() +
+ Static procedures included in this module: +
    +
  • cuddAddPermuteRecur() +
  • cuddBddPermuteRecur() +
  • cuddBddVarMapRecur() +
  • cuddAddVectorComposeRecur() +
  • cuddAddGeneralVectorComposeRecur() +
  • cuddAddNonSimComposeRecur() +
  • cuddBddVectorComposeRecur() +
  • ddIsIthAddVar() +
  • ddIsIthAddVarPair() +
+ The permutation functions use a local cache because the results to + be remembered depend on the permutation being applied. Since the + permutation is just an array, it cannot be stored in the global + cache. There are different procedured for BDDs and ADDs. This is + because bddPermuteRecur uses cuddBddIteRecur. If this were changed, + the procedures could be merged.] + + Author [Fabio Somenzi and Kavita Ravi] + + Copyright [Copyright (c) 1995-2012, 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: cuddCompose.c,v 1.46 2012/02/05 01:07:18 fabio Exp $"; +#endif + +#ifdef DD_DEBUG +static int addPermuteRecurHits; +static int bddPermuteRecurHits; +static int bddVectorComposeHits; +static int addVectorComposeHits; + +static int addGeneralVectorComposeHits; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * cuddAddPermuteRecur (DdManager *manager, DdHashTable *table, DdNode *node, int *permut); +static DdNode * cuddBddPermuteRecur (DdManager *manager, DdHashTable *table, DdNode *node, int *permut); +static DdNode * cuddBddVarMapRecur (DdManager *manager, DdNode *f); +static DdNode * cuddAddVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest); +static DdNode * cuddAddNonSimComposeRecur (DdManager *dd, DdNode *f, DdNode **vector, DdNode *key, DdNode *cube, int lastsub); +static DdNode * cuddBddVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest); +DD_INLINE static int ddIsIthAddVar (DdManager *dd, DdNode *f, unsigned int i); + +static DdNode * cuddAddGeneralVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vectorOn, DdNode **vectorOff, int deepest); +DD_INLINE static int ddIsIthAddVarPair (DdManager *dd, DdNode *f, DdNode *g, unsigned int i); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Substitutes g for x_v in the BDD for f.] + + Description [Substitutes g for x_v in the BDD for f. v is the index of the + variable to be substituted. Cudd_bddCompose passes the corresponding + projection function to the recursive procedure, so that the cache may + be used. Returns the composed BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addCompose] + +******************************************************************************/ +DdNode * +Cudd_bddCompose( + DdManager * dd, + DdNode * f, + DdNode * g, + int v) +{ + DdNode *proj, *res; + + /* Sanity check. */ + if (v < 0 || v >= dd->size) return(NULL); + + proj = dd->vars[v]; + do { + dd->reordered = 0; + res = cuddBddComposeRecur(dd,f,g,proj); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddCompose */ + + +/**Function******************************************************************** + + Synopsis [Substitutes g for x_v in the ADD for f.] + + Description [Substitutes g for x_v in the ADD for f. v is the index of the + variable to be substituted. g must be a 0-1 ADD. Cudd_bddCompose passes + the corresponding projection function to the recursive procedure, so + that the cache may be used. Returns the composed ADD if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddCompose] + +******************************************************************************/ +DdNode * +Cudd_addCompose( + DdManager * dd, + DdNode * f, + DdNode * g, + int v) +{ + DdNode *proj, *res; + + /* Sanity check. */ + if (v < 0 || v >= dd->size) return(NULL); + + proj = dd->vars[v]; + do { + dd->reordered = 0; + res = cuddAddComposeRecur(dd,f,g,proj); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_addCompose */ + + +/**Function******************************************************************** + + Synopsis [Permutes the variables of an ADD.] + + Description [Given a permutation in array permut, creates a new ADD + with permuted variables. There should be an entry in array permut + for each variable in the manager. The i-th entry of permut holds the + index of the variable that is to substitute the i-th + variable. Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute Cudd_addSwapVariables] + +******************************************************************************/ +DdNode * +Cudd_addPermute( + DdManager * manager, + DdNode * node, + int * permut) +{ + DdHashTable *table; + DdNode *res; + + do { + manager->reordered = 0; + table = cuddHashTableInit(manager,1,2); + if (table == NULL) return(NULL); + /* Recursively solve the problem. */ + res = cuddAddPermuteRecur(manager,table,node,permut); + if (res != NULL) cuddRef(res); + /* Dispose of local cache. */ + cuddHashTableQuit(table); + } while (manager->reordered == 1); + + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_addPermute */ + + +/**Function******************************************************************** + + Synopsis [Swaps two sets of variables of the same size (x and y) in + the ADD f.] + + Description [Swaps two sets of variables of the same size (x and y) in + the ADD f. The size is given by n. The two sets of variables are + assumed to be disjoint. Returns a pointer to the resulting ADD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addPermute Cudd_bddSwapVariables] + +******************************************************************************/ +DdNode * +Cudd_addSwapVariables( + DdManager * dd, + DdNode * f, + DdNode ** x, + DdNode ** y, + int n) +{ + DdNode *swapped; + int i, j, k; + int *permut; + + permut = ALLOC(int,dd->size); + if (permut == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < dd->size; i++) permut[i] = i; + for (i = 0; i < n; i++) { + j = x[i]->index; + k = y[i]->index; + permut[j] = k; + permut[k] = j; + } + + swapped = Cudd_addPermute(dd,f,permut); + FREE(permut); + + return(swapped); + +} /* end of Cudd_addSwapVariables */ + + +/**Function******************************************************************** + + Synopsis [Permutes the variables of a BDD.] + + Description [Given a permutation in array permut, creates a new BDD + with permuted variables. There should be an entry in array permut + for each variable in the manager. The i-th entry of permut holds the + index of the variable that is to substitute the i-th variable. + Returns a pointer to the resulting BDD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addPermute Cudd_bddSwapVariables] + +******************************************************************************/ +DdNode * +Cudd_bddPermute( + DdManager * manager, + DdNode * node, + int * permut) +{ + DdHashTable *table; + DdNode *res; + + do { + manager->reordered = 0; + table = cuddHashTableInit(manager,1,2); + if (table == NULL) return(NULL); + res = cuddBddPermuteRecur(manager,table,node,permut); + if (res != NULL) cuddRef(res); + /* Dispose of local cache. */ + cuddHashTableQuit(table); + + } while (manager->reordered == 1); + + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_bddPermute */ + + +/**Function******************************************************************** + + Synopsis [Remaps the variables of a BDD using the default variable map.] + + Description [Remaps the variables of a BDD using the default + variable map. A typical use of this function is to swap two sets of + variables. The variable map must be registered with Cudd_SetVarMap. + Returns a pointer to the resulting BDD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute Cudd_bddSwapVariables Cudd_SetVarMap] + +******************************************************************************/ +DdNode * +Cudd_bddVarMap( + DdManager * manager /* DD manager */, + DdNode * f /* function in which to remap variables */) +{ + DdNode *res; + + if (manager->map == NULL) return(NULL); + do { + manager->reordered = 0; + res = cuddBddVarMapRecur(manager, f); + } while (manager->reordered == 1); + + return(res); + +} /* end of Cudd_bddVarMap */ + + +/**Function******************************************************************** + + Synopsis [Registers a variable mapping with the manager.] + + Description [Registers with the manager a variable mapping described + by two sets of variables. This variable mapping is then used by + functions like Cudd_bddVarMap. This function is convenient for + those applications that perform the same mapping several times. + However, if several different permutations are used, it may be more + efficient not to rely on the registered mapping, because changing + mapping causes the cache to be cleared. (The initial setting, + however, does not clear the cache.) The two sets of variables (x and + y) must have the same size (x and y). The size is given by n. The + two sets of variables are normally disjoint, but this restriction is + not imposeded by the function. When new variables are created, the + map is automatically extended (each new variable maps to + itself). The typical use, however, is to wait until all variables + are created, and then create the map. Returns 1 if the mapping is + successfully registered with the manager; 0 otherwise.] + + SideEffects [Modifies the manager. May clear the cache.] + + SeeAlso [Cudd_bddVarMap Cudd_bddPermute Cudd_bddSwapVariables] + +******************************************************************************/ +int +Cudd_SetVarMap ( + DdManager *manager /* DD manager */, + DdNode **x /* first array of variables */, + DdNode **y /* second array of variables */, + int n /* length of both arrays */) +{ + int i; + + if (manager->map != NULL) { + cuddCacheFlush(manager); + } else { + manager->map = ALLOC(int,manager->maxSize); + if (manager->map == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return(0); + } + manager->memused += sizeof(int) * manager->maxSize; + } + /* Initialize the map to the identity. */ + for (i = 0; i < manager->size; i++) { + manager->map[i] = i; + } + /* Create the map. */ + for (i = 0; i < n; i++) { + manager->map[x[i]->index] = y[i]->index; + manager->map[y[i]->index] = x[i]->index; + } + return(1); + +} /* end of Cudd_SetVarMap */ + + +/**Function******************************************************************** + + Synopsis [Swaps two sets of variables of the same size (x and y) in + the BDD f.] + + Description [Swaps two sets of variables of the same size (x and y) + in the BDD f. The size is given by n. The two sets of variables are + assumed to be disjoint. Returns a pointer to the resulting BDD if + successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute Cudd_addSwapVariables] + +******************************************************************************/ +DdNode * +Cudd_bddSwapVariables( + DdManager * dd, + DdNode * f, + DdNode ** x, + DdNode ** y, + int n) +{ + DdNode *swapped; + int i, j, k; + int *permut; + + permut = ALLOC(int,dd->size); + if (permut == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < dd->size; i++) permut[i] = i; + for (i = 0; i < n; i++) { + j = x[i]->index; + k = y[i]->index; + permut[j] = k; + permut[k] = j; + } + + swapped = Cudd_bddPermute(dd,f,permut); + FREE(permut); + + return(swapped); + +} /* end of Cudd_bddSwapVariables */ + + +/**Function******************************************************************** + + Synopsis [Rearranges a set of variables in the BDD B.] + + Description [Rearranges a set of variables in the BDD B. The size of + the set is given by n. This procedure is intended for the + `randomization' of the priority functions. Returns a pointer to the + BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute Cudd_bddSwapVariables + Cudd_Dxygtdxz Cudd_Dxygtdyz Cudd_PrioritySelect] + +******************************************************************************/ +DdNode * +Cudd_bddAdjPermuteX( + DdManager * dd, + DdNode * B, + DdNode ** x, + int n) +{ + DdNode *swapped; + int i, j, k; + int *permut; + + permut = ALLOC(int,dd->size); + if (permut == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < dd->size; i++) permut[i] = i; + for (i = 0; i < n-2; i += 3) { + j = x[i]->index; + k = x[i+1]->index; + permut[j] = k; + permut[k] = j; + } + + swapped = Cudd_bddPermute(dd,B,permut); + FREE(permut); + + return(swapped); + +} /* end of Cudd_bddAdjPermuteX */ + + +/**Function******************************************************************** + + Synopsis [Composes an ADD with a vector of 0-1 ADDs.] + + Description [Given a vector of 0-1 ADDs, creates a new ADD by + substituting the 0-1 ADDs for the variables of the ADD f. There + should be an entry in vector for each variable in the manager. + If no substitution is sought for a given variable, the corresponding + projection function should be specified in the vector. + This function implements simultaneous composition. + Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addNonSimCompose Cudd_addPermute Cudd_addCompose + Cudd_bddVectorCompose] + +******************************************************************************/ +DdNode * +Cudd_addVectorCompose( + DdManager * dd, + DdNode * f, + DdNode ** vector) +{ + DdHashTable *table; + DdNode *res; + int deepest; + int i; + + do { + dd->reordered = 0; + /* Initialize local cache. */ + table = cuddHashTableInit(dd,1,2); + if (table == NULL) return(NULL); + + /* Find deepest real substitution. */ + for (deepest = dd->size - 1; deepest >= 0; deepest--) { + i = dd->invperm[deepest]; + if (!ddIsIthAddVar(dd,vector[i],i)) { + break; + } + } + + /* Recursively solve the problem. */ + res = cuddAddVectorComposeRecur(dd,table,f,vector,deepest); + if (res != NULL) cuddRef(res); + + /* Dispose of local cache. */ + cuddHashTableQuit(table); + } while (dd->reordered == 1); + + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_addVectorCompose */ + + +/**Function******************************************************************** + + Synopsis [Composes an ADD with a vector of ADDs.] + + Description [Given a vector of ADDs, creates a new ADD by substituting the + ADDs for the variables of the ADD f. vectorOn contains ADDs to be substituted + for the x_v and vectorOff the ADDs to be substituted for x_v'. There should + be an entry in vector for each variable in the manager. If no substitution + is sought for a given variable, the corresponding projection function should + be specified in the vector. This function implements simultaneous + composition. Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addVectorCompose Cudd_addNonSimCompose Cudd_addPermute + Cudd_addCompose Cudd_bddVectorCompose] + +******************************************************************************/ +DdNode * +Cudd_addGeneralVectorCompose( + DdManager * dd, + DdNode * f, + DdNode ** vectorOn, + DdNode ** vectorOff) +{ + DdHashTable *table; + DdNode *res; + int deepest; + int i; + + do { + dd->reordered = 0; + /* Initialize local cache. */ + table = cuddHashTableInit(dd,1,2); + if (table == NULL) return(NULL); + + /* Find deepest real substitution. */ + for (deepest = dd->size - 1; deepest >= 0; deepest--) { + i = dd->invperm[deepest]; + if (!ddIsIthAddVarPair(dd,vectorOn[i],vectorOff[i],i)) { + break; + } + } + + /* Recursively solve the problem. */ + res = cuddAddGeneralVectorComposeRecur(dd,table,f,vectorOn, + vectorOff,deepest); + if (res != NULL) cuddRef(res); + + /* Dispose of local cache. */ + cuddHashTableQuit(table); + } while (dd->reordered == 1); + + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_addGeneralVectorCompose */ + + +/**Function******************************************************************** + + Synopsis [Composes an ADD with a vector of 0-1 ADDs.] + + Description [Given a vector of 0-1 ADDs, creates a new ADD by + substituting the 0-1 ADDs for the variables of the ADD f. There + should be an entry in vector for each variable in the manager. + This function implements non-simultaneous composition. If any of the + functions being composed depends on any of the variables being + substituted, then the result depends on the order of composition, + which in turn depends on the variable order: The variables farther from + the roots in the order are substituted first. + Returns a pointer to the resulting ADD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addVectorCompose Cudd_addPermute Cudd_addCompose] + +******************************************************************************/ +DdNode * +Cudd_addNonSimCompose( + DdManager * dd, + DdNode * f, + DdNode ** vector) +{ + DdNode *cube, *key, *var, *tmp, *piece; + DdNode *res; + int i, lastsub; + + /* The cache entry for this function is composed of three parts: + ** f itself, the replacement relation, and the cube of the + ** variables being substituted. + ** The replacement relation is the product of the terms (yi EXNOR gi). + ** This apporach allows us to use the global cache for this function, + ** with great savings in memory with respect to using arrays for the + ** cache entries. + ** First we build replacement relation and cube of substituted + ** variables from the vector specifying the desired composition. + */ + key = DD_ONE(dd); + cuddRef(key); + cube = DD_ONE(dd); + cuddRef(cube); + for (i = (int) dd->size - 1; i >= 0; i--) { + if (ddIsIthAddVar(dd,vector[i],(unsigned int)i)) { + continue; + } + var = Cudd_addIthVar(dd,i); + if (var == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(var); + /* Update cube. */ + tmp = Cudd_addApply(dd,Cudd_addTimes,var,cube); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,cube); + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,cube); + cube = tmp; + /* Update replacement relation. */ + piece = Cudd_addApply(dd,Cudd_addXnor,var,vector[i]); + if (piece == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(piece); + Cudd_RecursiveDeref(dd,var); + tmp = Cudd_addApply(dd,Cudd_addTimes,key,piece); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,piece); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,piece); + key = tmp; + } + + /* Now try composition, until no reordering occurs. */ + do { + /* Find real substitution with largest index. */ + for (lastsub = dd->size - 1; lastsub >= 0; lastsub--) { + if (!ddIsIthAddVar(dd,vector[lastsub],(unsigned int)lastsub)) { + break; + } + } + + /* Recursively solve the problem. */ + dd->reordered = 0; + res = cuddAddNonSimComposeRecur(dd,f,vector,key,cube,lastsub+1); + if (res != NULL) cuddRef(res); + + } while (dd->reordered == 1); + + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,cube); + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_addNonSimCompose */ + + +/**Function******************************************************************** + + Synopsis [Composes a BDD with a vector of BDDs.] + + Description [Given a vector of BDDs, creates a new BDD by + substituting the BDDs for the variables of the BDD f. There + should be an entry in vector for each variable in the manager. + If no substitution is sought for a given variable, the corresponding + projection function should be specified in the vector. + This function implements simultaneous composition. + Returns a pointer to the resulting BDD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute Cudd_bddCompose Cudd_addVectorCompose] + +******************************************************************************/ +DdNode * +Cudd_bddVectorCompose( + DdManager * dd, + DdNode * f, + DdNode ** vector) +{ + DdHashTable *table; + DdNode *res; + int deepest; + int i; + + do { + dd->reordered = 0; + /* Initialize local cache. */ + table = cuddHashTableInit(dd,1,2); + if (table == NULL) return(NULL); + + /* Find deepest real substitution. */ + for (deepest = dd->size - 1; deepest >= 0; deepest--) { + i = dd->invperm[deepest]; + if (vector[i] != dd->vars[i]) { + break; + } + } + + /* Recursively solve the problem. */ + res = cuddBddVectorComposeRecur(dd,table,f,vector, deepest); + if (res != NULL) cuddRef(res); + + /* Dispose of local cache. */ + cuddHashTableQuit(table); + } while (dd->reordered == 1); + + if (res != NULL) cuddDeref(res); + return(res); + +} /* end of Cudd_bddVectorCompose */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddCompose.] + + Description [Performs the recursive step of Cudd_bddCompose. + Exploits the fact that the composition of f' with g + produces the complement of the composition of f with g to better + utilize the cache. Returns the composed BDD if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddCompose] + +******************************************************************************/ +DdNode * +cuddBddComposeRecur( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * proj) +{ + DdNode *F, *G, *f1, *f0, *g1, *g0, *r, *t, *e; + unsigned int v, topf, topg, topindex; + int comple; + + statLine(dd); + v = dd->perm[proj->index]; + F = Cudd_Regular(f); + topf = cuddI(dd,F->index); + + /* Terminal case. Subsumes the test for constant f. */ + if (topf > v) return(f); + + /* We solve the problem for a regular pointer, and then complement + ** the result if the pointer was originally complemented. + */ + comple = Cudd_IsComplement(f); + + /* Check cache. */ + r = cuddCacheLookup(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj); + if (r != NULL) { + return(Cudd_NotCond(r,comple)); + } + + if (topf == v) { + /* Compose. */ + f1 = cuddT(F); + f0 = cuddE(F); + r = cuddBddIteRecur(dd, g, f1, f0); + if (r == NULL) return(NULL); + } else { + /* Compute cofactors of f and g. Remember the index of the top + ** variable. + */ + G = Cudd_Regular(g); + topg = cuddI(dd,G->index); + if (topf > topg) { + topindex = G->index; + f1 = f0 = F; + } else { + topindex = F->index; + f1 = cuddT(F); + f0 = cuddE(F); + } + if (topg > topf) { + g1 = g0 = g; + } else { + g1 = cuddT(G); + g0 = cuddE(G); + if (g != G) { + g1 = Cudd_Not(g1); + g0 = Cudd_Not(g0); + } + } + /* Recursive step. */ + t = cuddBddComposeRecur(dd, f1, g1, proj); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddBddComposeRecur(dd, f0, g0, proj); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + cuddRef(e); + + r = cuddBddIteRecur(dd, dd->vars[topindex], t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, t); + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + cuddRef(r); + Cudd_IterDerefBdd(dd, t); /* t & e not necessarily part of r */ + Cudd_IterDerefBdd(dd, e); + cuddDeref(r); + } + + cuddCacheInsert(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj,r); + + return(Cudd_NotCond(r,comple)); + +} /* end of cuddBddComposeRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addCompose.] + + Description [Performs the recursive step of Cudd_addCompose. + Returns the composed BDD if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_addCompose] + +******************************************************************************/ +DdNode * +cuddAddComposeRecur( + DdManager * dd, + DdNode * f, + DdNode * g, + DdNode * proj) +{ + DdNode *f1, *f0, *g1, *g0, *r, *t, *e; + unsigned int v, topf, topg, topindex; + + statLine(dd); + v = dd->perm[proj->index]; + topf = cuddI(dd,f->index); + + /* Terminal case. Subsumes the test for constant f. */ + if (topf > v) return(f); + + /* Check cache. */ + r = cuddCacheLookup(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj); + if (r != NULL) { + return(r); + } + + if (topf == v) { + /* Compose. */ + f1 = cuddT(f); + f0 = cuddE(f); + r = cuddAddIteRecur(dd, g, f1, f0); + if (r == NULL) return(NULL); + } else { + /* Compute cofactors of f and g. Remember the index of the top + ** variable. + */ + topg = cuddI(dd,g->index); + if (topf > topg) { + topindex = g->index; + f1 = f0 = f; + } else { + topindex = f->index; + f1 = cuddT(f); + f0 = cuddE(f); + } + if (topg > topf) { + g1 = g0 = g; + } else { + g1 = cuddT(g); + g0 = cuddE(g); + } + /* Recursive step. */ + t = cuddAddComposeRecur(dd, f1, g1, proj); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddAddComposeRecur(dd, f0, g0, proj); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + r = cuddUniqueInter(dd, (int) topindex, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); + } + + cuddCacheInsert(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj,r); + + return(r); + +} /* end of cuddAddComposeRecur */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_addPermute.] + + Description [ Recursively puts the ADD in the order given in the + array permut. Checks for trivial cases to terminate recursion, then + splits on the children of this node. Once the solutions for the + children are obtained, it puts into the current position the node + from the rest of the ADD that should be here. Then returns this ADD. + The key here is that the node being visited is NOT put in its proper + place by this instance, but rather is switched when its proper + position is reached in the recursion tree.

+ The DdNode * that is returned is the same ADD as passed in as node, + but in the new order.] + + SideEffects [None] + + SeeAlso [Cudd_addPermute cuddBddPermuteRecur] + +******************************************************************************/ +static DdNode * +cuddAddPermuteRecur( + DdManager * manager /* DD manager */, + DdHashTable * table /* computed table */, + DdNode * node /* ADD to be reordered */, + int * permut /* permutation array */) +{ + DdNode *T,*E; + DdNode *res,*var; + int index; + + statLine(manager); + /* Check for terminal case of constant node. */ + if (cuddIsConstant(node)) { + return(node); + } + + /* If problem already solved, look up answer and return. */ + if (node->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) { +#ifdef DD_DEBUG + addPermuteRecurHits++; +#endif + return(res); + } + + /* Split and recur on children of this node. */ + T = cuddAddPermuteRecur(manager,table,cuddT(node),permut); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddAddPermuteRecur(manager,table,cuddE(node),permut); + if (E == NULL) { + Cudd_RecursiveDeref(manager, T); + return(NULL); + } + cuddRef(E); + + /* Move variable that should be in this position to this position + ** by creating a single var ADD for that variable, and calling + ** cuddAddIteRecur with the T and E we just created. + */ + index = permut[node->index]; + var = cuddUniqueInter(manager,index,DD_ONE(manager),DD_ZERO(manager)); + if (var == NULL) return(NULL); + cuddRef(var); + res = cuddAddIteRecur(manager,var,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(manager,var); + Cudd_RecursiveDeref(manager, T); + Cudd_RecursiveDeref(manager, E); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,var); + Cudd_RecursiveDeref(manager, T); + Cudd_RecursiveDeref(manager, E); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again. + */ + if (node->ref != 1) { + ptrint fanout = (ptrint) node->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,node,res,fanout)) { + Cudd_RecursiveDeref(manager, res); + return(NULL); + } + } + cuddDeref(res); + return(res); + +} /* end of cuddAddPermuteRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddPermute.] + + Description [ Recursively puts the BDD in the order given in the array permut. + Checks for trivial cases to terminate recursion, then splits on the + children of this node. Once the solutions for the children are + obtained, it puts into the current position the node from the rest of + the BDD that should be here. Then returns this BDD. + The key here is that the node being visited is NOT put in its proper + place by this instance, but rather is switched when its proper position + is reached in the recursion tree.

+ The DdNode * that is returned is the same BDD as passed in as node, + but in the new order.] + + SideEffects [None] + + SeeAlso [Cudd_bddPermute cuddAddPermuteRecur] + +******************************************************************************/ +static DdNode * +cuddBddPermuteRecur( + DdManager * manager /* DD manager */, + DdHashTable * table /* computed table */, + DdNode * node /* BDD to be reordered */, + int * permut /* permutation array */) +{ + DdNode *N,*T,*E; + DdNode *res; + int index; + + statLine(manager); + N = Cudd_Regular(node); + + /* Check for terminal case of constant node. */ + if (cuddIsConstant(N)) { + return(node); + } + + /* If problem already solved, look up answer and return. */ + if (N->ref != 1 && (res = cuddHashTableLookup1(table,N)) != NULL) { +#ifdef DD_DEBUG + bddPermuteRecurHits++; +#endif + return(Cudd_NotCond(res,N != node)); + } + + /* Split and recur on children of this node. */ + T = cuddBddPermuteRecur(manager,table,cuddT(N),permut); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddBddPermuteRecur(manager,table,cuddE(N),permut); + if (E == NULL) { + Cudd_IterDerefBdd(manager, T); + return(NULL); + } + cuddRef(E); + + /* Move variable that should be in this position to this position + ** by retrieving the single var BDD for that variable, and calling + ** cuddBddIteRecur with the T and E we just created. + */ + index = permut[N->index]; + res = cuddBddIteRecur(manager,manager->vars[index],T,E); + if (res == NULL) { + Cudd_IterDerefBdd(manager, T); + Cudd_IterDerefBdd(manager, E); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(manager, T); + Cudd_IterDerefBdd(manager, E); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again. + */ + if (N->ref != 1) { + ptrint fanout = (ptrint) N->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,N,res,fanout)) { + Cudd_IterDerefBdd(manager, res); + return(NULL); + } + } + cuddDeref(res); + return(Cudd_NotCond(res,N != node)); + +} /* end of cuddBddPermuteRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_bddVarMap.] + + Description [Implements the recursive step of Cudd_bddVarMap. + Returns a pointer to the result if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddVarMap] + +******************************************************************************/ +static DdNode * +cuddBddVarMapRecur( + DdManager *manager /* DD manager */, + DdNode *f /* BDD to be remapped */) +{ + DdNode *F, *T, *E; + DdNode *res; + int index; + + statLine(manager); + F = Cudd_Regular(f); + + /* Check for terminal case of constant node. */ + if (cuddIsConstant(F)) { + return(f); + } + + /* If problem already solved, look up answer and return. */ + if (F->ref != 1 && + (res = cuddCacheLookup1(manager,Cudd_bddVarMap,F)) != NULL) { + return(Cudd_NotCond(res,F != f)); + } + + /* Split and recur on children of this node. */ + T = cuddBddVarMapRecur(manager,cuddT(F)); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddBddVarMapRecur(manager,cuddE(F)); + if (E == NULL) { + Cudd_IterDerefBdd(manager, T); + return(NULL); + } + cuddRef(E); + + /* Move variable that should be in this position to this position + ** by retrieving the single var BDD for that variable, and calling + ** cuddBddIteRecur with the T and E we just created. + */ + index = manager->map[F->index]; + res = cuddBddIteRecur(manager,manager->vars[index],T,E); + if (res == NULL) { + Cudd_IterDerefBdd(manager, T); + Cudd_IterDerefBdd(manager, E); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(manager, T); + Cudd_IterDerefBdd(manager, E); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again. + */ + if (F->ref != 1) { + cuddCacheInsert1(manager,Cudd_bddVarMap,F,res); + } + cuddDeref(res); + return(Cudd_NotCond(res,F != f)); + +} /* end of cuddBddVarMapRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addVectorCompose.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +cuddAddVectorComposeRecur( + DdManager * dd /* DD manager */, + DdHashTable * table /* computed table */, + DdNode * f /* ADD in which to compose */, + DdNode ** vector /* functions to substitute */, + int deepest /* depth of deepest substitution */) +{ + DdNode *T,*E; + DdNode *res; + + statLine(dd); + /* If we are past the deepest substitution, return f. */ + if (cuddI(dd,f->index) > deepest) { + return(f); + } + + if ((res = cuddHashTableLookup1(table,f)) != NULL) { +#ifdef DD_DEBUG + addVectorComposeHits++; +#endif + return(res); + } + + /* Split and recur on children of this node. */ + T = cuddAddVectorComposeRecur(dd,table,cuddT(f),vector,deepest); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddAddVectorComposeRecur(dd,table,cuddE(f),vector,deepest); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + + /* Retrieve the 0-1 ADD for the current top variable and call + ** cuddAddIteRecur with the T and E we just created. + */ + res = cuddAddIteRecur(dd,vector[f->index],T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again + */ + if (f->ref != 1) { + ptrint fanout = (ptrint) f->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,f,res,fanout)) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + } + cuddDeref(res); + return(res); + +} /* end of cuddAddVectorComposeRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addGeneralVectorCompose.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +cuddAddGeneralVectorComposeRecur( + DdManager * dd /* DD manager */, + DdHashTable * table /* computed table */, + DdNode * f /* ADD in which to compose */, + DdNode ** vectorOn /* functions to substitute for x_i */, + DdNode ** vectorOff /* functions to substitute for x_i' */, + int deepest /* depth of deepest substitution */) +{ + DdNode *T,*E,*t,*e; + DdNode *res; + + /* If we are past the deepest substitution, return f. */ + if (cuddI(dd,f->index) > deepest) { + return(f); + } + + if ((res = cuddHashTableLookup1(table,f)) != NULL) { +#ifdef DD_DEBUG + addGeneralVectorComposeHits++; +#endif + return(res); + } + + /* Split and recur on children of this node. */ + T = cuddAddGeneralVectorComposeRecur(dd,table,cuddT(f), + vectorOn,vectorOff,deepest); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddAddGeneralVectorComposeRecur(dd,table,cuddE(f), + vectorOn,vectorOff,deepest); + if (E == NULL) { + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + cuddRef(E); + + /* Retrieve the compose ADDs for the current top variable and call + ** cuddAddApplyRecur with the T and E we just created. + */ + t = cuddAddApplyRecur(dd,Cudd_addTimes,vectorOn[f->index],T); + if (t == NULL) { + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + return(NULL); + } + cuddRef(t); + e = cuddAddApplyRecur(dd,Cudd_addTimes,vectorOff[f->index],E); + if (e == NULL) { + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + Cudd_RecursiveDeref(dd,t); + return(NULL); + } + cuddRef(e); + res = cuddAddApplyRecur(dd,Cudd_addPlus,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + Cudd_RecursiveDeref(dd,t); + Cudd_RecursiveDeref(dd,e); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + Cudd_RecursiveDeref(dd,t); + Cudd_RecursiveDeref(dd,e); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again + */ + if (f->ref != 1) { + ptrint fanout = (ptrint) f->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,f,res,fanout)) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + } + cuddDeref(res); + return(res); + +} /* end of cuddAddGeneralVectorComposeRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_addNonSimCompose.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +cuddAddNonSimComposeRecur( + DdManager * dd, + DdNode * f, + DdNode ** vector, + DdNode * key, + DdNode * cube, + int lastsub) +{ + DdNode *f1, *f0, *key1, *key0, *cube1, *var; + DdNode *T,*E; + DdNode *r; + unsigned int top, topf, topk, topc; + unsigned int index; + int i; + DdNode **vect1; + DdNode **vect0; + + statLine(dd); + /* If we are past the deepest substitution, return f. */ + if (cube == DD_ONE(dd) || cuddIsConstant(f)) { + return(f); + } + + /* If problem already solved, look up answer and return. */ + r = cuddCacheLookup(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube); + if (r != NULL) { + return(r); + } + + /* Find top variable. we just need to look at f, key, and cube, + ** because all the varibles in the gi are in key. + */ + topf = cuddI(dd,f->index); + topk = cuddI(dd,key->index); + top = ddMin(topf,topk); + topc = cuddI(dd,cube->index); + top = ddMin(top,topc); + index = dd->invperm[top]; + + /* Compute the cofactors. */ + if (topf == top) { + f1 = cuddT(f); + f0 = cuddE(f); + } else { + f1 = f0 = f; + } + if (topc == top) { + cube1 = cuddT(cube); + /* We want to eliminate vector[index] from key. Otherwise + ** cache performance is severely affected. Hence we + ** existentially quantify the variable with index "index" from key. + */ + var = Cudd_addIthVar(dd, (int) index); + if (var == NULL) { + return(NULL); + } + cuddRef(var); + key1 = cuddAddExistAbstractRecur(dd, key, var); + if (key1 == NULL) { + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(key1); + Cudd_RecursiveDeref(dd,var); + key0 = key1; + } else { + cube1 = cube; + if (topk == top) { + key1 = cuddT(key); + key0 = cuddE(key); + } else { + key1 = key0 = key; + } + cuddRef(key1); + } + + /* Allocate two new vectors for the cofactors of vector. */ + vect1 = ALLOC(DdNode *,lastsub); + if (vect1 == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd,key1); + return(NULL); + } + vect0 = ALLOC(DdNode *,lastsub); + if (vect0 == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd,key1); + FREE(vect1); + return(NULL); + } + + /* Cofactor the gi. Eliminate vect1[index] and vect0[index], because + ** we do not need them. + */ + for (i = 0; i < lastsub; i++) { + DdNode *gi = vector[i]; + if (gi == NULL) { + vect1[i] = vect0[i] = NULL; + } else if (gi->index == index) { + vect1[i] = cuddT(gi); + vect0[i] = cuddE(gi); + } else { + vect1[i] = vect0[i] = gi; + } + } + vect1[index] = vect0[index] = NULL; + + /* Recur on children. */ + T = cuddAddNonSimComposeRecur(dd,f1,vect1,key1,cube1,lastsub); + FREE(vect1); + if (T == NULL) { + Cudd_RecursiveDeref(dd,key1); + FREE(vect0); + return(NULL); + } + cuddRef(T); + E = cuddAddNonSimComposeRecur(dd,f0,vect0,key0,cube1,lastsub); + FREE(vect0); + if (E == NULL) { + Cudd_RecursiveDeref(dd,key1); + Cudd_RecursiveDeref(dd,T); + return(NULL); + } + cuddRef(E); + Cudd_RecursiveDeref(dd,key1); + + /* Retrieve the 0-1 ADD for the current top variable from vector, + ** and call cuddAddIteRecur with the T and E we just created. + */ + r = cuddAddIteRecur(dd,vector[index],T,E); + if (r == NULL) { + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + return(NULL); + } + cuddRef(r); + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + cuddDeref(r); + + /* Store answer to trim recursion. */ + cuddCacheInsert(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube,r); + + return(r); + +} /* end of cuddAddNonSimComposeRecur */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Cudd_bddVectorCompose.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdNode * +cuddBddVectorComposeRecur( + DdManager * dd /* DD manager */, + DdHashTable * table /* computed table */, + DdNode * f /* BDD in which to compose */, + DdNode ** vector /* functions to be composed */, + int deepest /* depth of the deepest substitution */) +{ + DdNode *F,*T,*E; + DdNode *res; + + statLine(dd); + F = Cudd_Regular(f); + + /* If we are past the deepest substitution, return f. */ + if (cuddI(dd,F->index) > deepest) { + return(f); + } + + /* If problem already solved, look up answer and return. */ + if ((res = cuddHashTableLookup1(table,F)) != NULL) { +#ifdef DD_DEBUG + bddVectorComposeHits++; +#endif + return(Cudd_NotCond(res,F != f)); + } + + /* Split and recur on children of this node. */ + T = cuddBddVectorComposeRecur(dd,table,cuddT(F),vector, deepest); + if (T == NULL) return(NULL); + cuddRef(T); + E = cuddBddVectorComposeRecur(dd,table,cuddE(F),vector, deepest); + if (E == NULL) { + Cudd_IterDerefBdd(dd, T); + return(NULL); + } + cuddRef(E); + + /* Call cuddBddIteRecur with the BDD that replaces the current top + ** variable and the T and E we just created. + */ + res = cuddBddIteRecur(dd,vector[F->index],T,E); + if (res == NULL) { + Cudd_IterDerefBdd(dd, T); + Cudd_IterDerefBdd(dd, E); + return(NULL); + } + cuddRef(res); + Cudd_IterDerefBdd(dd, T); + Cudd_IterDerefBdd(dd, E); + + /* Do not keep the result if the reference count is only 1, since + ** it will not be visited again. + */ + if (F->ref != 1) { + ptrint fanout = (ptrint) F->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,F,res,fanout)) { + Cudd_IterDerefBdd(dd, res); + return(NULL); + } + } + cuddDeref(res); + return(Cudd_NotCond(res,F != f)); + +} /* end of cuddBddVectorComposeRecur */ + + +/**Function******************************************************************** + + Synopsis [Comparison of a function to the i-th ADD variable.] + + Description [Comparison of a function to the i-th ADD variable. Returns 1 if + the function is the i-th ADD variable; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DD_INLINE +static int +ddIsIthAddVar( + DdManager * dd, + DdNode * f, + unsigned int i) +{ + return(f->index == i && cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd)); + +} /* end of ddIsIthAddVar */ + + +/**Function******************************************************************** + + Synopsis [Comparison of a pair of functions to the i-th ADD variable.] + + Description [Comparison of a pair of functions to the i-th ADD + variable. Returns 1 if the functions are the i-th ADD variable and its + complement; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DD_INLINE +static int +ddIsIthAddVarPair( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int i) +{ + return(f->index == i && g->index == i && + cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd) && + cuddT(g) == DD_ZERO(dd) && cuddE(g) == DD_ONE(dd)); + +} /* end of ddIsIthAddVarPair */ diff --git a/cudd_local/cudd/cuddDecomp.c b/cudd_local/cudd/cuddDecomp.c new file mode 100644 index 0000000..066027d --- /dev/null +++ b/cudd_local/cudd/cuddDecomp.c @@ -0,0 +1,2177 @@ +/**CFile*********************************************************************** + + FileName [cuddDecomp.c] + + PackageName [cudd] + + Synopsis [Functions for BDD decomposition.] + + Description [External procedures included in this file: +

    +
  • Cudd_bddApproxConjDecomp() +
  • Cudd_bddApproxDisjDecomp() +
  • Cudd_bddIterConjDecomp() +
  • Cudd_bddIterDisjDecomp() +
  • Cudd_bddGenConjDecomp() +
  • Cudd_bddGenDisjDecomp() +
  • Cudd_bddVarConjDecomp() +
  • Cudd_bddVarDisjDecomp() +
+ Static procedures included in this module: +
    +
  • cuddConjunctsAux() +
  • CreateBotDist() +
  • BuildConjuncts() +
  • ConjunctsFree() +
] + + Author [Kavita Ravi, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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 */ +/*---------------------------------------------------------------------------*/ +#define DEPTH 5 +#define THRESHOLD 10 +#define NONE 0 +#define PAIR_ST 1 +#define PAIR_CR 2 +#define G_ST 3 +#define G_CR 4 +#define H_ST 5 +#define H_CR 6 +#define BOTH_G 7 +#define BOTH_H 8 + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ +typedef struct Conjuncts { + DdNode *g; + DdNode *h; +} Conjuncts; + +typedef struct NodeStat { + int distance; + int localRef; +} NodeStat; + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddDecomp.c,v 1.45 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static DdNode *one, *zero; +long lastTimeG; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +#define FactorsNotStored(factors) ((int)((long)(factors) & 01)) + +#define FactorsComplement(factors) ((Conjuncts *)((long)(factors) | 01)) + +#define FactorsUncomplement(factors) ((Conjuncts *)((long)(factors) ^ 01)) + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static NodeStat * CreateBotDist (DdNode * node, st_table * distanceTable); +static double CountMinterms (DdNode * node, double max, st_table * mintermTable, FILE *fp); +static void ConjunctsFree (DdManager * dd, Conjuncts * factors); +static int PairInTables (DdNode * g, DdNode * h, st_table * ghTable); +static Conjuncts * CheckTablesCacheAndReturn (DdNode * node, DdNode * g, DdNode * h, st_table * ghTable, st_table * cacheTable); +static Conjuncts * PickOnePair (DdNode * node, DdNode * g1, DdNode * h1, DdNode * g2, DdNode * h2, st_table * ghTable, st_table * cacheTable); +static Conjuncts * CheckInTables (DdNode * node, DdNode * g1, DdNode * h1, DdNode * g2, DdNode * h2, st_table * ghTable, st_table * cacheTable, int * outOfMem); +static Conjuncts * ZeroCase (DdManager * dd, DdNode * node, Conjuncts * factorsNv, st_table * ghTable, st_table * cacheTable, int switched); +static Conjuncts * BuildConjuncts (DdManager * dd, DdNode * node, st_table * distanceTable, st_table * cacheTable, int approxDistance, int maxLocalRef, st_table * ghTable, st_table * mintermTable); +static int cuddConjunctsAux (DdManager * dd, DdNode * f, DdNode ** c1, DdNode ** c2); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Performs two-way conjunctive decomposition of a BDD.] + + Description [Performs two-way conjunctive decomposition of a + BDD. This procedure owes its name to the use of supersetting to + obtain an initial factor of the given function. Returns the number + of conjuncts produced, that is, 2 if successful; 1 if no meaningful + decomposition was found; 0 otherwise. The conjuncts produced by this + procedure tend to be imbalanced.] + + SideEffects [The factors are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the conjuncts are already + referenced. If the function returns 0, the array for the conjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddApproxDisjDecomp Cudd_bddIterConjDecomp + Cudd_bddGenConjDecomp Cudd_bddVarConjDecomp Cudd_RemapOverApprox + Cudd_bddSqueeze Cudd_bddLICompaction] + +******************************************************************************/ +int +Cudd_bddApproxConjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** conjuncts /* address of the first factor */) +{ + DdNode *superset1, *superset2, *glocal, *hlocal; + int nvars = Cudd_SupportSize(dd,f); + + /* Find a tentative first factor by overapproximation and minimization. */ + superset1 = Cudd_RemapOverApprox(dd,f,nvars,0,1.0); + if (superset1 == NULL) return(0); + cuddRef(superset1); + superset2 = Cudd_bddSqueeze(dd,f,superset1); + if (superset2 == NULL) { + Cudd_RecursiveDeref(dd,superset1); + return(0); + } + cuddRef(superset2); + Cudd_RecursiveDeref(dd,superset1); + + /* Compute the second factor by minimization. */ + hlocal = Cudd_bddLICompaction(dd,f,superset2); + if (hlocal == NULL) { + Cudd_RecursiveDeref(dd,superset2); + return(0); + } + cuddRef(hlocal); + + /* Refine the first factor by minimization. If h turns out to be f, this + ** step guarantees that g will be 1. */ + glocal = Cudd_bddLICompaction(dd,superset2,hlocal); + if (glocal == NULL) { + Cudd_RecursiveDeref(dd,superset2); + Cudd_RecursiveDeref(dd,hlocal); + return(0); + } + cuddRef(glocal); + Cudd_RecursiveDeref(dd,superset2); + + if (glocal != DD_ONE(dd)) { + if (hlocal != DD_ONE(dd)) { + *conjuncts = ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + (*conjuncts)[1] = hlocal; + return(2); + } else { + Cudd_RecursiveDeref(dd,hlocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + return(1); + } + } else { + Cudd_RecursiveDeref(dd,glocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = hlocal; + return(1); + } + +} /* end of Cudd_bddApproxConjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way disjunctive decomposition of a BDD.] + + Description [Performs two-way disjunctive decomposition of a BDD. + Returns the number of disjuncts produced, that is, 2 if successful; + 1 if no meaningful decomposition was found; 0 otherwise. The + disjuncts produced by this procedure tend to be imbalanced.] + + SideEffects [The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already + referenced. If the function returns 0, the array for the disjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddApproxConjDecomp Cudd_bddIterDisjDecomp + Cudd_bddGenDisjDecomp Cudd_bddVarDisjDecomp] + +******************************************************************************/ +int +Cudd_bddApproxDisjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** disjuncts /* address of the array of the disjuncts */) +{ + int result, i; + + result = Cudd_bddApproxConjDecomp(dd,Cudd_Not(f),disjuncts); + for (i = 0; i < result; i++) { + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + } + return(result); + +} /* end of Cudd_bddApproxDisjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way conjunctive decomposition of a BDD.] + + Description [Performs two-way conjunctive decomposition of a + BDD. This procedure owes its name to the iterated use of + supersetting to obtain a factor of the given function. Returns the + number of conjuncts produced, that is, 2 if successful; 1 if no + meaningful decomposition was found; 0 otherwise. The conjuncts + produced by this procedure tend to be imbalanced.] + + SideEffects [The factors are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the conjuncts are already + referenced. If the function returns 0, the array for the conjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddIterDisjDecomp Cudd_bddApproxConjDecomp + Cudd_bddGenConjDecomp Cudd_bddVarConjDecomp Cudd_RemapOverApprox + Cudd_bddSqueeze Cudd_bddLICompaction] + +******************************************************************************/ +int +Cudd_bddIterConjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** conjuncts /* address of the array of conjuncts */) +{ + DdNode *superset1, *superset2, *old[2], *res[2]; + int sizeOld, sizeNew; + int nvars = Cudd_SupportSize(dd,f); + + old[0] = DD_ONE(dd); + cuddRef(old[0]); + old[1] = f; + cuddRef(old[1]); + sizeOld = Cudd_SharingSize(old,2); + + do { + /* Find a tentative first factor by overapproximation and + ** minimization. */ + superset1 = Cudd_RemapOverApprox(dd,old[1],nvars,0,1.0); + if (superset1 == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(superset1); + superset2 = Cudd_bddSqueeze(dd,old[1],superset1); + if (superset2 == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + Cudd_RecursiveDeref(dd,superset1); + return(0); + } + cuddRef(superset2); + Cudd_RecursiveDeref(dd,superset1); + res[0] = Cudd_bddAnd(dd,old[0],superset2); + if (res[0] == NULL) { + Cudd_RecursiveDeref(dd,superset2); + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(res[0]); + Cudd_RecursiveDeref(dd,superset2); + if (res[0] == old[0]) { + Cudd_RecursiveDeref(dd,res[0]); + break; /* avoid infinite loop */ + } + + /* Compute the second factor by minimization. */ + res[1] = Cudd_bddLICompaction(dd,old[1],res[0]); + if (res[1] == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(res[1]); + + sizeNew = Cudd_SharingSize(res,2); + if (sizeNew <= sizeOld) { + Cudd_RecursiveDeref(dd,old[0]); + old[0] = res[0]; + Cudd_RecursiveDeref(dd,old[1]); + old[1] = res[1]; + sizeOld = sizeNew; + } else { + Cudd_RecursiveDeref(dd,res[0]); + Cudd_RecursiveDeref(dd,res[1]); + break; + } + + } while (1); + + /* Refine the first factor by minimization. If h turns out to + ** be f, this step guarantees that g will be 1. */ + superset1 = Cudd_bddLICompaction(dd,old[0],old[1]); + if (superset1 == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(superset1); + Cudd_RecursiveDeref(dd,old[0]); + old[0] = superset1; + + if (old[0] != DD_ONE(dd)) { + if (old[1] != DD_ONE(dd)) { + *conjuncts = ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = old[0]; + (*conjuncts)[1] = old[1]; + return(2); + } else { + Cudd_RecursiveDeref(dd,old[1]); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = old[0]; + return(1); + } + } else { + Cudd_RecursiveDeref(dd,old[0]); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,old[1]); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = old[1]; + return(1); + } + +} /* end of Cudd_bddIterConjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way disjunctive decomposition of a BDD.] + + Description [Performs two-way disjunctive decomposition of a BDD. + Returns the number of disjuncts produced, that is, 2 if successful; + 1 if no meaningful decomposition was found; 0 otherwise. The + disjuncts produced by this procedure tend to be imbalanced.] + + SideEffects [The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already + referenced. If the function returns 0, the array for the disjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddIterConjDecomp Cudd_bddApproxDisjDecomp + Cudd_bddGenDisjDecomp Cudd_bddVarDisjDecomp] + +******************************************************************************/ +int +Cudd_bddIterDisjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** disjuncts /* address of the array of the disjuncts */) +{ + int result, i; + + result = Cudd_bddIterConjDecomp(dd,Cudd_Not(f),disjuncts); + for (i = 0; i < result; i++) { + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + } + return(result); + +} /* end of Cudd_bddIterDisjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way conjunctive decomposition of a BDD.] + + Description [Performs two-way conjunctive decomposition of a + BDD. This procedure owes its name to the fact tht it generalizes the + decomposition based on the cofactors with respect to one + variable. Returns the number of conjuncts produced, that is, 2 if + successful; 1 if no meaningful decomposition was found; 0 + otherwise. The conjuncts produced by this procedure tend to be + balanced.] + + SideEffects [The two factors are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the conjuncts are already + referenced. If the function returns 0, the array for the conjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddGenDisjDecomp Cudd_bddApproxConjDecomp + Cudd_bddIterConjDecomp Cudd_bddVarConjDecomp] + +******************************************************************************/ +int +Cudd_bddGenConjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** conjuncts /* address of the array of conjuncts */) +{ + int result; + DdNode *glocal, *hlocal; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + do { + dd->reordered = 0; + result = cuddConjunctsAux(dd, f, &glocal, &hlocal); + } while (dd->reordered == 1); + + if (result == 0) { + return(0); + } + + if (glocal != one) { + if (hlocal != one) { + *conjuncts = ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + (*conjuncts)[1] = hlocal; + return(2); + } else { + Cudd_RecursiveDeref(dd,hlocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + return(1); + } + } else { + Cudd_RecursiveDeref(dd,glocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = hlocal; + return(1); + } + +} /* end of Cudd_bddGenConjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way disjunctive decomposition of a BDD.] + + Description [Performs two-way disjunctive decomposition of a BDD. + Returns the number of disjuncts produced, that is, 2 if successful; + 1 if no meaningful decomposition was found; 0 otherwise. The + disjuncts produced by this procedure tend to be balanced.] + + SideEffects [The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already + referenced. If the function returns 0, the array for the disjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddGenConjDecomp Cudd_bddApproxDisjDecomp + Cudd_bddIterDisjDecomp Cudd_bddVarDisjDecomp] + +******************************************************************************/ +int +Cudd_bddGenDisjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** disjuncts /* address of the array of the disjuncts */) +{ + int result, i; + + result = Cudd_bddGenConjDecomp(dd,Cudd_Not(f),disjuncts); + for (i = 0; i < result; i++) { + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + } + return(result); + +} /* end of Cudd_bddGenDisjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way conjunctive decomposition of a BDD.] + + Description [Conjunctively decomposes one BDD according to a + variable. If f is the function of the BDD and + x is the variable, the decomposition is + (f+x)(f+x'). The variable is chosen so as to balance + the sizes of the two conjuncts and to keep them small. Returns the + number of conjuncts produced, that is, 2 if successful; 1 if no + meaningful decomposition was found; 0 otherwise.] + + SideEffects [The two factors are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the conjuncts are already + referenced. If the function returns 0, the array for the conjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddVarDisjDecomp Cudd_bddGenConjDecomp + Cudd_bddApproxConjDecomp Cudd_bddIterConjDecomp] + +*****************************************************************************/ +int +Cudd_bddVarConjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** conjuncts /* address of the array of conjuncts */) +{ + int best; + int min; + DdNode *support, *scan, *var, *glocal, *hlocal; + + /* Find best cofactoring variable. */ + support = Cudd_Support(dd,f); + if (support == NULL) return(0); + if (Cudd_IsConstant(support)) { + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = f; + cuddRef((*conjuncts)[0]); + return(1); + } + cuddRef(support); + min = 1000000000; + best = -1; + scan = support; + while (!Cudd_IsConstant(scan)) { + int i = scan->index; + int est1 = Cudd_EstimateCofactor(dd,f,i,1); + int est0 = Cudd_EstimateCofactor(dd,f,i,0); + /* Minimize the size of the larger of the two cofactors. */ + int est = (est1 > est0) ? est1 : est0; + if (est < min) { + min = est; + best = i; + } + scan = cuddT(scan); + } +#ifdef DD_DEBUG + assert(best >= 0 && best < dd->size); +#endif + Cudd_RecursiveDeref(dd,support); + + var = Cudd_bddIthVar(dd,best); + glocal = Cudd_bddOr(dd,f,var); + if (glocal == NULL) { + return(0); + } + cuddRef(glocal); + hlocal = Cudd_bddOr(dd,f,Cudd_Not(var)); + if (hlocal == NULL) { + Cudd_RecursiveDeref(dd,glocal); + return(0); + } + cuddRef(hlocal); + + if (glocal != DD_ONE(dd)) { + if (hlocal != DD_ONE(dd)) { + *conjuncts = ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + (*conjuncts)[1] = hlocal; + return(2); + } else { + Cudd_RecursiveDeref(dd,hlocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + return(1); + } + } else { + Cudd_RecursiveDeref(dd,glocal); + *conjuncts = ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = hlocal; + return(1); + } + +} /* end of Cudd_bddVarConjDecomp */ + + +/**Function******************************************************************** + + Synopsis [Performs two-way disjunctive decomposition of a BDD.] + + Description [Performs two-way disjunctive decomposition of a BDD + according to a variable. If f is the function of the + BDD and x is the variable, the decomposition is + f*x + f*x'. The variable is chosen so as to balance + the sizes of the two disjuncts and to keep them small. Returns the + number of disjuncts produced, that is, 2 if successful; 1 if no + meaningful decomposition was found; 0 otherwise.] + + SideEffects [The two disjuncts are returned in an array as side effects. + The array is allocated by this function. It is the caller's responsibility + to free it. On successful completion, the disjuncts are already + referenced. If the function returns 0, the array for the disjuncts is + not allocated. If the function returns 1, the only factor equals the + function to be decomposed.] + + SeeAlso [Cudd_bddVarConjDecomp Cudd_bddApproxDisjDecomp + Cudd_bddIterDisjDecomp Cudd_bddGenDisjDecomp] + +******************************************************************************/ +int +Cudd_bddVarDisjDecomp( + DdManager * dd /* manager */, + DdNode * f /* function to be decomposed */, + DdNode *** disjuncts /* address of the array of the disjuncts */) +{ + int result, i; + + result = Cudd_bddVarConjDecomp(dd,Cudd_Not(f),disjuncts); + for (i = 0; i < result; i++) { + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + } + return(result); + +} /* end of Cudd_bddVarDisjDecomp */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Get longest distance of node from constant.] + + Description [Get longest distance of node from constant. Returns the + distance of the root from the constant if successful; CUDD_OUT_OF_MEM + otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static NodeStat * +CreateBotDist( + DdNode * node, + st_table * distanceTable) +{ + DdNode *N, *Nv, *Nnv; + int distance, distanceNv, distanceNnv; + NodeStat *nodeStat, *nodeStatNv, *nodeStatNnv; + +#if 0 + if (Cudd_IsConstant(node)) { + return(0); + } +#endif + + /* Return the entry in the table if found. */ + N = Cudd_Regular(node); + if (st_lookup(distanceTable, N, &nodeStat)) { + nodeStat->localRef++; + return(nodeStat); + } + + Nv = cuddT(N); + Nnv = cuddE(N); + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + /* Recur on the children. */ + nodeStatNv = CreateBotDist(Nv, distanceTable); + if (nodeStatNv == NULL) return(NULL); + distanceNv = nodeStatNv->distance; + + nodeStatNnv = CreateBotDist(Nnv, distanceTable); + if (nodeStatNnv == NULL) return(NULL); + distanceNnv = nodeStatNnv->distance; + /* Store max distance from constant; note sometimes this distance + ** may be to 0. + */ + distance = (distanceNv > distanceNnv) ? (distanceNv+1) : (distanceNnv + 1); + + nodeStat = ALLOC(NodeStat, 1); + if (nodeStat == NULL) { + return(0); + } + nodeStat->distance = distance; + nodeStat->localRef = 1; + + if (st_insert(distanceTable, (char *)N, (char *)nodeStat) == + ST_OUT_OF_MEM) { + return(0); + + } + return(nodeStat); + +} /* end of CreateBotDist */ + + +/**Function******************************************************************** + + Synopsis [Count the number of minterms of each node ina a BDD and + store it in a hash table.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static double +CountMinterms( + DdNode * node, + double max, + st_table * mintermTable, + FILE *fp) +{ + DdNode *N, *Nv, *Nnv; + double min, minNv, minNnv; + double *dummy; + + N = Cudd_Regular(node); + + if (cuddIsConstant(N)) { + if (node == zero) { + return(0); + } else { + return(max); + } + } + + /* Return the entry in the table if found. */ + if (st_lookup(mintermTable, node, &dummy)) { + min = *dummy; + return(min); + } + + Nv = cuddT(N); + Nnv = cuddE(N); + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + /* Recur on the children. */ + minNv = CountMinterms(Nv, max, mintermTable, fp); + if (minNv == -1.0) return(-1.0); + minNnv = CountMinterms(Nnv, max, mintermTable, fp); + if (minNnv == -1.0) return(-1.0); + min = minNv / 2.0 + minNnv / 2.0; + /* store + */ + + dummy = ALLOC(double, 1); + if (dummy == NULL) return(-1.0); + *dummy = min; + if (st_insert(mintermTable, (char *)node, (char *)dummy) == ST_OUT_OF_MEM) { + (void) fprintf(fp, "st table insert failed\n"); + } + return(min); + +} /* end of CountMinterms */ + + +/**Function******************************************************************** + + Synopsis [Free factors structure] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static void +ConjunctsFree( + DdManager * dd, + Conjuncts * factors) +{ + Cudd_RecursiveDeref(dd, factors->g); + Cudd_RecursiveDeref(dd, factors->h); + FREE(factors); + return; + +} /* end of ConjunctsFree */ + + +/**Function******************************************************************** + + Synopsis [Check whether the given pair is in the tables.] + + Description [.Check whether the given pair is in the tables. gTable + and hTable are combined. + absence in both is indicated by 0, + presence in gTable is indicated by 1, + presence in hTable by 2 and + presence in both by 3. + The values returned by this function are PAIR_ST, + PAIR_CR, G_ST, G_CR, H_ST, H_CR, BOTH_G, BOTH_H, NONE. + PAIR_ST implies g in gTable and h in hTable + PAIR_CR implies g in hTable and h in gTable + G_ST implies g in gTable and h not in any table + G_CR implies g in hTable and h not in any table + H_ST implies h in hTable and g not in any table + H_CR implies h in gTable and g not in any table + BOTH_G implies both in gTable + BOTH_H implies both in hTable + NONE implies none in table; ] + + SideEffects [] + + SeeAlso [CheckTablesCacheAndReturn CheckInTables] + +******************************************************************************/ +static int +PairInTables( + DdNode * g, + DdNode * h, + st_table * ghTable) +{ + int valueG, valueH, gPresent, hPresent; + + valueG = valueH = gPresent = hPresent = 0; + + gPresent = st_lookup_int(ghTable, (char *)Cudd_Regular(g), &valueG); + hPresent = st_lookup_int(ghTable, (char *)Cudd_Regular(h), &valueH); + + if (!gPresent && !hPresent) return(NONE); + + if (!hPresent) { + if (valueG & 1) return(G_ST); + if (valueG & 2) return(G_CR); + } + if (!gPresent) { + if (valueH & 1) return(H_CR); + if (valueH & 2) return(H_ST); + } + /* both in tables */ + if ((valueG & 1) && (valueH & 2)) return(PAIR_ST); + if ((valueG & 2) && (valueH & 1)) return(PAIR_CR); + + if (valueG & 1) { + return(BOTH_G); + } else { + return(BOTH_H); + } + +} /* end of PairInTables */ + + +/**Function******************************************************************** + + Synopsis [Check the tables for the existence of pair and return one + combination, cache the result.] + + Description [Check the tables for the existence of pair and return + one combination, cache the result. The assumption is that one of the + conjuncts is already in the tables.] + + SideEffects [g and h referenced for the cache] + + SeeAlso [ZeroCase] + +******************************************************************************/ +static Conjuncts * +CheckTablesCacheAndReturn( + DdNode * node, + DdNode * g, + DdNode * h, + st_table * ghTable, + st_table * cacheTable) +{ + int pairValue; + int value; + Conjuncts *factors; + + value = 0; + /* check tables */ + pairValue = PairInTables(g, h, ghTable); + assert(pairValue != NONE); + /* if both dont exist in table, we know one exists(either g or h). + * Therefore store the other and proceed + */ + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) return(NULL); + if ((pairValue == BOTH_H) || (pairValue == H_ST)) { + if (g != one) { + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(g), &value)) { + value |= 1; + } else { + value = 1; + } + if (st_insert(ghTable, (char *)Cudd_Regular(g), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } + } + factors->g = g; + factors->h = h; + } else if ((pairValue == BOTH_G) || (pairValue == G_ST)) { + if (h != one) { + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(h), &value)) { + value |= 2; + } else { + value = 2; + } + if (st_insert(ghTable, (char *)Cudd_Regular(h), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } + } + factors->g = g; + factors->h = h; + } else if (pairValue == H_CR) { + if (g != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(g), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } + } + factors->g = h; + factors->h = g; + } else if (pairValue == G_CR) { + if (h != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(h), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } + } + factors->g = h; + factors->h = g; + } else if (pairValue == PAIR_CR) { + /* pair exists in table */ + factors->g = h; + factors->h = g; + } else if (pairValue == PAIR_ST) { + factors->g = g; + factors->h = h; + } + + /* cache the result for this node */ + if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + + return(factors); + +} /* end of CheckTablesCacheAndReturn */ + +/**Function******************************************************************** + + Synopsis [Check the tables for the existence of pair and return one + combination, store in cache.] + + Description [Check the tables for the existence of pair and return + one combination, store in cache. The pair that has more pointers to + it is picked. An approximation of the number of local pointers is + made by taking the reference count of the pairs sent. ] + + SideEffects [] + + SeeAlso [ZeroCase BuildConjuncts] + +******************************************************************************/ +static Conjuncts * +PickOnePair( + DdNode * node, + DdNode * g1, + DdNode * h1, + DdNode * g2, + DdNode * h2, + st_table * ghTable, + st_table * cacheTable) +{ + int value; + Conjuncts *factors; + int oneRef, twoRef; + + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) return(NULL); + + /* count the number of pointers to pair 2 */ + if (h2 == one) { + twoRef = (Cudd_Regular(g2))->ref; + } else if (g2 == one) { + twoRef = (Cudd_Regular(h2))->ref; + } else { + twoRef = ((Cudd_Regular(g2))->ref + (Cudd_Regular(h2))->ref)/2; + } + + /* count the number of pointers to pair 1 */ + if (h1 == one) { + oneRef = (Cudd_Regular(g1))->ref; + } else if (g1 == one) { + oneRef = (Cudd_Regular(h1))->ref; + } else { + oneRef = ((Cudd_Regular(g1))->ref + (Cudd_Regular(h1))->ref)/2; + } + + /* pick the pair with higher reference count */ + if (oneRef >= twoRef) { + factors->g = g1; + factors->h = h1; + } else { + factors->g = g2; + factors->h = h2; + } + + /* + * Store computed factors in respective tables to encourage + * recombination. + */ + if (factors->g != one) { + /* insert g in htable */ + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(factors->g), &value)) { + if (value == 2) { + value |= 1; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->g), + (char *)(long)value) == ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + } + } else { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->g), + (char *)(long)value) == ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + } + } + + if (factors->h != one) { + /* insert h in htable */ + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(factors->h), &value)) { + if (value == 1) { + value |= 2; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->h), + (char *)(long)value) == ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + } + } else { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->h), + (char *)(long)value) == ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + } + } + + /* Store factors in cache table for later use. */ + if (st_insert(cacheTable, (char *)node, (char *)factors) == + ST_OUT_OF_MEM) { + FREE(factors); + return(NULL); + } + + return(factors); + +} /* end of PickOnePair */ + + +/**Function******************************************************************** + + Synopsis [Check if the two pairs exist in the table, If any of the + conjuncts do exist, store in the cache and return the corresponding pair.] + + Description [Check if the two pairs exist in the table. If any of + the conjuncts do exist, store in the cache and return the + corresponding pair.] + + SideEffects [] + + SeeAlso [ZeroCase BuildConjuncts] + +******************************************************************************/ +static Conjuncts * +CheckInTables( + DdNode * node, + DdNode * g1, + DdNode * h1, + DdNode * g2, + DdNode * h2, + st_table * ghTable, + st_table * cacheTable, + int * outOfMem) +{ + int pairValue1, pairValue2; + Conjuncts *factors; + int value; + + *outOfMem = 0; + + /* check existence of pair in table */ + pairValue1 = PairInTables(g1, h1, ghTable); + pairValue2 = PairInTables(g2, h2, ghTable); + + /* if none of the 4 exist in the gh tables, return NULL */ + if ((pairValue1 == NONE) && (pairValue2 == NONE)) { + return NULL; + } + + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) { + *outOfMem = 1; + return NULL; + } + + /* pairs that already exist in the table get preference. */ + if (pairValue1 == PAIR_ST) { + factors->g = g1; + factors->h = h1; + } else if (pairValue2 == PAIR_ST) { + factors->g = g2; + factors->h = h2; + } else if (pairValue1 == PAIR_CR) { + factors->g = h1; + factors->h = g1; + } else if (pairValue2 == PAIR_CR) { + factors->g = h2; + factors->h = g2; + } else if (pairValue1 == G_ST) { + /* g exists in the table, h is not found in either table */ + factors->g = g1; + factors->h = h1; + if (h1 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(h1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue1 == BOTH_G) { + /* g and h are found in the g table */ + factors->g = g1; + factors->h = h1; + if (h1 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(h1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue1 == H_ST) { + /* h exists in the table, g is not found in either table */ + factors->g = g1; + factors->h = h1; + if (g1 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(g1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue1 == BOTH_H) { + /* g and h are found in the h table */ + factors->g = g1; + factors->h = h1; + if (g1 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(g1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == G_ST) { + /* g exists in the table, h is not found in either table */ + factors->g = g2; + factors->h = h2; + if (h2 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(h2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == BOTH_G) { + /* g and h are found in the g table */ + factors->g = g2; + factors->h = h2; + if (h2 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(h2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == H_ST) { + /* h exists in the table, g is not found in either table */ + factors->g = g2; + factors->h = h2; + if (g2 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(g2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == BOTH_H) { + /* g and h are found in the h table */ + factors->g = g2; + factors->h = h2; + if (g2 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(g2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue1 == G_CR) { + /* g found in h table and h in none */ + factors->g = h1; + factors->h = g1; + if (h1 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(h1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue1 == H_CR) { + /* h found in g table and g in none */ + factors->g = h1; + factors->h = g1; + if (g1 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(g1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == G_CR) { + /* g found in h table and h in none */ + factors->g = h2; + factors->h = g2; + if (h2 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(h2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } else if (pairValue2 == H_CR) { + /* h found in g table and g in none */ + factors->g = h2; + factors->h = g2; + if (g2 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(g2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + } + } + + /* Store factors in cache table for later use. */ + if (st_insert(cacheTable, (char *)node, (char *)factors) == + ST_OUT_OF_MEM) { + *outOfMem = 1; + FREE(factors); + return(NULL); + } + return factors; +} /* end of CheckInTables */ + + + +/**Function******************************************************************** + + Synopsis [If one child is zero, do explicitly what Restrict does or better] + + Description [If one child is zero, do explicitly what Restrict does or better. + First separate a variable and its child in the base case. In case of a cube + times a function, separate the cube and function. As a last resort, look in + tables.] + + SideEffects [Frees the BDDs in factorsNv. factorsNv itself is not freed + because it is freed above.] + + SeeAlso [BuildConjuncts] + +******************************************************************************/ +static Conjuncts * +ZeroCase( + DdManager * dd, + DdNode * node, + Conjuncts * factorsNv, + st_table * ghTable, + st_table * cacheTable, + int switched) +{ + int topid; + DdNode *g, *h, *g1, *g2, *h1, *h2, *x, *N, *G, *H, *Gv, *Gnv; + DdNode *Hv, *Hnv; + int value; + int outOfMem; + Conjuncts *factors; + + /* get var at this node */ + N = Cudd_Regular(node); + topid = N->index; + x = dd->vars[topid]; + x = (switched) ? Cudd_Not(x): x; + cuddRef(x); + + /* Seprate variable and child */ + if (factorsNv->g == one) { + Cudd_RecursiveDeref(dd, factorsNv->g); + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, x); + return(NULL); + } + factors->g = x; + factors->h = factorsNv->h; + /* cache the result*/ + if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, x); + FREE(factors); + return NULL; + } + + /* store x in g table, the other node is already in the table */ + if (st_lookup_int(ghTable, (char *)Cudd_Regular(x), &value)) { + value |= 1; + } else { + value = 1; + } + if (st_insert(ghTable, (char *)Cudd_Regular(x), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + return NULL; + } + return(factors); + } + + /* Seprate variable and child */ + if (factorsNv->h == one) { + Cudd_RecursiveDeref(dd, factorsNv->h); + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, x); + return(NULL); + } + factors->g = factorsNv->g; + factors->h = x; + /* cache the result. */ + if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, x); + FREE(factors); + return(NULL); + } + /* store x in h table, the other node is already in the table */ + if (st_lookup_int(ghTable, (char *)Cudd_Regular(x), &value)) { + value |= 2; + } else { + value = 2; + } + if (st_insert(ghTable, (char *)Cudd_Regular(x), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + return NULL; + } + return(factors); + } + + G = Cudd_Regular(factorsNv->g); + Gv = cuddT(G); + Gnv = cuddE(G); + Gv = Cudd_NotCond(Gv, Cudd_IsComplement(node)); + Gnv = Cudd_NotCond(Gnv, Cudd_IsComplement(node)); + /* if the child below is a variable */ + if ((Gv == zero) || (Gnv == zero)) { + h = factorsNv->h; + g = cuddBddAndRecur(dd, x, factorsNv->g); + if (g != NULL) cuddRef(g); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, x); + if (g == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->h); + return NULL; + } + /* CheckTablesCacheAndReturn responsible for allocating + * factors structure., g,h referenced for cache store the + */ + factors = CheckTablesCacheAndReturn(node, + g, + h, + ghTable, + cacheTable); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g); + Cudd_RecursiveDeref(dd, h); + } + return(factors); + } + + H = Cudd_Regular(factorsNv->h); + Hv = cuddT(H); + Hnv = cuddE(H); + Hv = Cudd_NotCond(Hv, Cudd_IsComplement(node)); + Hnv = Cudd_NotCond(Hnv, Cudd_IsComplement(node)); + /* if the child below is a variable */ + if ((Hv == zero) || (Hnv == zero)) { + g = factorsNv->g; + h = cuddBddAndRecur(dd, x, factorsNv->h); + if (h!= NULL) cuddRef(h); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, x); + if (h == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + return NULL; + } + /* CheckTablesCacheAndReturn responsible for allocating + * factors structure.g,h referenced for table store + */ + factors = CheckTablesCacheAndReturn(node, + g, + h, + ghTable, + cacheTable); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g); + Cudd_RecursiveDeref(dd, h); + } + return(factors); + } + + /* build g1 = x*g; h1 = h */ + /* build g2 = g; h2 = x*h */ + Cudd_RecursiveDeref(dd, x); + h1 = factorsNv->h; + g1 = cuddBddAndRecur(dd, x, factorsNv->g); + if (g1 != NULL) cuddRef(g1); + if (g1 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + return NULL; + } + + g2 = factorsNv->g; + h2 = cuddBddAndRecur(dd, x, factorsNv->h); + if (h2 != NULL) cuddRef(h2); + if (h2 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNv->g); + return NULL; + } + + /* check whether any pair is in tables */ + factors = CheckInTables(node, g1, h1, g2, h2, ghTable, cacheTable, &outOfMem); + if (outOfMem) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + return NULL; + } + if (factors != NULL) { + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } + return factors; + } + + /* check for each pair in tables and choose one */ + factors = PickOnePair(node,g1, h1, g2, h2, ghTable, cacheTable); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + /* now free what was created and not used */ + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } + } + + return(factors); +} /* end of ZeroCase */ + + +/**Function******************************************************************** + + Synopsis [Builds the conjuncts recursively, bottom up.] + + Description [Builds the conjuncts recursively, bottom up. Constants + are returned as (f, f). The cache is checked for previously computed + result. The decomposition points are determined by the local + reference count of this node and the longest distance from the + constant. At the decomposition point, the factors returned are (f, + 1). Recur on the two children. The order is determined by the + heavier branch. Combine the factors of the two children and pick the + one that already occurs in the gh table. Occurence in g is indicated + by value 1, occurence in h by 2, occurence in both 3.] + + SideEffects [] + + SeeAlso [cuddConjunctsAux] + +******************************************************************************/ +static Conjuncts * +BuildConjuncts( + DdManager * dd, + DdNode * node, + st_table * distanceTable, + st_table * cacheTable, + int approxDistance, + int maxLocalRef, + st_table * ghTable, + st_table * mintermTable) +{ + int topid, distance; + Conjuncts *factorsNv, *factorsNnv, *factors; + Conjuncts *dummy; + DdNode *N, *Nv, *Nnv, *temp, *g1, *g2, *h1, *h2, *topv; + double minNv = 0.0, minNnv = 0.0; + double *doubleDummy; + int switched =0; + int outOfMem; + int freeNv = 0, freeNnv = 0, freeTemp; + NodeStat *nodeStat; + int value; + + /* if f is constant, return (f,f) */ + if (Cudd_IsConstant(node)) { + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + factors->g = node; + factors->h = node; + return(FactorsComplement(factors)); + } + + /* If result (a pair of conjuncts) in cache, return the factors. */ + if (st_lookup(cacheTable, node, &dummy)) { + factors = dummy; + return(factors); + } + + /* check distance and local reference count of this node */ + N = Cudd_Regular(node); + if (!st_lookup(distanceTable, N, &nodeStat)) { + (void) fprintf(dd->err, "Not in table, Something wrong\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + distance = nodeStat->distance; + + /* at or below decomposition point, return (f, 1) */ + if (((nodeStat->localRef > maxLocalRef*2/3) && + (distance < approxDistance*2/3)) || + (distance <= approxDistance/4)) { + factors = ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + /* alternate assigning (f,1) */ + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(node), &value)) { + if (value == 3) { + if (!lastTimeG) { + factors->g = node; + factors->h = one; + lastTimeG = 1; + } else { + factors->g = one; + factors->h = node; + lastTimeG = 0; + } + } else if (value == 1) { + factors->g = node; + factors->h = one; + } else { + factors->g = one; + factors->h = node; + } + } else if (!lastTimeG) { + factors->g = node; + factors->h = one; + lastTimeG = 1; + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(node), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(factors); + return NULL; + } + } else { + factors->g = one; + factors->h = node; + lastTimeG = 0; + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(node), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + FREE(factors); + return NULL; + } + } + return(FactorsComplement(factors)); + } + + /* get the children and recur */ + Nv = cuddT(N); + Nnv = cuddE(N); + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + /* Choose which subproblem to solve first based on the number of + * minterms. We go first where there are more minterms. + */ + if (!Cudd_IsConstant(Nv)) { + if (!st_lookup(mintermTable, Nv, &doubleDummy)) { + (void) fprintf(dd->err, "Not in table: Something wrong\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + minNv = *doubleDummy; + } + + if (!Cudd_IsConstant(Nnv)) { + if (!st_lookup(mintermTable, Nnv, &doubleDummy)) { + (void) fprintf(dd->err, "Not in table: Something wrong\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + minNnv = *doubleDummy; + } + + if (minNv < minNnv) { + temp = Nv; + Nv = Nnv; + Nnv = temp; + switched = 1; + } + + /* build gt, ht recursively */ + if (Nv != zero) { + factorsNv = BuildConjuncts(dd, Nv, distanceTable, + cacheTable, approxDistance, maxLocalRef, + ghTable, mintermTable); + if (factorsNv == NULL) return(NULL); + freeNv = FactorsNotStored(factorsNv); + factorsNv = (freeNv) ? FactorsUncomplement(factorsNv) : factorsNv; + cuddRef(factorsNv->g); + cuddRef(factorsNv->h); + + /* Deal with the zero case */ + if (Nnv == zero) { + /* is responsible for freeing factorsNv */ + factors = ZeroCase(dd, node, factorsNv, ghTable, + cacheTable, switched); + if (freeNv) FREE(factorsNv); + return(factors); + } + } + + /* build ge, he recursively */ + if (Nnv != zero) { + factorsNnv = BuildConjuncts(dd, Nnv, distanceTable, + cacheTable, approxDistance, maxLocalRef, + ghTable, mintermTable); + if (factorsNnv == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + if (freeNv) FREE(factorsNv); + return(NULL); + } + freeNnv = FactorsNotStored(factorsNnv); + factorsNnv = (freeNnv) ? FactorsUncomplement(factorsNnv) : factorsNnv; + cuddRef(factorsNnv->g); + cuddRef(factorsNnv->h); + + /* Deal with the zero case */ + if (Nv == zero) { + /* is responsible for freeing factorsNv */ + factors = ZeroCase(dd, node, factorsNnv, ghTable, + cacheTable, switched); + if (freeNnv) FREE(factorsNnv); + return(factors); + } + } + + /* construct the 2 pairs */ + /* g1 = x*gt + x'*ge; h1 = x*ht + x'*he; */ + /* g2 = x*gt + x'*he; h2 = x*ht + x'*ge */ + if (switched) { + factors = factorsNnv; + factorsNnv = factorsNv; + factorsNv = factors; + freeTemp = freeNv; + freeNv = freeNnv; + freeNnv = freeTemp; + } + + /* Build the factors for this node. */ + topid = N->index; + topv = dd->vars[topid]; + + g1 = cuddBddIteRecur(dd, topv, factorsNv->g, factorsNnv->g); + if (g1 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + if (freeNv) FREE(factorsNv); + if (freeNnv) FREE(factorsNnv); + return(NULL); + } + + cuddRef(g1); + + h1 = cuddBddIteRecur(dd, topv, factorsNv->h, factorsNnv->h); + if (h1 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + Cudd_RecursiveDeref(dd, g1); + if (freeNv) FREE(factorsNv); + if (freeNnv) FREE(factorsNnv); + return(NULL); + } + + cuddRef(h1); + + g2 = cuddBddIteRecur(dd, topv, factorsNv->g, factorsNnv->h); + if (g2 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + if (freeNv) FREE(factorsNv); + if (freeNnv) FREE(factorsNnv); + return(NULL); + } + cuddRef(g2); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + + h2 = cuddBddIteRecur(dd, topv, factorsNv->h, factorsNnv->g); + if (h2 == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + if (freeNv) FREE(factorsNv); + if (freeNnv) FREE(factorsNnv); + return(NULL); + } + cuddRef(h2); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + if (freeNv) FREE(factorsNv); + if (freeNnv) FREE(factorsNnv); + + /* check for each pair in tables and choose one */ + factors = CheckInTables(node, g1, h1, g2, h2, ghTable, cacheTable, &outOfMem); + if (outOfMem) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + return(NULL); + } + if (factors != NULL) { + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } + return(factors); + } + + /* if not in tables, pick one pair */ + factors = PickOnePair(node,g1, h1, g2, h2, ghTable, cacheTable); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + /* now free what was created and not used */ + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } + } + + return(factors); + +} /* end of BuildConjuncts */ + + +/**Function******************************************************************** + + Synopsis [Procedure to compute two conjunctive factors of f and place in *c1 and *c2.] + + Description [Procedure to compute two conjunctive factors of f and + place in *c1 and *c2. Sets up the required data - table of distances + from the constant and local reference count. Also minterm table. ] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +static int +cuddConjunctsAux( + DdManager * dd, + DdNode * f, + DdNode ** c1, + DdNode ** c2) +{ + st_table *distanceTable = NULL; + st_table *cacheTable = NULL; + st_table *mintermTable = NULL; + st_table *ghTable = NULL; + st_generator *stGen; + char *key, *value; + Conjuncts *factors; + int distance, approxDistance; + double max, minterms; + int freeFactors; + NodeStat *nodeStat; + int maxLocalRef; + + /* initialize */ + *c1 = NULL; + *c2 = NULL; + + /* initialize distances table */ + distanceTable = st_init_table(st_ptrcmp,st_ptrhash); + if (distanceTable == NULL) goto outOfMem; + + /* make the entry for the constant */ + nodeStat = ALLOC(NodeStat, 1); + if (nodeStat == NULL) goto outOfMem; + nodeStat->distance = 0; + nodeStat->localRef = 1; + if (st_insert(distanceTable, (char *)one, (char *)nodeStat) == ST_OUT_OF_MEM) { + goto outOfMem; + } + + /* Count node distances from constant. */ + nodeStat = CreateBotDist(f, distanceTable); + if (nodeStat == NULL) goto outOfMem; + + /* set the distance for the decomposition points */ + approxDistance = (DEPTH < nodeStat->distance) ? nodeStat->distance : DEPTH; + distance = nodeStat->distance; + + if (distance < approxDistance) { + /* Too small to bother. */ + *c1 = f; + *c2 = DD_ONE(dd); + cuddRef(*c1); cuddRef(*c2); + stGen = st_init_gen(distanceTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(distanceTable); + return(1); + } + + /* record the maximum local reference count */ + maxLocalRef = 0; + stGen = st_init_gen(distanceTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + nodeStat = (NodeStat *)value; + maxLocalRef = (nodeStat->localRef > maxLocalRef) ? + nodeStat->localRef : maxLocalRef; + } + st_free_gen(stGen); stGen = NULL; + + + /* Count minterms for each node. */ + max = pow(2.0, (double)Cudd_SupportSize(dd,f)); /* potential overflow */ + mintermTable = st_init_table(st_ptrcmp,st_ptrhash); + if (mintermTable == NULL) goto outOfMem; + minterms = CountMinterms(f, max, mintermTable, dd->err); + if (minterms == -1.0) goto outOfMem; + + lastTimeG = Cudd_Random() & 1; + cacheTable = st_init_table(st_ptrcmp, st_ptrhash); + if (cacheTable == NULL) goto outOfMem; + ghTable = st_init_table(st_ptrcmp, st_ptrhash); + if (ghTable == NULL) goto outOfMem; + + /* Build conjuncts. */ + factors = BuildConjuncts(dd, f, distanceTable, cacheTable, + approxDistance, maxLocalRef, ghTable, mintermTable); + if (factors == NULL) goto outOfMem; + + /* free up tables */ + stGen = st_init_gen(distanceTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(distanceTable); distanceTable = NULL; + st_free_table(ghTable); ghTable = NULL; + + stGen = st_init_gen(mintermTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(mintermTable); mintermTable = NULL; + + freeFactors = FactorsNotStored(factors); + factors = (freeFactors) ? FactorsUncomplement(factors) : factors; + if (factors != NULL) { + *c1 = factors->g; + *c2 = factors->h; + cuddRef(*c1); + cuddRef(*c2); + if (freeFactors) FREE(factors); + +#if 0 + if ((*c1 == f) && (!Cudd_IsConstant(f))) { + assert(*c2 == one); + } + if ((*c2 == f) && (!Cudd_IsConstant(f))) { + assert(*c1 == one); + } + + if ((*c1 != one) && (!Cudd_IsConstant(f))) { + assert(!Cudd_bddLeq(dd, *c2, *c1)); + } + if ((*c2 != one) && (!Cudd_IsConstant(f))) { + assert(!Cudd_bddLeq(dd, *c1, *c2)); + } +#endif + } + + stGen = st_init_gen(cacheTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + ConjunctsFree(dd, (Conjuncts *)value); + } + st_free_gen(stGen); stGen = NULL; + + st_free_table(cacheTable); cacheTable = NULL; + + return(1); + +outOfMem: + if (distanceTable != NULL) { + stGen = st_init_gen(distanceTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(distanceTable); distanceTable = NULL; + } + if (mintermTable != NULL) { + stGen = st_init_gen(mintermTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(mintermTable); mintermTable = NULL; + } + if (ghTable != NULL) st_free_table(ghTable); + if (cacheTable != NULL) { + stGen = st_init_gen(cacheTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (char **)&key, (char **)&value)) { + ConjunctsFree(dd, (Conjuncts *)value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(cacheTable); cacheTable = NULL; + } + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + +} /* end of cuddConjunctsAux */ diff --git a/cudd_local/cudd/cuddEssent.c b/cudd_local/cudd/cuddEssent.c new file mode 100644 index 0000000..7af6df6 --- /dev/null +++ b/cudd_local/cudd/cuddEssent.c @@ -0,0 +1,1467 @@ +/**CFile*********************************************************************** + + FileName [cuddEssent.c] + + PackageName [cudd] + + Synopsis [Functions for the detection of essential variables.] + + Description [External procedures included in this file: +
    +
  • Cudd_FindEssential() +
  • Cudd_bddIsVarEssential() +
  • Cudd_FindTwoLiteralClauses() +
  • Cudd_ReadIthClause() +
  • Cudd_PrintTwoLiteralClauses() +
  • Cudd_tlcInfoFree() +
+ Static procedures included in this module: +
    +
  • ddFindEssentialRecur() +
  • ddFindTwoLiteralClausesRecur() +
  • computeClauses() +
  • computeClausesWithUniverse() +
  • emptyClauseSet() +
  • sentinelp() +
  • equalp() +
  • beforep() +
  • oneliteralp() +
  • impliedp() +
  • bitVectorAlloc() +
  • bitVectorClear() +
  • bitVectorFree() +
  • bitVectorRead() +
  • bitVectorSet() +
  • tlcInfoAlloc() +
] + + Author [Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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 */ +/*---------------------------------------------------------------------------*/ + +/* These definitions are for the bit vectors. */ +#if SIZEOF_LONG == 8 +#define BPL 64 +#define LOGBPL 6 +#else +#define BPL 32 +#define LOGBPL 5 +#endif + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/* This structure holds the set of clauses for a node. Each clause consists +** of two literals. For one-literal clauses, the second lietral is FALSE. +** Each literal is composed of a variable and a phase. A variable is a node +** index, and requires sizeof(DdHalfWord) bytes. The constant literals use +** CUDD_MAXINDEX as variable indicator. Each phase is a bit: 0 for positive +** phase, and 1 for negative phase. +** Variables and phases are stored separately for the sake of compactness. +** The variables are stored in an array of DdHalfWord's terminated by a +** sentinel (a pair of zeroes). The phases are stored in a bit vector. +** The cnt field holds, at the end, the number of clauses. +** The clauses of the set are kept sorted. For each clause, the first literal +** is the one of least index. So, the clause with literals +2 and -4 is stored +** as (+2,-4). A one-literal clause with literal +3 is stored as +** (+3,-CUDD_MAXINDEX). Clauses are sorted in decreasing order as follows: +** (+5,-7) +** (+5,+6) +** (-5,+7) +** (-4,FALSE) +** (-4,+8) +** ... +** That is, one first looks at the variable of the first literal, then at the +** phase of the first litral, then at the variable of the second literal, +** and finally at the phase of the second literal. +*/ +struct DdTlcInfo { + DdHalfWord *vars; + long *phases; + DdHalfWord cnt; +}; + +/* This structure is for temporary representation of sets of clauses. It is +** meant to be used in link lists, when the number of clauses is not yet +** known. The encoding of a clause is the same as in DdTlcInfo, though +** the phase information is not stored in a bit array. */ +struct TlClause { + DdHalfWord v1, v2; + short p1, p2; + struct TlClause *next; +}; + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +typedef long BitVector; +typedef struct TlClause TlClause; + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +#ifndef lint +static char rcsid[] DD_UNUSED = "$Id: cuddEssent.c,v 1.25 2012/02/05 01:07:18 fabio Exp $"; +#endif + +static BitVector *Tolv; +static BitVector *Tolp; +static BitVector *Eolv; +static BitVector *Eolp; + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static DdNode * ddFindEssentialRecur (DdManager *dd, DdNode *f); +static DdTlcInfo * ddFindTwoLiteralClausesRecur (DdManager * dd, DdNode * f, st_table *table); +static DdTlcInfo * computeClauses (DdTlcInfo *Tres, DdTlcInfo *Eres, DdHalfWord label, int size); +static DdTlcInfo * computeClausesWithUniverse (DdTlcInfo *Cres, DdHalfWord label, short phase); +static DdTlcInfo * emptyClauseSet (void); +static int sentinelp (DdHalfWord var1, DdHalfWord var2); +static int equalp (DdHalfWord var1a, short phase1a, DdHalfWord var1b, short phase1b, DdHalfWord var2a, short phase2a, DdHalfWord var2b, short phase2b); +static int beforep (DdHalfWord var1a, short phase1a, DdHalfWord var1b, short phase1b, DdHalfWord var2a, short phase2a, DdHalfWord var2b, short phase2b); +static int oneliteralp (DdHalfWord var); +static int impliedp (DdHalfWord var1, short phase1, DdHalfWord var2, short phase2, BitVector *olv, BitVector *olp); +static BitVector * bitVectorAlloc (int size); +DD_INLINE static void bitVectorClear (BitVector *vector, int size); +static void bitVectorFree (BitVector *vector); +DD_INLINE static short bitVectorRead (BitVector *vector, int i); +DD_INLINE static void bitVectorSet (BitVector * vector, int i, short val); +static DdTlcInfo * tlcInfoAlloc (void); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Finds the essential variables of a DD.] + + Description [Returns the cube of the essential variables. A positive + literal means that the variable must be set to 1 for the function to be + 1. A negative literal means that the variable must be set to 0 for the + function to be 1. Returns a pointer to the cube BDD if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddIsVarEssential] + +******************************************************************************/ +DdNode * +Cudd_FindEssential( + DdManager * dd, + DdNode * f) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = ddFindEssentialRecur(dd,f); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_FindEssential */ + + +/**Function******************************************************************** + + Synopsis [Determines whether a given variable is essential with a + given phase in a BDD.] + + Description [Determines whether a given variable is essential with a + given phase in a BDD. Uses Cudd_bddIteConstant. Returns 1 if phase == 1 + and f-->x_id, or if phase == 0 and f-->x_id'.] + + SideEffects [None] + + SeeAlso [Cudd_FindEssential] + +******************************************************************************/ +int +Cudd_bddIsVarEssential( + DdManager * manager, + DdNode * f, + int id, + int phase) +{ + DdNode *var; + int res; + + var = Cudd_bddIthVar(manager, id); + + var = Cudd_NotCond(var,phase == 0); + + res = Cudd_bddLeq(manager, f, var); + + return(res); + +} /* end of Cudd_bddIsVarEssential */ + + +/**Function******************************************************************** + + Synopsis [Finds the two literal clauses of a DD.] + + Description [Returns the one- and two-literal clauses of a DD. + Returns a pointer to the structure holding the clauses if + successful; NULL otherwise. For a constant DD, the empty set of clauses + is returned. This is obviously correct for a non-zero constant. For the + constant zero, it is based on the assumption that only those clauses + containing variables in the support of the function are considered. Since + the support of a constant function is empty, no clauses are returned.] + + SideEffects [None] + + SeeAlso [Cudd_FindEssential] + +******************************************************************************/ +DdTlcInfo * +Cudd_FindTwoLiteralClauses( + DdManager * dd, + DdNode * f) +{ + DdTlcInfo *res; + st_table *table; + st_generator *gen; + DdTlcInfo *tlc; + DdNode *node; + int size = dd->size; + + if (Cudd_IsConstant(f)) { + res = emptyClauseSet(); + return(res); + } + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) return(NULL); + Tolv = bitVectorAlloc(size); + if (Tolv == NULL) { + st_free_table(table); + return(NULL); + } + Tolp = bitVectorAlloc(size); + if (Tolp == NULL) { + st_free_table(table); + bitVectorFree(Tolv); + return(NULL); + } + Eolv = bitVectorAlloc(size); + if (Eolv == NULL) { + st_free_table(table); + bitVectorFree(Tolv); + bitVectorFree(Tolp); + return(NULL); + } + Eolp = bitVectorAlloc(size); + if (Eolp == NULL) { + st_free_table(table); + bitVectorFree(Tolv); + bitVectorFree(Tolp); + bitVectorFree(Eolv); + return(NULL); + } + + res = ddFindTwoLiteralClausesRecur(dd,f,table); + /* Dispose of table contents and free table. */ + st_foreach_item(table, gen, &node, &tlc) { + if (node != f) { + Cudd_tlcInfoFree(tlc); + } + } + st_free_table(table); + bitVectorFree(Tolv); + bitVectorFree(Tolp); + bitVectorFree(Eolv); + bitVectorFree(Eolp); + + if (res != NULL) { + int i; + for (i = 0; !sentinelp(res->vars[i], res->vars[i+1]); i += 2); + res->cnt = i >> 1; + } + + return(res); + +} /* end of Cudd_FindTwoLiteralClauses */ + + +/**Function******************************************************************** + + Synopsis [Accesses the i-th clause of a DD.] + + Description [Accesses the i-th clause of a DD given the clause set which + must be already computed. Returns 1 if successful; 0 if i is out of range, + or in case of error.] + + SideEffects [the four components of a clause are returned as side effects.] + + SeeAlso [Cudd_FindTwoLiteralClauses] + +******************************************************************************/ +int +Cudd_ReadIthClause( + DdTlcInfo * tlc, + int i, + DdHalfWord *var1, + DdHalfWord *var2, + int *phase1, + int *phase2) +{ + if (tlc == NULL) return(0); + if (tlc->vars == NULL || tlc->phases == NULL) return(0); + if (i < 0 || (unsigned) i >= tlc->cnt) return(0); + *var1 = tlc->vars[2*i]; + *var2 = tlc->vars[2*i+1]; + *phase1 = (int) bitVectorRead(tlc->phases, 2*i); + *phase2 = (int) bitVectorRead(tlc->phases, 2*i+1); + return(1); + +} /* end of Cudd_ReadIthClause */ + + +/**Function******************************************************************** + + Synopsis [Prints the two literal clauses of a DD.] + + Description [Prints the one- and two-literal clauses. Returns 1 if + successful; 0 otherwise. The argument "names" can be NULL, in which case + the variable indices are printed.] + + SideEffects [None] + + SeeAlso [Cudd_FindTwoLiteralClauses] + +******************************************************************************/ +int +Cudd_PrintTwoLiteralClauses( + DdManager * dd, + DdNode * f, + char **names, + FILE *fp) +{ + DdHalfWord *vars; + BitVector *phases; + int i; + DdTlcInfo *res = Cudd_FindTwoLiteralClauses(dd, f); + FILE *ifp = fp == NULL ? dd->out : fp; + + if (res == NULL) return(0); + vars = res->vars; + phases = res->phases; + for (i = 0; !sentinelp(vars[i], vars[i+1]); i += 2) { + if (names != NULL) { + if (vars[i+1] == CUDD_MAXINDEX) { + (void) fprintf(ifp, "%s%s\n", + bitVectorRead(phases, i) ? "~" : " ", + names[vars[i]]); + } else { + (void) fprintf(ifp, "%s%s | %s%s\n", + bitVectorRead(phases, i) ? "~" : " ", + names[vars[i]], + bitVectorRead(phases, i+1) ? "~" : " ", + names[vars[i+1]]); + } + } else { + if (vars[i+1] == CUDD_MAXINDEX) { + (void) fprintf(ifp, "%s%d\n", + bitVectorRead(phases, i) ? "~" : " ", + (int) vars[i]); + } else { + (void) fprintf(ifp, "%s%d | %s%d\n", + bitVectorRead(phases, i) ? "~" : " ", + (int) vars[i], + bitVectorRead(phases, i+1) ? "~" : " ", + (int) vars[i+1]); + } + } + } + Cudd_tlcInfoFree(res); + + return(1); + +} /* end of Cudd_PrintTwoLiteralClauses */ + + +/**Function******************************************************************** + + Synopsis [Frees a DdTlcInfo Structure.] + + Description [Frees a DdTlcInfo Structure as well as the memory pointed + by it.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_tlcInfoFree( + DdTlcInfo * t) +{ + if (t->vars != NULL) FREE(t->vars); + if (t->phases != NULL) FREE(t->phases); + FREE(t); + +} /* end of Cudd_tlcInfoFree */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_FindEssential.] + + Description [Implements the recursive step of Cudd_FindEssential. + Returns a pointer to the cube BDD if successful; NULL otherwise.] + + SideEffects [None] + +******************************************************************************/ +static DdNode * +ddFindEssentialRecur( + DdManager * dd, + DdNode * f) +{ + DdNode *T, *E, *F; + DdNode *essT, *essE, *res; + int index; + DdNode *one, *lzero, *azero; + + one = DD_ONE(dd); + F = Cudd_Regular(f); + /* If f is constant the set of essential variables is empty. */ + if (cuddIsConstant(F)) return(one); + + res = cuddCacheLookup1(dd,Cudd_FindEssential,f); + if (res != NULL) { + return(res); + } + + lzero = Cudd_Not(one); + azero = DD_ZERO(dd); + /* Find cofactors: here f is non-constant. */ + T = cuddT(F); + E = cuddE(F); + if (Cudd_IsComplement(f)) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + + index = F->index; + if (Cudd_IsConstant(T) && T != lzero && T != azero) { + /* if E is zero, index is essential, otherwise there are no + ** essentials, because index is not essential and no other variable + ** can be, since setting index = 1 makes the function constant and + ** different from 0. + */ + if (E == lzero || E == azero) { + res = dd->vars[index]; + } else { + res = one; + } + } else if (T == lzero || T == azero) { + if (Cudd_IsConstant(E)) { /* E cannot be zero here */ + res = Cudd_Not(dd->vars[index]); + } else { /* E == non-constant */ + /* find essentials in the else branch */ + essE = ddFindEssentialRecur(dd,E); + if (essE == NULL) { + return(NULL); + } + cuddRef(essE); + + /* add index to the set with negative phase */ + res = cuddUniqueInter(dd,index,one,Cudd_Not(essE)); + if (res == NULL) { + Cudd_RecursiveDeref(dd,essE); + return(NULL); + } + res = Cudd_Not(res); + cuddDeref(essE); + } + } else { /* T == non-const */ + if (E == lzero || E == azero) { + /* find essentials in the then branch */ + essT = ddFindEssentialRecur(dd,T); + if (essT == NULL) { + return(NULL); + } + cuddRef(essT); + + /* add index to the set with positive phase */ + /* use And because essT may be complemented */ + res = cuddBddAndRecur(dd,dd->vars[index],essT); + if (res == NULL) { + Cudd_RecursiveDeref(dd,essT); + return(NULL); + } + cuddDeref(essT); + } else if (!Cudd_IsConstant(E)) { + /* if E is a non-zero constant there are no essentials + ** because T is non-constant. + */ + essT = ddFindEssentialRecur(dd,T); + if (essT == NULL) { + return(NULL); + } + if (essT == one) { + res = one; + } else { + cuddRef(essT); + essE = ddFindEssentialRecur(dd,E); + if (essE == NULL) { + Cudd_RecursiveDeref(dd,essT); + return(NULL); + } + cuddRef(essE); + + /* res = intersection(essT, essE) */ + res = cuddBddLiteralSetIntersectionRecur(dd,essT,essE); + if (res == NULL) { + Cudd_RecursiveDeref(dd,essT); + Cudd_RecursiveDeref(dd,essE); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,essT); + Cudd_RecursiveDeref(dd,essE); + cuddDeref(res); + } + } else { /* E is a non-zero constant */ + res = one; + } + } + + cuddCacheInsert1(dd,Cudd_FindEssential, f, res); + return(res); + +} /* end of ddFindEssentialRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_FindTwoLiteralClauses.] + + Description [Implements the recursive step of + Cudd_FindTwoLiteralClauses. The DD node is assumed to be not + constant. Returns a pointer to a set of clauses if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_FindTwoLiteralClauses] + +******************************************************************************/ +static DdTlcInfo * +ddFindTwoLiteralClausesRecur( + DdManager * dd, + DdNode * f, + st_table *table) +{ + DdNode *T, *E, *F; + DdNode *one, *lzero, *azero; + DdTlcInfo *res, *Tres, *Eres; + DdHalfWord index; + + F = Cudd_Regular(f); + + assert(!cuddIsConstant(F)); + + /* Check computed table. Separate entries are necessary for + ** a node and its complement. We should update the counter here. */ + if (st_lookup(table, f, &res)) { + return(res); + } + + /* Easy access to the constants for BDDs and ADDs. */ + one = DD_ONE(dd); + lzero = Cudd_Not(one); + azero = DD_ZERO(dd); + + /* Find cofactors and variable labeling the top node. */ + T = cuddT(F); E = cuddE(F); + if (Cudd_IsComplement(f)) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + index = F->index; + + if (Cudd_IsConstant(T) && T != lzero && T != azero) { + /* T is a non-zero constant. If E is zero, then this node's index + ** is a one-literal clause. Otherwise, if E is a non-zero + ** constant, there are no clauses for this node. Finally, + ** if E is not constant, we recursively compute its clauses, and then + ** merge using the empty set for T. */ + if (E == lzero || E == azero) { + /* Create the clause (index + 0). */ + res = tlcInfoAlloc(); + if (res == NULL) return(NULL); + res->vars = ALLOC(DdHalfWord,4); + if (res->vars == NULL) { + FREE(res); + return(NULL); + } + res->phases = bitVectorAlloc(2); + if (res->phases == NULL) { + FREE(res->vars); + FREE(res); + return(NULL); + } + res->vars[0] = index; + res->vars[1] = CUDD_MAXINDEX; + res->vars[2] = 0; + res->vars[3] = 0; + bitVectorSet(res->phases, 0, 0); /* positive phase */ + bitVectorSet(res->phases, 1, 1); /* negative phase */ + } else if (Cudd_IsConstant(E)) { + /* If E is a non-zero constant, no clauses. */ + res = emptyClauseSet(); + } else { + /* E is non-constant */ + Tres = emptyClauseSet(); + if (Tres == NULL) return(NULL); + Eres = ddFindTwoLiteralClausesRecur(dd, E, table); + if (Eres == NULL) { + Cudd_tlcInfoFree(Tres); + return(NULL); + } + res = computeClauses(Tres, Eres, index, dd->size); + Cudd_tlcInfoFree(Tres); + } + } else if (T == lzero || T == azero) { + /* T is zero. If E is a non-zero constant, then the + ** complement of this node's index is a one-literal clause. + ** Otherwise, if E is not constant, we recursively compute its + ** clauses, and then merge using the universal set for T. */ + if (Cudd_IsConstant(E)) { /* E cannot be zero here */ + /* Create the clause (!index + 0). */ + res = tlcInfoAlloc(); + if (res == NULL) return(NULL); + res->vars = ALLOC(DdHalfWord,4); + if (res->vars == NULL) { + FREE(res); + return(NULL); + } + res->phases = bitVectorAlloc(2); + if (res->phases == NULL) { + FREE(res->vars); + FREE(res); + return(NULL); + } + res->vars[0] = index; + res->vars[1] = CUDD_MAXINDEX; + res->vars[2] = 0; + res->vars[3] = 0; + bitVectorSet(res->phases, 0, 1); /* negative phase */ + bitVectorSet(res->phases, 1, 1); /* negative phase */ + } else { /* E == non-constant */ + Eres = ddFindTwoLiteralClausesRecur(dd, E, table); + if (Eres == NULL) return(NULL); + res = computeClausesWithUniverse(Eres, index, 1); + } + } else { /* T == non-const */ + Tres = ddFindTwoLiteralClausesRecur(dd, T, table); + if (Tres == NULL) return(NULL); + if (Cudd_IsConstant(E)) { + if (E == lzero || E == azero) { + res = computeClausesWithUniverse(Tres, index, 0); + } else { + Eres = emptyClauseSet(); + if (Eres == NULL) return(NULL); + res = computeClauses(Tres, Eres, index, dd->size); + Cudd_tlcInfoFree(Eres); + } + } else { + Eres = ddFindTwoLiteralClausesRecur(dd, E, table); + if (Eres == NULL) return(NULL); + res = computeClauses(Tres, Eres, index, dd->size); + } + } + + /* Cache results. */ + if (st_add_direct(table, (char *)f, (char *)res) == ST_OUT_OF_MEM) { + FREE(res); + return(NULL); + } + return(res); + +} /* end of ddFindTwoLiteralClausesRecur */ + + +/**Function******************************************************************** + + Synopsis [Computes the two-literal clauses for a node.] + + Description [Computes the two-literal clauses for a node given the + clauses for its children and the label of the node. Returns a + pointer to a TclInfo structure if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [computeClausesWithUniverse] + +******************************************************************************/ +static DdTlcInfo * +computeClauses( + DdTlcInfo *Tres /* list of clauses for T child */, + DdTlcInfo *Eres /* list of clauses for E child */, + DdHalfWord label /* variable labeling the current node */, + int size /* number of variables in the manager */) +{ + DdHalfWord *Tcv = Tres->vars; /* variables of clauses for the T child */ + BitVector *Tcp = Tres->phases; /* phases of clauses for the T child */ + DdHalfWord *Ecv = Eres->vars; /* variables of clauses for the E child */ + BitVector *Ecp = Eres->phases; /* phases of clauses for the E child */ + DdHalfWord *Vcv = NULL; /* pointer to variables of the clauses for v */ + BitVector *Vcp = NULL; /* pointer to phases of the clauses for v */ + DdTlcInfo *res = NULL; /* the set of clauses to be returned */ + int pt = 0; /* index in the list of clauses of T */ + int pe = 0; /* index in the list of clauses of E */ + int cv = 0; /* counter of the clauses for this node */ + TlClause *iclauses = NULL; /* list of inherited clauses */ + TlClause *tclauses = NULL; /* list of 1-literal clauses of T */ + TlClause *eclauses = NULL; /* list of 1-literal clauses of E */ + TlClause *nclauses = NULL; /* list of new (non-inherited) clauses */ + TlClause *lnclause = NULL; /* pointer to last new clause */ + TlClause *newclause; /* temporary pointer to new clauses */ + + /* Initialize sets of one-literal clauses. The one-literal clauses + ** are stored redundantly. These sets allow constant-time lookup, which + ** we need when we check for implication of a two-literal clause by a + ** one-literal clause. The linked lists allow fast sequential + ** processing. */ + bitVectorClear(Tolv, size); + bitVectorClear(Tolp, size); + bitVectorClear(Eolv, size); + bitVectorClear(Eolp, size); + + /* Initialize result structure. */ + res = tlcInfoAlloc(); + if (res == NULL) goto cleanup; + + /* Scan the two input list. Extract inherited two-literal clauses + ** and set aside one-literal clauses from each list. The incoming lists + ** are sorted in the order defined by beforep. The three linked list + ** produced by this loop are sorted in the reverse order because we + ** always append to the front of the lists. + ** The inherited clauses are those clauses (both one- and two-literal) + ** that are common to both children; and the two-literal clauses of + ** one child that are implied by a one-literal clause of the other + ** child. */ + while (!sentinelp(Tcv[pt], Tcv[pt+1]) || !sentinelp(Ecv[pe], Ecv[pe+1])) { + if (equalp(Tcv[pt], bitVectorRead(Tcp, pt), + Tcv[pt+1], bitVectorRead(Tcp, pt+1), + Ecv[pe], bitVectorRead(Ecp, pe), + Ecv[pe+1], bitVectorRead(Ecp, pe+1))) { + /* Add clause to inherited list. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Tcv[pt]; + newclause->v2 = Tcv[pt+1]; + newclause->p1 = bitVectorRead(Tcp, pt); + newclause->p2 = bitVectorRead(Tcp, pt+1); + newclause->next = iclauses; + iclauses = newclause; + pt += 2; pe += 2; cv++; + } else if (beforep(Tcv[pt], bitVectorRead(Tcp, pt), + Tcv[pt+1], bitVectorRead(Tcp, pt+1), + Ecv[pe], bitVectorRead(Ecp, pe), + Ecv[pe+1], bitVectorRead(Ecp, pe+1))) { + if (oneliteralp(Tcv[pt+1])) { + /* Add this one-literal clause to the T set. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Tcv[pt]; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = bitVectorRead(Tcp, pt); + newclause->p2 = 1; + newclause->next = tclauses; + tclauses = newclause; + bitVectorSet(Tolv, Tcv[pt], 1); + bitVectorSet(Tolp, Tcv[pt], bitVectorRead(Tcp, pt)); + } else { + if (impliedp(Tcv[pt], bitVectorRead(Tcp, pt), + Tcv[pt+1], bitVectorRead(Tcp, pt+1), + Eolv, Eolp)) { + /* Add clause to inherited list. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Tcv[pt]; + newclause->v2 = Tcv[pt+1]; + newclause->p1 = bitVectorRead(Tcp, pt); + newclause->p2 = bitVectorRead(Tcp, pt+1); + newclause->next = iclauses; + iclauses = newclause; + cv++; + } + } + pt += 2; + } else { /* !beforep() */ + if (oneliteralp(Ecv[pe+1])) { + /* Add this one-literal clause to the E set. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Ecv[pe]; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = bitVectorRead(Ecp, pe); + newclause->p2 = 1; + newclause->next = eclauses; + eclauses = newclause; + bitVectorSet(Eolv, Ecv[pe], 1); + bitVectorSet(Eolp, Ecv[pe], bitVectorRead(Ecp, pe)); + } else { + if (impliedp(Ecv[pe], bitVectorRead(Ecp, pe), + Ecv[pe+1], bitVectorRead(Ecp, pe+1), + Tolv, Tolp)) { + /* Add clause to inherited list. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Ecv[pe]; + newclause->v2 = Ecv[pe+1]; + newclause->p1 = bitVectorRead(Ecp, pe); + newclause->p2 = bitVectorRead(Ecp, pe+1); + newclause->next = iclauses; + iclauses = newclause; + cv++; + } + } + pe += 2; + } + } + + /* Add one-literal clauses for the label variable to the front of + ** the two lists. */ + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = label; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = 0; + newclause->p2 = 1; + newclause->next = tclauses; + tclauses = newclause; + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = label; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = 1; + newclause->p2 = 1; + newclause->next = eclauses; + eclauses = newclause; + + /* Produce the non-inherited clauses. We preserve the "reverse" + ** order of the two input lists by appending to the end of the + ** list. In this way, iclauses and nclauses are consistent. */ + while (tclauses != NULL && eclauses != NULL) { + if (beforep(eclauses->v1, eclauses->p1, eclauses->v2, eclauses->p2, + tclauses->v1, tclauses->p1, tclauses->v2, tclauses->p2)) { + TlClause *nextclause = tclauses->next; + TlClause *otherclauses = eclauses; + while (otherclauses != NULL) { + if (tclauses->v1 != otherclauses->v1) { + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = tclauses->v1; + newclause->v2 = otherclauses->v1; + newclause->p1 = tclauses->p1; + newclause->p2 = otherclauses->p1; + newclause->next = NULL; + if (nclauses == NULL) { + nclauses = newclause; + lnclause = newclause; + } else { + lnclause->next = newclause; + lnclause = newclause; + } + cv++; + } + otherclauses = otherclauses->next; + } + FREE(tclauses); + tclauses = nextclause; + } else { + TlClause *nextclause = eclauses->next; + TlClause *otherclauses = tclauses; + while (otherclauses != NULL) { + if (eclauses->v1 != otherclauses->v1) { + newclause = ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = eclauses->v1; + newclause->v2 = otherclauses->v1; + newclause->p1 = eclauses->p1; + newclause->p2 = otherclauses->p1; + newclause->next = NULL; + if (nclauses == NULL) { + nclauses = newclause; + lnclause = newclause; + } else { + lnclause->next = newclause; + lnclause = newclause; + } + cv++; + } + otherclauses = otherclauses->next; + } + FREE(eclauses); + eclauses = nextclause; + } + } + while (tclauses != NULL) { + TlClause *nextclause = tclauses->next; + FREE(tclauses); + tclauses = nextclause; + } + while (eclauses != NULL) { + TlClause *nextclause = eclauses->next; + FREE(eclauses); + eclauses = nextclause; + } + + /* Merge inherited and non-inherited clauses. Now that we know the + ** total number, we allocate the arrays, and we fill them bottom-up + ** to restore the proper ordering. */ + Vcv = ALLOC(DdHalfWord, 2*(cv+1)); + if (Vcv == NULL) goto cleanup; + if (cv > 0) { + Vcp = bitVectorAlloc(2*cv); + if (Vcp == NULL) goto cleanup; + } else { + Vcp = NULL; + } + res->vars = Vcv; + res->phases = Vcp; + /* Add sentinel. */ + Vcv[2*cv] = 0; + Vcv[2*cv+1] = 0; + while (iclauses != NULL || nclauses != NULL) { + TlClause *nextclause; + cv--; + if (nclauses == NULL || (iclauses != NULL && + beforep(nclauses->v1, nclauses->p1, nclauses->v2, nclauses->p2, + iclauses->v1, iclauses->p1, iclauses->v2, iclauses->p2))) { + Vcv[2*cv] = iclauses->v1; + Vcv[2*cv+1] = iclauses->v2; + bitVectorSet(Vcp, 2*cv, iclauses->p1); + bitVectorSet(Vcp, 2*cv+1, iclauses->p2); + nextclause = iclauses->next; + FREE(iclauses); + iclauses = nextclause; + } else { + Vcv[2*cv] = nclauses->v1; + Vcv[2*cv+1] = nclauses->v2; + bitVectorSet(Vcp, 2*cv, nclauses->p1); + bitVectorSet(Vcp, 2*cv+1, nclauses->p2); + nextclause = nclauses->next; + FREE(nclauses); + nclauses = nextclause; + } + } + assert(cv == 0); + + return(res); + + cleanup: + if (res != NULL) Cudd_tlcInfoFree(res); + while (iclauses != NULL) { + TlClause *nextclause = iclauses->next; + FREE(iclauses); + iclauses = nextclause; + } + while (nclauses != NULL) { + TlClause *nextclause = nclauses->next; + FREE(nclauses); + nclauses = nextclause; + } + while (tclauses != NULL) { + TlClause *nextclause = tclauses->next; + FREE(tclauses); + tclauses = nextclause; + } + while (eclauses != NULL) { + TlClause *nextclause = eclauses->next; + FREE(eclauses); + eclauses = nextclause; + } + + return(NULL); + +} /* end of computeClauses */ + + +/**Function******************************************************************** + + Synopsis [Computes the two-literal clauses for a node.] + + Description [Computes the two-literal clauses for a node with a zero + child, given the clauses for its other child and the label of the + node. Returns a pointer to a TclInfo structure if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [computeClauses] + +******************************************************************************/ +static DdTlcInfo * +computeClausesWithUniverse( + DdTlcInfo *Cres /* list of clauses for child */, + DdHalfWord label /* variable labeling the current node */, + short phase /* 0 if E child is zero; 1 if T child is zero */) +{ + DdHalfWord *Ccv = Cres->vars; /* variables of clauses for child */ + BitVector *Ccp = Cres->phases; /* phases of clauses for child */ + DdHalfWord *Vcv = NULL; /* pointer to the variables of the clauses for v */ + BitVector *Vcp = NULL; /* pointer to the phases of the clauses for v */ + DdTlcInfo *res = NULL; /* the set of clauses to be returned */ + int i; + + /* Initialize result. */ + res = tlcInfoAlloc(); + if (res == NULL) goto cleanup; + /* Count entries for new list and allocate accordingly. */ + for (i = 0; !sentinelp(Ccv[i], Ccv[i+1]); i += 2); + /* At this point, i is twice the number of clauses in the child's + ** list. We need four more entries for this node: 2 for the one-literal + ** clause for the label, and 2 for the sentinel. */ + Vcv = ALLOC(DdHalfWord,i+4); + if (Vcv == NULL) goto cleanup; + Vcp = bitVectorAlloc(i+4); + if (Vcp == NULL) goto cleanup; + res->vars = Vcv; + res->phases = Vcp; + /* Copy old list into new. */ + for (i = 0; !sentinelp(Ccv[i], Ccv[i+1]); i += 2) { + Vcv[i] = Ccv[i]; + Vcv[i+1] = Ccv[i+1]; + bitVectorSet(Vcp, i, bitVectorRead(Ccp, i)); + bitVectorSet(Vcp, i+1, bitVectorRead(Ccp, i+1)); + } + /* Add clause corresponding to label. */ + Vcv[i] = label; + bitVectorSet(Vcp, i, phase); + i++; + Vcv[i] = CUDD_MAXINDEX; + bitVectorSet(Vcp, i, 1); + i++; + /* Add sentinel. */ + Vcv[i] = 0; + Vcv[i+1] = 0; + bitVectorSet(Vcp, i, 0); + bitVectorSet(Vcp, i+1, 0); + + return(res); + + cleanup: + /* Vcp is guaranteed to be NULL here. Hence, we do not try to free it. */ + if (Vcv != NULL) FREE(Vcv); + if (res != NULL) Cudd_tlcInfoFree(res); + + return(NULL); + +} /* end of computeClausesWithUniverse */ + + +/**Function******************************************************************** + + Synopsis [Returns an enpty set of clauses.] + + Description [Returns a pointer to an empty set of clauses if + successful; NULL otherwise. No bit vector for the phases is + allocated.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdTlcInfo * +emptyClauseSet(void) +{ + DdTlcInfo *eset; + + eset = ALLOC(DdTlcInfo,1); + if (eset == NULL) return(NULL); + eset->vars = ALLOC(DdHalfWord,2); + if (eset->vars == NULL) { + FREE(eset); + return(NULL); + } + /* Sentinel */ + eset->vars[0] = 0; + eset->vars[1] = 0; + eset->phases = NULL; /* does not matter */ + eset->cnt = 0; + return(eset); + +} /* end of emptyClauseSet */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the argument is the sentinel clause.] + + Description [Returns true iff the argument is the sentinel clause. + A sentinel clause has both variables equal to 0.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +sentinelp( + DdHalfWord var1, + DdHalfWord var2) +{ + return(var1 == 0 && var2 == 0); + +} /* end of sentinelp */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the two arguments are identical clauses.] + + Description [Returns true iff the two arguments are identical + clauses. Since literals are sorted, we only need to compare + literals in the same position.] + + SideEffects [None] + + SeeAlso [beforep] + +******************************************************************************/ +static int +equalp( + DdHalfWord var1a, + short phase1a, + DdHalfWord var1b, + short phase1b, + DdHalfWord var2a, + short phase2a, + DdHalfWord var2b, + short phase2b) +{ + return(var1a == var2a && phase1a == phase2a && + var1b == var2b && phase1b == phase2b); + +} /* end of equalp */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the first argument precedes the second in + the clause order.] + + Description [Returns true iff the first argument precedes the second + in the clause order. A clause precedes another if its first lieral + precedes the first literal of the other, or if the first literals + are the same, and its second literal precedes the second literal of + the other clause. A literal precedes another if it has a higher + index, of if it has the same index, but it has lower phase. Phase 0 + is the positive phase, and it is lower than Phase 1 (negative + phase).] + + SideEffects [None] + + SeeAlso [equalp] + +******************************************************************************/ +static int +beforep( + DdHalfWord var1a, + short phase1a, + DdHalfWord var1b, + short phase1b, + DdHalfWord var2a, + short phase2a, + DdHalfWord var2b, + short phase2b) +{ + return(var1a > var2a || (var1a == var2a && + (phase1a < phase2a || (phase1a == phase2a && + (var1b > var2b || (var1b == var2b && phase1b < phase2b)))))); + +} /* end of beforep */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the argument is a one-literal clause.] + + Description [Returns true iff the argument is a one-literal clause. + A one-litaral clause has the constant FALSE as second literal. + Since the constant TRUE is never used, it is sufficient to test for + a constant.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +oneliteralp( + DdHalfWord var) +{ + return(var == CUDD_MAXINDEX); + +} /* end of oneliteralp */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff either literal of a clause is in a set of + literals.] + + Description [Returns true iff either literal of a clause is in a set + of literals. The first four arguments specify the clause. The + remaining two arguments specify the literal set.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +impliedp( + DdHalfWord var1, + short phase1, + DdHalfWord var2, + short phase2, + BitVector *olv, + BitVector *olp) +{ + return((bitVectorRead(olv, var1) && + bitVectorRead(olp, var1) == phase1) || + (bitVectorRead(olv, var2) && + bitVectorRead(olp, var2) == phase2)); + +} /* end of impliedp */ + + +/**Function******************************************************************** + + Synopsis [Allocates a bit vector.] + + Description [Allocates a bit vector. The parameter size gives the + number of bits. This procedure allocates enough long's to hold the + specified number of bits. Returns a pointer to the allocated vector + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [bitVectorClear bitVectorFree] + +******************************************************************************/ +static BitVector * +bitVectorAlloc( + int size) +{ + int allocSize; + BitVector *vector; + + /* Find out how many long's we need. + ** There are sizeof(long) * 8 bits in a long. + ** The ceiling of the ratio of two integers m and n is given + ** by ((n-1)/m)+1. Putting all this together, we get... */ + allocSize = ((size - 1) / (sizeof(BitVector) * 8)) + 1; + vector = ALLOC(BitVector, allocSize); + if (vector == NULL) return(NULL); + /* Clear the whole array. */ + (void) memset(vector, 0, allocSize * sizeof(BitVector)); + return(vector); + +} /* end of bitVectorAlloc */ + + +/**Function******************************************************************** + + Synopsis [Clears a bit vector.] + + Description [Clears a bit vector. The parameter size gives the + number of bits.] + + SideEffects [None] + + SeeAlso [bitVectorAlloc] + +******************************************************************************/ +DD_INLINE +static void +bitVectorClear( + BitVector *vector, + int size) +{ + int allocSize; + + /* Find out how many long's we need. + ** There are sizeof(long) * 8 bits in a long. + ** The ceiling of the ratio of two integers m and n is given + ** by ((n-1)/m)+1. Putting all this together, we get... */ + allocSize = ((size - 1) / (sizeof(BitVector) * 8)) + 1; + /* Clear the whole array. */ + (void) memset(vector, 0, allocSize * sizeof(BitVector)); + return; + +} /* end of bitVectorClear */ + + +/**Function******************************************************************** + + Synopsis [Frees a bit vector.] + + Description [Frees a bit vector.] + + SideEffects [None] + + SeeAlso [bitVectorAlloc] + +******************************************************************************/ +static void +bitVectorFree( + BitVector *vector) +{ + FREE(vector); + +} /* end of bitVectorFree */ + + +/**Function******************************************************************** + + Synopsis [Returns the i-th entry of a bit vector.] + + Description [Returns the i-th entry of a bit vector.] + + SideEffects [None] + + SeeAlso [bitVectorSet] + +******************************************************************************/ +DD_INLINE +static short +bitVectorRead( + BitVector *vector, + int i) +{ + int word, bit; + short result; + + if (vector == NULL) return((short) 0); + + word = i >> LOGBPL; + bit = i & (BPL - 1); + result = (short) ((vector[word] >> bit) & 1L); + return(result); + +} /* end of bitVectorRead */ + + +/**Function******************************************************************** + + Synopsis [Sets the i-th entry of a bit vector to a value.] + + Description [Sets the i-th entry of a bit vector to a value.] + + SideEffects [None] + + SeeAlso [bitVectorRead] + +******************************************************************************/ +DD_INLINE +static void +bitVectorSet( + BitVector * vector, + int i, + short val) +{ + int word, bit; + + word = i >> LOGBPL; + bit = i & (BPL - 1); + vector[word] &= ~(1L << bit); + vector[word] |= (((long) val) << bit); + +} /* end of bitVectorSet */ + + +/**Function******************************************************************** + + Synopsis [Allocates a DdTlcInfo Structure.] + + Description [Returns a pointer to a DdTlcInfo Structure if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_tlcInfoFree] + +******************************************************************************/ +static DdTlcInfo * +tlcInfoAlloc(void) +{ + DdTlcInfo *res = ALLOC(DdTlcInfo,1); + if (res == NULL) return(NULL); + res->vars = NULL; + res->phases = NULL; + res->cnt = 0; + return(res); + +} /* end of tlcInfoAlloc */ diff --git a/cudd_local/cudd/cuddExact.c b/cudd_local/cudd/cuddExact.c new file mode 100644 index 0000000..caffbba --- /dev/null +++ b/cudd_local/cudd/cuddExact.c @@ -0,0 +1,1020 @@ +/**CFile*********************************************************************** + + FileName [cuddExact.c] + + PackageName [cudd] + + Synopsis [Functions for exact variable reordering.] + + Description [External procedures included in this file: +
    +
+ Internal procedures included in this module: +
    +
  • cuddExact() +
+ Static procedures included in this module: +
    +
  • getMaxBinomial() +
  • gcd() +
  • getMatrix() +
  • freeMatrix() +
  • getLevelKeys() +
  • ddShuffle() +
  • ddSiftUp() +
  • updateUB() +
  • ddCountRoots() +
  • ddClearGlobal() +
  • computeLB() +
  • updateEntry() +
  • pushDown() +
  • initSymmInfo() +
] + + Author [Cheng Hua, Fabio Somenzi] + + Copyright [Copyright (c) 1995-2012, 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: cuddExact.c,v 1.30 2012/02/05 01:07:18 fabio Exp $"; +#endif + +#ifdef DD_STATS +static int ddTotalShuffles; +#endif + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +static int getMaxBinomial (int n); +static DdHalfWord ** getMatrix (int rows, int cols); +static void freeMatrix (DdHalfWord **matrix); +static int getLevelKeys (DdManager *table, int l); +static int ddShuffle (DdManager *table, DdHalfWord *permutation, int lower, int upper); +static int ddSiftUp (DdManager *table, int x, int xLow); +static int updateUB (DdManager *table, int oldBound, DdHalfWord *bestOrder, int lower, int upper); +static int ddCountRoots (DdManager *table, int lower, int upper); +static void ddClearGlobal (DdManager *table, int lower, int maxlevel); +static int computeLB (DdManager *table, DdHalfWord *order, int roots, int cost, int lower, int upper, int level); +static int updateEntry (DdManager *table, DdHalfWord *order, int level, int cost, DdHalfWord **orders, int *costs, int subsets, char *mask, int lower, int upper); +static void pushDown (DdHalfWord *order, int j, int level); +static DdHalfWord * initSymmInfo (DdManager *table, int lower, int upper); +static int checkSymmInfo (DdManager *table, DdHalfWord *symmInfo, int index, int level); + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Exact variable ordering algorithm.] + + Description [Exact variable ordering algorithm. Finds an optimum + order for the variables between lower and upper. Returns 1 if + successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +int +cuddExact( + DdManager * table, + int lower, + int upper) +{ + int k, i, j; + int maxBinomial, oldSubsets, newSubsets; + int subsetCost; + int size; /* number of variables to be reordered */ + int unused, nvars, level, result; + int upperBound, lowerBound, cost; + int roots; + char *mask = NULL; + DdHalfWord *symmInfo = NULL; + DdHalfWord **newOrder = NULL; + DdHalfWord **oldOrder = NULL; + int *newCost = NULL; + int *oldCost = NULL; + DdHalfWord **tmpOrder; + int *tmpCost; + DdHalfWord *bestOrder = NULL; + DdHalfWord *order; +#ifdef DD_STATS + int ddTotalSubsets; +#endif + + /* Restrict the range to be reordered by excluding unused variables + ** at the two ends. */ + while (table->subtables[lower].keys == 1 && + table->vars[table->invperm[lower]]->ref == 1 && + lower < upper) + lower++; + while (table->subtables[upper].keys == 1 && + table->vars[table->invperm[upper]]->ref == 1 && + lower < upper) + upper--; + if (lower == upper) return(1); /* trivial problem */ + + /* Apply symmetric sifting to get a good upper bound and to extract + ** symmetry information. */ + result = cuddSymmSiftingConv(table,lower,upper); + if (result == 0) goto cuddExactOutOfMem; + +#ifdef DD_STATS + (void) fprintf(table->out,"\n"); + ddTotalShuffles = 0; + ddTotalSubsets = 0; +#endif + + /* Initialization. */ + nvars = table->size; + size = upper - lower + 1; + /* Count unused variable among those to be reordered. This is only + ** used to compute maxBinomial. */ + unused = 0; + for (i = lower + 1; i < upper; i++) { + if (table->subtables[i].keys == 1 && + table->vars[table->invperm[i]]->ref == 1) + unused++; + } + + /* Find the maximum number of subsets we may have to store. */ + maxBinomial = getMaxBinomial(size - unused); + if (maxBinomial == -1) goto cuddExactOutOfMem; + + newOrder = getMatrix(maxBinomial, size); + if (newOrder == NULL) goto cuddExactOutOfMem; + + newCost = ALLOC(int, maxBinomial); + if (newCost == NULL) goto cuddExactOutOfMem; + + oldOrder = getMatrix(maxBinomial, size); + if (oldOrder == NULL) goto cuddExactOutOfMem; + + oldCost = ALLOC(int, maxBinomial); + if (oldCost == NULL) goto cuddExactOutOfMem; + + bestOrder = ALLOC(DdHalfWord, size); + if (bestOrder == NULL) goto cuddExactOutOfMem; + + mask = ALLOC(char, nvars); + if (mask == NULL) goto cuddExactOutOfMem; + + symmInfo = initSymmInfo(table, lower, upper); + if (symmInfo == NULL) goto cuddExactOutOfMem; + + roots = ddCountRoots(table, lower, upper); + + /* Initialize the old order matrix for the empty subset and the best + ** order to the current order. The cost for the empty subset includes + ** the cost of the levels between upper and the constants. These levels + ** are not going to change. Hence, we count them only once. + */ + oldSubsets = 1; + for (i = 0; i < size; i++) { + oldOrder[0][i] = bestOrder[i] = (DdHalfWord) table->invperm[i+lower]; + } + subsetCost = table->constants.keys; + for (i = upper + 1; i < nvars; i++) + subsetCost += getLevelKeys(table,i); + oldCost[0] = subsetCost; + /* The upper bound is initialized to the current size of the BDDs. */ + upperBound = table->keys - table->isolated; + + /* Now consider subsets of increasing size. */ + for (k = 1; k <= size; k++) { +#ifdef DD_STATS + (void) fprintf(table->out,"Processing subsets of size %d\n", k); + fflush(table->out); +#endif + newSubsets = 0; + level = size - k; /* offset of first bottom variable */ + + for (i = 0; i < oldSubsets; i++) { /* for each subset of size k-1 */ + order = oldOrder[i]; + cost = oldCost[i]; + lowerBound = computeLB(table, order, roots, cost, lower, upper, + level); + if (lowerBound >= upperBound) + continue; + /* Impose new order. */ + result = ddShuffle(table, order, lower, upper); + if (result == 0) goto cuddExactOutOfMem; + upperBound = updateUB(table,upperBound,bestOrder,lower,upper); + /* For each top bottom variable. */ + for (j = level; j >= 0; j--) { + /* Skip unused variables. */ + if (table->subtables[j+lower-1].keys == 1 && + table->vars[table->invperm[j+lower-1]]->ref == 1) continue; + /* Find cost under this order. */ + subsetCost = cost + getLevelKeys(table, lower + level); + newSubsets = updateEntry(table, order, level, subsetCost, + newOrder, newCost, newSubsets, mask, + lower, upper); + if (j == 0) + break; + if (checkSymmInfo(table, symmInfo, order[j-1], level) == 0) + continue; + pushDown(order,j-1,level); + /* Impose new order. */ + result = ddShuffle(table, order, lower, upper); + if (result == 0) goto cuddExactOutOfMem; + upperBound = updateUB(table,upperBound,bestOrder,lower,upper); + } /* for each bottom variable */ + } /* for each subset of size k */ + + /* New orders become old orders in preparation for next iteration. */ + tmpOrder = oldOrder; tmpCost = oldCost; + oldOrder = newOrder; oldCost = newCost; + newOrder = tmpOrder; newCost = tmpCost; +#ifdef DD_STATS + ddTotalSubsets += newSubsets; +#endif + oldSubsets = newSubsets; + } + result = ddShuffle(table, bestOrder, lower, upper); + if (result == 0) goto cuddExactOutOfMem; +#ifdef DD_STATS +#ifdef DD_VERBOSE + (void) fprintf(table->out,"\n"); +#endif + (void) fprintf(table->out,"#:S_EXACT %8d: total subsets\n", + ddTotalSubsets); + (void) fprintf(table->out,"#:H_EXACT %8d: total shuffles", + ddTotalShuffles); +#endif + + freeMatrix(newOrder); + freeMatrix(oldOrder); + FREE(bestOrder); + FREE(oldCost); + FREE(newCost); + FREE(symmInfo); + FREE(mask); + return(1); + +cuddExactOutOfMem: + + if (newOrder != NULL) freeMatrix(newOrder); + if (oldOrder != NULL) freeMatrix(oldOrder); + if (bestOrder != NULL) FREE(bestOrder); + if (oldCost != NULL) FREE(oldCost); + if (newCost != NULL) FREE(newCost); + if (symmInfo != NULL) FREE(symmInfo); + if (mask != NULL) FREE(mask); + table->errorCode = CUDD_MEMORY_OUT; + return(0); + +} /* end of cuddExact */ + + +/**Function******************************************************************** + + Synopsis [Returns the maximum value of (n choose k) for a given n.] + + Description [Computes the maximum value of (n choose k) for a given + n. The maximum value occurs for k = n/2 when n is even, or k = + (n-1)/2 when n is odd. The algorithm used in this procedure avoids + intermediate overflow problems. It is based on the identity +
+    binomial(n,k) = n/k * binomial(n-1,k-1).
+  
+ Returns the computed value if successful; -1 if out of range.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +getMaxBinomial( + int n) +{ + double i, j, result; + + if (n < 0 || n > 33) return(-1); /* error */ + if (n < 2) return(1); + + for (result = (double)((n+3)/2), i = result+1, j=2; i <= n; i++, j++) { + result *= i; + result /= j; + } + + return((int)result); + +} /* end of getMaxBinomial */ + + +#if 0 +/**Function******************************************************************** + + Synopsis [Returns the gcd of two integers.] + + Description [Returns the gcd of two integers. Uses the binary GCD + algorithm described in Cormen, Leiserson, and Rivest.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +gcd( + int x, + int y) +{ + int a; + int b; + int lsbMask; + + /* GCD(n,0) = n. */ + if (x == 0) return(y); + if (y == 0) return(x); + + a = x; b = y; lsbMask = 1; + + /* Here both a and b are != 0. The iteration maintains this invariant. + ** Hence, we only need to check for when they become equal. + */ + while (a != b) { + if (a & lsbMask) { + if (b & lsbMask) { /* both odd */ + if (a < b) { + b = (b - a) >> 1; + } else { + a = (a - b) >> 1; + } + } else { /* a odd, b even */ + b >>= 1; + } + } else { + if (b & lsbMask) { /* a even, b odd */ + a >>= 1; + } else { /* both even */ + lsbMask <<= 1; + } + } + } + + return(a); + +} /* end of gcd */ +#endif + + +/**Function******************************************************************** + + Synopsis [Allocates a two-dimensional matrix of ints.] + + Description [Allocates a two-dimensional matrix of ints. + Returns the pointer to the matrix if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [freeMatrix] + +******************************************************************************/ +static DdHalfWord ** +getMatrix( + int rows /* number of rows */, + int cols /* number of columns */) +{ + DdHalfWord **matrix; + int i; + + if (cols*rows == 0) return(NULL); + matrix = ALLOC(DdHalfWord *, rows); + if (matrix == NULL) return(NULL); + matrix[0] = ALLOC(DdHalfWord, cols*rows); + if (matrix[0] == NULL) { + FREE(matrix); + return(NULL); + } + for (i = 1; i < rows; i++) { + matrix[i] = matrix[i-1] + cols; + } + return(matrix); + +} /* end of getMatrix */ + + +/**Function******************************************************************** + + Synopsis [Frees a two-dimensional matrix allocated by getMatrix.] + + Description [] + + SideEffects [None] + + SeeAlso [getMatrix] + +******************************************************************************/ +static void +freeMatrix( + DdHalfWord ** matrix) +{ + FREE(matrix[0]); + FREE(matrix); + return; + +} /* end of freeMatrix */ + + +/**Function******************************************************************** + + Synopsis [Returns the number of nodes at one level of a unique table.] + + Description [Returns the number of nodes at one level of a unique table. + The projection function, if isolated, is not counted.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +getLevelKeys( + DdManager * table, + int l) +{ + int isolated; + int x; /* x is an index */ + + x = table->invperm[l]; + isolated = table->vars[x]->ref == 1; + + return(table->subtables[l].keys - isolated); + +} /* end of getLevelKeys */ + + +/**Function******************************************************************** + + Synopsis [Reorders variables according to a given permutation.] + + Description [Reorders variables according to a given permutation. + The i-th permutation array contains the index of the variable that + should be brought to the i-th level. ddShuffle assumes that no + dead nodes are present and that the interaction matrix is properly + initialized. The reordering is achieved by a series of upward sifts. + Returns 1 if successful; 0 otherwise.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddShuffle( + DdManager * table, + DdHalfWord * permutation, + int lower, + int upper) +{ + DdHalfWord index; + int level; + int position; +#if 0 + int numvars; +#endif + int result; +#ifdef DD_STATS + unsigned long localTime; + int initialSize; +#ifdef DD_VERBOSE + int finalSize; +#endif + int previousSize; +#endif + +#ifdef DD_STATS + localTime = util_cpu_time(); + initialSize = table->keys - table->isolated; +#endif + +#if 0 + numvars = table->size; + + (void) fprintf(table->out,"%d:", ddTotalShuffles); + for (level = 0; level < numvars; level++) { + (void) fprintf(table->out," %d", table->invperm[level]); + } + (void) fprintf(table->out,"\n"); +#endif + + for (level = 0; level <= upper - lower; level++) { + index = permutation[level]; + position = table->perm[index]; +#ifdef DD_STATS + previousSize = table->keys - table->isolated; +#endif + result = ddSiftUp(table,position,level+lower); + if (!result) return(0); + } + +#ifdef DD_STATS + ddTotalShuffles++; +#ifdef DD_VERBOSE + finalSize = table->keys - table->isolated; + if (finalSize < initialSize) { + (void) fprintf(table->out,"-"); + } else if (finalSize > initialSize) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + if ((ddTotalShuffles & 63) == 0) (void) fprintf(table->out,"\n"); + fflush(table->out); +#endif +#endif + + return(1); + +} /* end of ddShuffle */ + + +/**Function******************************************************************** + + Synopsis [Moves one variable up.] + + Description [Takes a variable from position x and sifts it up to + position xLow; xLow should be less than or equal to x. + Returns 1 if successful; 0 otherwise] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +ddSiftUp( + DdManager * table, + int x, + int xLow) +{ + int y; + int size; + + y = cuddNextLow(table,x); + while (y >= xLow) { + size = cuddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddNextLow(table,x); + } + return(1); + +} /* end of ddSiftUp */ + + +/**Function******************************************************************** + + Synopsis [Updates the upper bound and saves the best order seen so far.] + + Description [Updates the upper bound and saves the best order seen so far. + Returns the current value of the upper bound.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +updateUB( + DdManager * table, + int oldBound, + DdHalfWord * bestOrder, + int lower, + int upper) +{ + int i; + int newBound = table->keys - table->isolated; + + if (newBound < oldBound) { +#ifdef DD_STATS + (void) fprintf(table->out,"New upper bound = %d\n", newBound); + fflush(table->out); +#endif + for (i = lower; i <= upper; i++) + bestOrder[i-lower] = (DdHalfWord) table->invperm[i]; + return(newBound); + } else { + return(oldBound); + } + +} /* end of updateUB */ + + +/**Function******************************************************************** + + Synopsis [Counts the number of roots.] + + Description [Counts the number of roots at the levels between lower and + upper. The computation is based on breadth-first search. + A node is a root if it is not reachable from any previously visited node. + (All the nodes at level lower are therefore considered roots.) + The visited flag uses the LSB of the next pointer. Returns the root + count. The roots that are constant nodes are always ignored.] + + SideEffects [None] + + SeeAlso [ddClearGlobal] + +******************************************************************************/ +static int +ddCountRoots( + DdManager * table, + int lower, + int upper) +{ + int i,j; + DdNode *f; + DdNodePtr *nodelist; + DdNode *sentinel = &(table->sentinel); + int slots; + int roots = 0; + int maxlevel = lower; + + for (i = lower; i <= upper; i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + /* A node is a root of the DAG if it cannot be + ** reached by nodes above it. If a node was never + ** reached during the previous depth-first searches, + ** then it is a root, and we start a new depth-first + ** search from it. + */ + if (!Cudd_IsComplement(f->next)) { + if (f != table->vars[f->index]) { + roots++; + } + } + if (!Cudd_IsConstant(cuddT(f))) { + cuddT(f)->next = Cudd_Complement(cuddT(f)->next); + if (table->perm[cuddT(f)->index] > maxlevel) + maxlevel = table->perm[cuddT(f)->index]; + } + if (!Cudd_IsConstant(cuddE(f))) { + Cudd_Regular(cuddE(f))->next = + Cudd_Complement(Cudd_Regular(cuddE(f))->next); + if (table->perm[Cudd_Regular(cuddE(f))->index] > maxlevel) + maxlevel = table->perm[Cudd_Regular(cuddE(f))->index]; + } + f = Cudd_Regular(f->next); + } + } + } + ddClearGlobal(table, lower, maxlevel); + + return(roots); + +} /* end of ddCountRoots */ + + +/**Function******************************************************************** + + Synopsis [Scans the DD and clears the LSB of the next pointers.] + + Description [Scans the DD and clears the LSB of the next pointers. + The LSB of the next pointers are used as markers to tell whether a + node was reached. Once the roots are counted, these flags are + reset.] + + SideEffects [None] + + SeeAlso [ddCountRoots] + +******************************************************************************/ +static void +ddClearGlobal( + DdManager * table, + int lower, + int maxlevel) +{ + int i,j; + DdNode *f; + DdNodePtr *nodelist; + DdNode *sentinel = &(table->sentinel); + int slots; + + for (i = lower; i <= maxlevel; i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + f->next = Cudd_Regular(f->next); + f = f->next; + } + } + } + +} /* end of ddClearGlobal */ + + +/**Function******************************************************************** + + Synopsis [Computes a lower bound on the size of a BDD.] + + Description [Computes a lower bound on the size of a BDD from the + following factors: +