123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833 |
- /**
- @file
- @ingroup cplusplus
- @brief Test program for the C++ object-oriented encapsulation of CUDD.
- @author Fabio Somenzi
- @copyright@parblock
- Copyright (c) 1995-2015, 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.
- @endparblock
- */
- #include "cuddObj.hh"
- #include <math.h>
- #include <iostream>
- #include <sstream>
- #include <cassert>
- #include <stdexcept>
- using namespace std;
- /*---------------------------------------------------------------------------*/
- /* Variable declarations */
- /*---------------------------------------------------------------------------*/
- /*---------------------------------------------------------------------------*/
- /* Static function prototypes */
- /*---------------------------------------------------------------------------*/
- static void testBdd(Cudd& mgr, int verbosity);
- static void testAdd(Cudd& mgr, int verbosity);
- static void testAdd2(Cudd& mgr, int verbosity);
- static void testZdd(Cudd& mgr, int verbosity);
- static void testBdd2(Cudd& mgr, int verbosity);
- static void testBdd3(Cudd& mgr, int verbosity);
- static void testZdd2(Cudd& mgr, int verbosity);
- static void testBdd4(Cudd& mgr, int verbosity);
- static void testBdd5(Cudd& mgr, int verbosity);
- static void testInterpolation(Cudd& mgr, int verbosity);
- static void testErrorHandling(Cudd& mgr, int verbosity);
- /*---------------------------------------------------------------------------*/
- /* Definition of exported functions */
- /*---------------------------------------------------------------------------*/
- /**
- @brief Main program for testobj.
- */
- int
- main(int argc, char **argv)
- {
- int verbosity = 0;
- if (argc == 2) {
- int cnt;
- int retval = sscanf(argv[1], "%d %n", &verbosity, &cnt);
- if (retval != 1 || argv[1][cnt])
- return 1;
- } else if (argc != 1) {
- return 1;
- }
- Cudd mgr(0,2);
- if (verbosity > 2) mgr.makeVerbose(); // trace constructors and destructors
- testBdd(mgr,verbosity);
- testAdd(mgr,verbosity);
- testAdd2(mgr,verbosity);
- testZdd(mgr,verbosity);
- testBdd2(mgr,verbosity);
- testBdd3(mgr,verbosity);
- testZdd2(mgr,verbosity);
- testBdd4(mgr,verbosity);
- testBdd5(mgr,verbosity);
- testInterpolation(mgr,verbosity);
- testErrorHandling(mgr,verbosity);
- if (verbosity) mgr.info();
- return 0;
- } // main
- /**
- @brief Test basic operators on BDDs.
- @details The function returns void
- because it relies on the error handling done by the interface. The
- default error handler causes program termination.
- @sideeffect Creates BDD variables in the manager.
- @see testBdd2 testBdd3 testBdd4 testBdd5
- */
- static void
- testBdd(
- Cudd& mgr,
- int verbosity)
- {
- if (verbosity) cout << "Entering testBdd\n";
- // Create two new variables in the manager. If testBdd is called before
- // any variable is created in mgr, then x gets index 0 and y gets index 1.
- BDD x = mgr.bddVar();
- BDD y = mgr.bddVar();
- BDD f = x * y;
- if (verbosity) cout << "f"; f.print(2,verbosity);
- BDD g = y + !x;
- if (verbosity) cout << "g"; g.print(2,verbosity);
- if (verbosity)
- cout << "f and g are" << (f == !g ? "" : " not") << " complementary\n";
- if (verbosity)
- cout << "f is" << (f <= g ? "" : " not") << " less than or equal to g\n";
- g = f | ~g;
- if (verbosity) cout << "g"; g.print(2,verbosity);
- BDD h = f = y;
- if (verbosity) cout << "h"; h.print(2,verbosity);
- if (verbosity) cout << "x + h has " << (x+h).nodeCount() << " nodes\n";
- h += x;
- if (verbosity) cout << "h"; h.print(2,verbosity);
- } // testBdd
- /**
- @brief Test basic operators on ADDs.
- @details The function returns void because it relies on the error
- handling done by the interface. The default error handler causes
- program termination.
- @sideeffect May create ADD variables in the manager.
- @see testAdd2
- */
- static void
- testAdd(
- Cudd& mgr,
- int verbosity)
- {
- if (verbosity) cout << "Entering testAdd\n";
- // Create two ADD variables. If we called method addVar without an
- // argument, we would get two new indices. If testAdd is indeed called
- // after testBdd, then those indices would be 2 and 3. By specifying the
- // arguments, on the other hand, we avoid creating new unnecessary BDD
- // variables.
- ADD p = mgr.addVar(0);
- ADD q = mgr.addVar(1);
- // Test arithmetic operators.
- ADD r = p + q;
- if (verbosity) cout << "r"; r.print(2,verbosity);
- // CUDD_VALUE_TYPE is double.
- ADD s = mgr.constant(3.0);
- s *= p * q;
- if (verbosity) cout << "s"; s.print(2,verbosity);
- s += mgr.plusInfinity();
- if (verbosity) cout << "s"; s.print(2,verbosity);
- // Test relational operators.
- if (verbosity)
- cout << "p is" << (p <= r ? "" : " not") << " less than or equal to r\n";
- // Test logical operators.
- r = p | q;
- if (verbosity) cout << "r"; r.print(2,verbosity);
- } // testAdd
- /**
- @brief Test some more operators on ADDs.
- @details The function returns void because it relies on the error
- handling done by the interface. The default error handler causes
- program termination.
- @sideeffect May create ADD variables in the manager.
- @see testAdd
- */
- static void
- testAdd2(
- Cudd& mgr,
- int verbosity)
- {
- if (verbosity) cout << "Entering testAdd2\n";
- // Create two ADD variables. If we called method addVar without an
- // argument, we would get two new indices.
- vector<ADD> x(2);
- for (size_t i = 0; i < 2; ++i) {
- x[i] = mgr.addVar((int) i);
- }
- // Build a probability density function: [0.1, 0.2, 0.3, 0.4].
- ADD f0 = x[1].Ite(mgr.constant(0.2), mgr.constant(0.1));
- ADD f1 = x[1].Ite(mgr.constant(0.4), mgr.constant(0.3));
- ADD f = x[0].Ite(f1, f0);
- if (verbosity) cout << "f"; f.print(2,verbosity);
- // Compute the entropy.
- ADD l = f.Log();
- if (verbosity) cout << "l"; l.print(2,verbosity);
- ADD r = f * l;
- if (verbosity) cout << "r"; r.print(2,verbosity);
- ADD e = r.MatrixMultiply(mgr.constant(-1.0/log(2.0)),x);
- if (verbosity) cout << "e"; e.print(2,verbosity);
- } // testAdd2
- /**
- @brief Test basic operators on ZDDs.
- @details The function returns void because it relies on the error
- handling done by the interface. The default error handler causes
- program termination.
- @sideeffect May create ZDD variables in the manager.
- @see testZdd2
- */
- static void
- testZdd(
- Cudd& mgr,
- int verbosity)
- {
- if (verbosity) cout << "Entering testZdd\n";
- ZDD v = mgr.zddVar(0);
- ZDD w = mgr.zddVar(1);
- ZDD s = v + w;
- if (verbosity) cout << "s"; s.print(2,verbosity);
- if (verbosity) cout << "v is" << (v < s ? "" : " not") << " less than s\n";
- s -= v;
- if (verbosity) cout << "s"; s.print(2,verbosity);
- } // testZdd
- /**
- @brief Test vector operators on BDDs.
- @details The function returns void because it relies on the error
- handling done by the interface. The default error handler causes
- program termination.
- @sideeffect May create BDD variables in the manager.
- @see testBdd testBdd3 testBdd4 testBdd5
- */
- static void
- testBdd2(
- Cudd& mgr,
- int verbosity)
- {
- if (verbosity) cout << "Entering testBdd2\n";
- vector<BDD> x(4);
- for (size_t i = 0; i < 4; ++i) {
- x[i] = mgr.bddVar((int) i);
- }
- // Create the BDD for the Achilles' Heel function.
- BDD p1 = x[0] * x[2];
- BDD p2 = x[1] * x[3];
- BDD f = p1 + p2;
- const char* inames[] = {"x0", "x1", "x2", "x3"};
- if (verbosity) {
- cout << "f"; f.print(4,verbosity);
- cout << "Irredundant cover of f:" << endl; f.PrintCover();
- cout << "Number of minterms (arbitrary precision): "; f.ApaPrintMinterm(4);
- cout << "Number of minterms (extended precision): "; f.EpdPrintMinterm(4);
- cout << "Two-literal clauses of f:" << endl;
- f.PrintTwoLiteralClauses((char **)inames); cout << endl;
- }
- vector<BDD> vect = f.CharToVect();
- if (verbosity) {
- for (size_t i = 0; i < vect.size(); i++) {
- cout << "vect[" << i << "]" << endl; vect[i].PrintCover();
- }
- }
- // v0,...,v3 suffice if testBdd2 is called before testBdd3.
- if (verbosity) {
- const char* onames[] = {"v0", "v1", "v2", "v3", "v4", "v5"};
- mgr.DumpDot(vect, (char **)inames,(char **)onames);
- }
- } // testBdd2
- /**
- @brief Test additional operators on BDDs.
- @details The function returns void because it relies on the error
- handling done by the interface. The default error handler causes
- program termination.
- @sideeffect May create BDD variables in the manager.
- @see testBdd testBdd2 testBdd4 testBdd5
- */
- static void
- testBdd3(
- Cudd& mgr,
- int verbosity)
- {
- if (verbosity) cout << "Entering testBdd3\n";
- vector<BDD> x(6);
- for (size_t i = 0; i < 6; ++i) {
- x[i] = mgr.bddVar((int) i);
- }
- BDD G = x[4] + !x[5];
- BDD H = x[4] * x[5];
- BDD E = x[3].Ite(G,!x[5]);
- BDD F = x[3] + !H;
- BDD D = x[2].Ite(F,!H);
- BDD C = x[2].Ite(E,!F);
- BDD B = x[1].Ite(C,!F);
- BDD A = x[0].Ite(B,!D);
- BDD f = !A;
- if (verbosity) cout << "f"; f.print(6,verbosity);
- BDD f1 = f.RemapUnderApprox(6);
- if (verbosity) cout << "f1"; f1.print(6,verbosity);
- if (verbosity)
- cout << "f1 is" << (f1 <= f ? "" : " not") << " less than or equal to f\n";
- BDD g;
- BDD h;
- f.GenConjDecomp(&g,&h);
- if (verbosity) {
- cout << "g"; g.print(6,verbosity);
- cout << "h"; h.print(6,verbosity);
- cout << "g * h " << (g * h == f ? "==" : "!=") << " f\n";
- }
- } // testBdd3
- /**
- @brief Test cover manipulation with BDDs and ZDDs.
- @details The function returns void because it relies on the error
- handling done by the interface. The default error handler causes
- program termination. This function builds the BDDs for a
- transformed adder: one in which the inputs are transformations of
- the original inputs. It then creates ZDDs for the covers from the
- BDDs.
- @sideeffect May create BDD and ZDD variables in the manager.
- @see testZdd
- */
- static void
- testZdd2(
- Cudd& mgr,
- int verbosity)
- {
- if (verbosity) cout << "Entering testZdd2\n";
- size_t N = 3; // number of bits
- // Create variables.
- vector<BDD> a(N);
- vector<BDD> b(N);
- vector<BDD> c(N+1);
- for (size_t i = 0; i < N; ++i) {
- a[N-1-i] = mgr.bddVar(2*(int)i);
- b[N-1-i] = mgr.bddVar(2*(int)i+1);
- }
- c[0] = mgr.bddVar(2*(int)N);
- // Build functions.
- vector<BDD> s(N);
- for (size_t i = 0; i < N; ++i) {
- s[i] = a[i].Xnor(c[i]);
- c[i+1] = a[i].Ite(b[i],c[i]);
- }
- // Create array of outputs and print it.
- vector<BDD> p(N+1);
- for (size_t i = 0; i < N; ++i) {
- p[i] = s[i];
- }
- p[N] = c[N];
- if (verbosity) {
- for (size_t i = 0; i < p.size(); ++i) {
- cout << "p[" << i << "]"; p[i].print(2*(int)N+1,verbosity);
- }
- }
- const char* onames[] = {"s0", "s1", "s2", "c3"};
- if (verbosity) {
- const char* inames[] = {"a2", "b2", "a1", "b1", "a0", "b0", "c0"};
- mgr.DumpDot(p, (char **)inames,(char **)onames);
- }
- // Create ZDD variables and build ZDD covers from BDDs.
- mgr.zddVarsFromBddVars(2);
- vector<ZDD> z(N+1);
- for (size_t i = 0; i < N+1; ++i) {
- ZDD temp;
- BDD dummy = p[i].zddIsop(p[i],&temp);
- z[i] = temp;
- }
- // Print out covers.
- if (verbosity) {
- DdGen *gen;
- int *path;
- for (size_t i = 0; i < z.size(); i++) {
- cout << "z[" << i << "]"; z[i].print(4*(int)N+2,verbosity);
- }
- // Print cover in two different ways: with PrintCover and with
- // enumeration over the paths. The only difference should be
- // a reversal in the order of the cubes.
- for (size_t i = 0; i < z.size(); i++) {
- cout << "z[" << i << "]\n"; z[i].PrintCover();
- cout << "z[" << i << "]\n";
- DdNode *f = Cudd_Not(z[i].getNode());
- Cudd_zddForeachPath(z[i].manager(), f, gen, path) {
- for (size_t q = 0; q < 4*N+2; q += 2) {
- int v = path[q] * 4 + path[q+1];
- switch (v) {
- case 0:
- case 2:
- case 8:
- case 10:
- cout << "-";
- break;
- case 1:
- case 9:
- cout << "0";
- break;
- case 6:
- cout << "1";
- break;
- default:
- cout << "?";
- }
- }
- cout << " 1\n";
- }
- }
- const char* znames[] = {"a2+", "a2-", "b2+", "b2-", "a1+", "a1-", "b1+",
- "b1-", "a0+", "a0-", "b0+", "b0-", "c0+", "c0-"};
- mgr.DumpDot(z, (char **)znames,(char **)onames);
- }
- } // testZdd2
- /**
- @brief Test transfer between BDD managers.
- @details The function returns void because it relies on the error
- handling done by the interface. The default error handler causes
- program termination.
- @sideeffect May create BDD variables in the manager.
- @see testBdd testBdd2 testBdd3 testBdd5
- */
- static void
- testBdd4(
- Cudd& mgr,
- int verbosity)
- {
- if (verbosity) cout << "Entering testBdd4\n";
- BDD x = mgr.bddVar(0);
- BDD y = mgr.bddVar(1);
- BDD z = mgr.bddVar(2);
- BDD f = (~x & ~y & ~z) | (x & y);
- if (verbosity) cout << "f"; f.print(3,verbosity);
- Cudd otherMgr(0,0);
- BDD g = f.Transfer(otherMgr);
- if (verbosity) cout << "g"; g.print(3,verbosity);
- BDD h = g.Transfer(mgr);
- if (verbosity)
- cout << "f and h are" << (f == h ? "" : " not") << " identical\n";
- } // testBdd4
- /**
- @brief Test maximal expansion of cubes.
- @details The function returns void because it relies on the error
- handling done by the interface. The default error handler causes
- program termination.
- @sideeffect May create BDD variables in the manager.
- @see testBdd testBdd2 testBdd3 testBdd4
- */
- static void
- testBdd5(
- Cudd& mgr,
- int verbosity)
- {
- if (verbosity) cout << "Entering testBdd5\n";
- vector<BDD> x;
- x.reserve(4);
- for (int i = 0; i < 4; i++) {
- x.push_back(mgr.bddVar(i));
- }
- const char* inames[] = {"a", "b", "c", "d"};
- BDD f = (x[1] & x[3]) | (x[0] & ~x[2] & x[3]) | (~x[0] & x[1] & ~x[2]);
- BDD lb = x[1] & ~x[2] & x[3];
- BDD ub = x[3];
- BDD primes = lb.MaximallyExpand(ub,f);
- assert(primes == (x[1] & x[3]));
- BDD lprime = primes.LargestPrimeUnate(lb);
- assert(lprime == primes);
- if (verbosity) {
- const char * onames[] = {"lb", "ub", "f", "primes", "lprime"};
- vector<BDD> z;
- z.reserve(5);
- z.push_back(lb);
- z.push_back(ub);
- z.push_back(f);
- z.push_back(primes);
- z.push_back(lprime);
- mgr.DumpDot(z, (char **)inames, (char **)onames);
- cout << "primes(1)"; primes.print(4,verbosity);
- }
- lb = ~x[0] & x[2] & x[3];
- primes = lb.MaximallyExpand(ub,f);
- assert(primes == mgr.bddZero());
- if (verbosity) {
- cout << "primes(2)"; primes.print(4,verbosity);
- }
- lb = x[0] & ~x[2] & x[3];
- primes = lb.MaximallyExpand(ub,f);
- assert(primes == lb);
- lprime = primes.LargestPrimeUnate(lb);
- assert(lprime == primes);
- if (verbosity) {
- cout << "primes(3)"; primes.print(4,verbosity);
- }
- lb = ~x[0] & x[1] & ~x[2] & x[3];
- ub = mgr.bddOne();
- primes = lb.MaximallyExpand(ub,f);
- assert(primes == ((x[1] & x[3]) | (~x[0] & x[1] & ~x[2])));
- lprime = primes.LargestPrimeUnate(lb);
- assert(lprime == (x[1] & x[3]));
- if (verbosity) {
- cout << "primes(4)"; primes.print(4,1); primes.PrintCover();
- }
- ub = ~x[0] & x[3];
- primes = lb.MaximallyExpand(ub,f);
- assert(primes == (~x[0] & x[1] & x[3]));
- lprime = primes.LargestPrimeUnate(lb);
- assert(lprime == primes);
- if (verbosity) {
- cout << "primes(5)"; primes.print(4,verbosity);
- }
- } // testBdd5
- /**
- @brief Test BDD interpolation.
- */
- static void
- testInterpolation(
- Cudd& mgr,
- int verbosity)
- {
- BDD a = mgr.bddVar(0);
- BDD b = mgr.bddVar(1);
- BDD c = mgr.bddVar(2);
- BDD d = mgr.bddVar(3);
- BDD l1 = (a | d) & b & c;
- BDD u1 = (~a & ~b & ~c) | ((a | b) & c);
- BDD ip1 = l1.Interpolate(u1);
- if (verbosity) {
- cout << "l1"; l1.print(4,verbosity);
- cout << "u1"; u1.print(4,verbosity);
- cout << "interpolant1"; ip1.print(4,verbosity);
- }
- BDD l2 = (~a | ~b) & (a | c) & (b | c) & (a | ~b | ~d);
- BDD u2 = (~b & ~d) | (~b & c & d) | (b & c & ~d);
- BDD ip2 = l2.Interpolate(u2);
- if (verbosity) {
- cout << "l2"; l2.print(4,verbosity);
- cout << "u2"; u2.print(4,verbosity);
- cout << "interpolant2"; ip2.print(4,verbosity);
- }
- BDD l3 = ~a & ~b & d;
- BDD u3 = ~b & d;
- BDD ip3 = l3.Interpolate(u3);
- if (verbosity) {
- cout << "l3"; l3.print(4,verbosity);
- cout << "u3"; u3.print(4,verbosity);
- cout << "interpolant3"; ip3.print(4,verbosity);
- }
- } // testInterpolation
- /**
- @brief Basic test of error handling.
- @details This function also illustrates the use of the overloading of the
- stream insertion operator (operator<<) for BDDs.
- */
- static void
- testErrorHandling(
- Cudd& mgr,
- int verbosity)
- {
- // Setup.
- if (verbosity) cout << "Entering testErrorHandling\n";
- FILE *savefp = 0;
- if (verbosity == 0) {
- // Suppress error messages coming from CUDD.
- savefp = mgr.ReadStderr();
- #ifndef _WIN32
- FILE * devnull = fopen("/dev/null", "w");
- #else
- FILE * devnull = fopen("NUL", "w");
- #endif
- if (devnull)
- mgr.SetStderr(devnull);
- }
- size_t const N = 60;
- vector<BDD> vars;
- vars.reserve(N);
- for (size_t i = 0; i < N; ++i) {
- vars.push_back(mgr.bddVar((int) i));
- }
- // It is necessary to give names to all the BDD variables in the manager
- // for the names to be used by operator<<.
- for (int i = 0; i < mgr.ReadSize(); ++i) {
- ostringstream os;
- os << "var[" << i << "]";
- mgr.pushVariableName(os.str());
- }
- // Tests.
- // Trying to print the expression of an empty BDD.
- try {
- BDD empty;
- if (verbosity > 0)
- cout << "Oops! ";
- cout << empty << endl;
- } catch (logic_error const & e) {
- if (verbosity > 0)
- cerr << "Caught: " << e.what() << endl;
- }
- // Trying to extract a minterm from the zero BDD.
- try {
- BDD zero = mgr.bddZero();
- BDD minterm = zero.PickOneMinterm(vars);
- } catch (logic_error const & e) {
- if (verbosity > 0)
- cerr << "Caught: " << e.what() << endl;
- mgr.ClearErrorCode();
- }
- // Passing a non-cube second argument to Cofactor.
- try {
- BDD f = vars.at(1) | (vars.at(2) & vars.at(3));
- if (verbosity > 0)
- cout << "f = " << f << endl;
- BDD notAcube = vars.at(0) | vars.at(1);
- if (verbosity > 0)
- cout << notAcube << " is not a cube" << endl;
- BDD fc = f.Cofactor(notAcube);
- if (verbosity > 0) {
- cout << "The cofactor is: "; fc.summary(3);
- }
- } catch (logic_error const & e) {
- if (verbosity > 0)
- cerr << "Caught: " << e.what() << endl;
- mgr.ClearErrorCode();
- }
- #if 0
- // This attempt to allocate over 100 GB may succeed on machines with
- // enough memory; hence we exclude it from "make check."
- // Failing malloc.
- // Don't let the memory manager kill the program if malloc fails.
- DD_OOMFP saveHandler = mgr.InstallOutOfMemoryHandler(Cudd_OutOfMemSilent);
- try {
- mgr.Reserve(2000000000);
- } catch (logic_error const & e) {
- if (verbosity > 0)
- cerr << "Caught: " << e.what() << endl;
- mgr.ClearErrorCode();
- }
- (void) mgr.InstallOutOfMemoryHandler(saveHandler);
- #endif
- // Forgetting to check for empty result when setting a limit on
- // the number of new nodes.
- try {
- BDD f = mgr.bddOne();
- BDD g = f;
- for (size_t i = 0; i < N/2; i += 4) {
- f &= vars.at(i) | vars.at(i+N/2);
- g &= vars.at(i+1) | vars.at(i+N/2+1);
- }
- if (verbosity > 0) {
- cout << "f "; f.summary(N);
- cout << "g "; g.summary(N);
- }
- BDD h = f.And(g, /* max new nodes */ 1);
- if (verbosity > 0) {
- cout << "h "; h.summary(N);
- }
- } catch (logic_error const & e) {
- if (verbosity > 0)
- cerr << "Caught: " << e.what() << endl;
- mgr.ClearErrorCode();
- }
- // Using more memory than the set limit.
- size_t saveLimit = mgr.SetMaxMemory((size_t) 1);
- try {
- // The limit is ridiculously low (1 byte), but CUDD is resourceful.
- // Therefore we can still create a few BDDs.
- BDD f = mgr.Interval(vars, 122346345U, 348353453U);
- if (verbosity > 0) {
- cout << "f "; f.summary(N);
- }
- BDD g = mgr.Interval(vars, 34234U, 3143534534U);
- if (verbosity > 0) {
- cout << "g "; g.summary(N);
- }
- BDD h = f ^ g;
- if (verbosity > 0) {
- cout << "h "; h.summary(N);
- }
- // But if we really insist...
- BDD extra = mgr.bddVar(60000);
- // Here we would have to fix the variable names.
- } catch (logic_error const & e) {
- if (verbosity > 0)
- cerr << "Caught: " << e.what() << endl;
- mgr.ClearErrorCode();
- }
- (void) mgr.SetMaxMemory(saveLimit);
- // Timing out.
- unsigned long saveTl = mgr.SetTimeLimit(1UL); // 1 ms
- try {
- BDD f = mgr.bddOne();
- for (size_t i = 0; i < N/2; ++i) {
- f &= vars.at(i) | vars.at(i+N/2);
- }
- } catch (logic_error const & e) {
- if (verbosity > 0)
- cerr << "Caught: " << e.what() << endl;
- mgr.ClearErrorCode();
- }
- (void) mgr.SetTimeLimit(saveTl);
- // Let's clean up after ourselves.
- mgr.clearVariableNames();
- if (verbosity == 0) {
- mgr.SetStderr(savefp);
- }
- } // testErrorHandling
|