/*======================================================================== Copyright (C) 1996-2002 by Jorn Lind-Nielsen All rights reserved Permission is hereby granted, without written agreement and without license or royalty fees, to use, reproduce, prepare derivative works, distribute, and display this software and its documentation for any purpose, provided that (1) the above copyright notice and the following two paragraphs appear in all copies of the source code and (2) redistributions, including without limitation binaries, reproduce these notices in the supporting documentation. Substantial modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here, provided that the new terms are clearly indicated in all files where they apply. IN NO EVENT SHALL JORN LIND-NIELSEN, OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. JORN LIND-NIELSEN SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. ========================================================================*/ /************************************************************************* $Header: /cvsroot/buddy/buddy/src/cppext.cxx,v 1.1.1.1 2004/06/25 13:22:39 haimcohen Exp $ FILE: cppext.cxx DESCR: C++ extension of BDD package AUTH: Jorn Lind DATE: (C) august 1997 *************************************************************************/ #include #include #include #include "kernel.h" #include "bvec.h" using namespace std; /* Formatting objects for iostreams */ #define IOFORMAT_SET 0 #define IOFORMAT_TABLE 1 #define IOFORMAT_DOT 2 #define IOFORMAT_ALL 3 #define IOFORMAT_FDDSET 4 int bdd_ioformat::curformat = IOFORMAT_SET; bdd_ioformat bddset(IOFORMAT_SET); bdd_ioformat bddtable(IOFORMAT_TABLE); bdd_ioformat bdddot(IOFORMAT_DOT); bdd_ioformat bddall(IOFORMAT_ALL); bdd_ioformat fddset(IOFORMAT_FDDSET); /* Constant true and false extension */ const bdd bddtruepp = bdd_true(); const bdd bddfalsepp = bdd_false(); /* Internal prototypes */ static void bdd_printset_rec(ostream&, int, int*); static void bdd_printdot_rec(ostream&, int); static void fdd_printset_rec(ostream &, int, int *); static bddstrmhandler strmhandler_bdd; static bddstrmhandler strmhandler_fdd; // Avoid calling C++ version of anodecount #undef bdd_anodecount /************************************************************************* Setup (and shutdown) *************************************************************************/ #undef bdd_init int bdd_cpp_init(int n, int c) { int ok = bdd_init(n,c); strmhandler_bdd = NULL; strmhandler_fdd = NULL; return ok; } /************************************************************************* BDD C++ functions *************************************************************************/ bdd bdd_buildcube(int val, int width, const bdd *variables) { BDD *var = NEW(BDD,width); BDD res; int n; // No need for ref.cou. since variables[n] holds the reference for (n=0 ; n 0) { if (!first) o << ", "; first = 0; if (strmhandler_bdd) strmhandler_bdd(o,bddlevel2var[n]); else o << bddlevel2var[n]; o << ":" << (set[n]==2 ? 1 : 0); } } o << ">"; } else { set[LEVEL(r)] = 1; bdd_printset_rec(o, LOW(r), set); set[LEVEL(r)] = 2; bdd_printset_rec(o, HIGH(r), set); set[LEVEL(r)] = 0; } } static void bdd_printdot_rec(ostream& o, int r) { if (ISCONST(r) || MARKED(r)) return; o << r << "[label=\""; if (strmhandler_bdd) strmhandler_bdd(o,bddlevel2var[LEVEL(r)]); else o << bddlevel2var[LEVEL(r)]; o << "\"];\n"; o << r << " -> " << LOW(r) << "[style=dotted];\n"; o << r << " -> " << HIGH(r) << "[style=filled];\n"; SETMARK(r); bdd_printdot_rec(o, LOW(r)); bdd_printdot_rec(o, HIGH(r)); } static void fdd_printset_rec(ostream &o, int r, int *set) { int n,m,i; int used = 0; int *binval; int ok, first; if (r == 0) return; else if (r == 1) { o << "<"; first=1; int fdvarnum = fdd_domainnum(); for (n=0 ; n"; } else { set[bddlevel2var[LEVEL(r)]] = 1; fdd_printset_rec(o, LOW(r), set); set[bddlevel2var[LEVEL(r)]] = 2; fdd_printset_rec(o, HIGH(r), set); set[bddlevel2var[LEVEL(r)]] = 0; } } /*=[ FDD I/O functions ]================================================*/ /* NAME {* fdd\_strm\_hook *} SECTION {* fdd *} SHORT {* Specifies a printing callback handler *} PROTO {* bddstrmhandler fdd_strm_hook(bddstrmhandler handler) *} DESCR {* A printing callback handler for use with FDDs is used to convert the FDD integer identifier into something readable by the end user. Typically the handler will print a string name instead of the identifier. A handler could look like this: \begin{verbatim} void printhandler(ostream &o, int var) { extern char **names; o << names[var]; } \end{verbatim} \noindent The handler can then be passed to BuDDy like this: {\tt fdd\_strm\_hook(printhandler)}. No default handler is supplied. The argument {\tt handler} may be NULL if no handler is needed. *} RETURN {* The old handler *} ALSO {* fdd\_printset, bdd\_file\_hook *} */ bddstrmhandler fdd_strm_hook(bddstrmhandler handler) { bddstrmhandler old = strmhandler_fdd; strmhandler_fdd = handler; return old; } /************************************************************************* bvec functions *************************************************************************/ bvec bvec::operator=(const bvec &src) { if (&src != this) { bvec_free(roots); roots = bvec_copy(src.roots); } return *this; } void bvec::set(int bitnum, const bdd &b) { bdd_delref(roots.bitvec[bitnum]); roots.bitvec[bitnum] = b.root; bdd_addref(roots.bitvec[bitnum]); } /*======================================================================*/ bvec bvec_map1(const bvec &a, bdd (*fun)(const bdd &)) { bvec res; int n; res = bvec_false(a.bitnum()); for (n=0 ; n < a.bitnum() ; n++) res.set(n, fun(a[n])); return res; } bvec bvec_map2(const bvec &a, const bvec &b, bdd (*fun)(const bdd &, const bdd &)) { bvec res; int n; if (a.bitnum() != b.bitnum()) { bdd_error(BVEC_SIZE); return res; } res = bvec_false(a.bitnum()); for (n=0 ; n < a.bitnum() ; n++) res.set(n, fun(a[n], b[n])); return res; } bvec bvec_map3(const bvec &a, const bvec &b, const bvec &c, bdd (*fun)(const bdd &, const bdd &, const bdd &)) { bvec res; int n; if (a.bitnum() != b.bitnum() || b.bitnum() != c.bitnum()) { bdd_error(BVEC_SIZE); return res; } res = bvec_false(a.bitnum()); for (n=0 ; n < a.bitnum() ; n++) res.set(n, fun(a[n], b[n], c[n]) ); return res; } ostream &operator<<(ostream &o, const bvec &v) { for (int i=0 ; i