mirror of https://github.com/YosysHQ/abc.git
Upgrade to the latest CUDD 2.4.2.
This commit is contained in:
parent
d99de60e6c
commit
e7b544f111
|
|
@ -0,0 +1,68 @@
|
|||
M src\bdd\cudd\cudd.h
|
||||
M src\bdd\cudd\cuddAPI.c
|
||||
M src\bdd\cudd\cuddAddAbs.c
|
||||
M src\bdd\cudd\cuddAddApply.c
|
||||
M src\bdd\cudd\cuddAddFind.c
|
||||
M src\bdd\cudd\cuddAddInv.c
|
||||
M src\bdd\cudd\cuddAddIte.c
|
||||
M src\bdd\cudd\cuddAddNeg.c
|
||||
M src\bdd\cudd\cuddAddWalsh.c
|
||||
M src\bdd\cudd\cuddAndAbs.c
|
||||
M src\bdd\cudd\cuddAnneal.c
|
||||
M src\bdd\cudd\cuddApa.c
|
||||
M src\bdd\cudd\cuddApprox.c
|
||||
M src\bdd\cudd\cuddBddAbs.c
|
||||
M src\bdd\cudd\cuddBddCorr.c
|
||||
M src\bdd\cudd\cuddBddIte.c
|
||||
M src\bdd\cudd\cuddBridge.c
|
||||
M src\bdd\cudd\cuddCache.c
|
||||
M src\bdd\cudd\cuddCheck.c
|
||||
M src\bdd\cudd\cuddClip.c
|
||||
M src\bdd\cudd\cuddCof.c
|
||||
M src\bdd\cudd\cuddCompose.c
|
||||
M src\bdd\cudd\cuddDecomp.c
|
||||
M src\bdd\cudd\cuddEssent.c
|
||||
M src\bdd\cudd\cuddExact.c
|
||||
M src\bdd\cudd\cuddExport.c
|
||||
M src\bdd\cudd\cuddGenCof.c
|
||||
M src\bdd\cudd\cuddGenetic.c
|
||||
M src\bdd\cudd\cuddGroup.c
|
||||
M src\bdd\cudd\cuddHarwell.c
|
||||
M src\bdd\cudd\cuddInit.c
|
||||
M src\bdd\cudd\cuddInt.h
|
||||
M src\bdd\cudd\cuddInteract.c
|
||||
M src\bdd\cudd\cuddLCache.c
|
||||
M src\bdd\cudd\cuddLevelQ.c
|
||||
M src\bdd\cudd\cuddLinear.c
|
||||
M src\bdd\cudd\cuddLiteral.c
|
||||
M src\bdd\cudd\cuddMatMult.c
|
||||
M src\bdd\cudd\cuddPriority.c
|
||||
M src\bdd\cudd\cuddRead.c
|
||||
M src\bdd\cudd\cuddRef.c
|
||||
M src\bdd\cudd\cuddReorder.c
|
||||
M src\bdd\cudd\cuddSat.c
|
||||
M src\bdd\cudd\cuddSign.c
|
||||
M src\bdd\cudd\cuddSolve.c
|
||||
M src\bdd\cudd\cuddSplit.c
|
||||
M src\bdd\cudd\cuddSubsetHB.c
|
||||
M src\bdd\cudd\cuddSubsetSP.c
|
||||
M src\bdd\cudd\cuddSymmetry.c
|
||||
M src\bdd\cudd\cuddTable.c
|
||||
M src\bdd\cudd\cuddUtil.c
|
||||
M src\bdd\cudd\cuddWindow.c
|
||||
M src\bdd\cudd\cuddZddCount.c
|
||||
M src\bdd\cudd\cuddZddFuncs.c
|
||||
M src\bdd\cudd\cuddZddGroup.c
|
||||
M src\bdd\cudd\cuddZddIsop.c
|
||||
M src\bdd\cudd\cuddZddLin.c
|
||||
M src\bdd\cudd\cuddZddMisc.c
|
||||
M src\bdd\cudd\cuddZddPort.c
|
||||
M src\bdd\cudd\cuddZddReord.c
|
||||
M src\bdd\cudd\cuddZddSetop.c
|
||||
M src\bdd\cudd\cuddZddSymm.c
|
||||
M src\bdd\cudd\cuddZddUtil.c
|
||||
M src\bdd\cudd\r7x8.1.mat
|
||||
M src\bdd\cudd\testcudd.c
|
||||
? 1.txt
|
||||
? src\bdd\cudd\Makefile
|
||||
? src\bdd\cudd\r7x8.1.out
|
||||
|
|
@ -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
|
||||
1001
src/bdd/cudd/cudd.h
1001
src/bdd/cudd/cudd.h
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -7,37 +7,65 @@
|
|||
Synopsis [Quantification functions for ADDs.]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_addExistAbstract()
|
||||
<li> Cudd_addUnivAbstract()
|
||||
<li> Cudd_addOrAbstract()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddAddExistAbstractRecur()
|
||||
<li> cuddAddUnivAbstractRecur()
|
||||
<li> cuddAddOrAbstractRecur()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> addCheckPositiveCube()
|
||||
</ul>]
|
||||
<ul>
|
||||
<li> Cudd_addExistAbstract()
|
||||
<li> Cudd_addUnivAbstract()
|
||||
<li> Cudd_addOrAbstract()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddAddExistAbstractRecur()
|
||||
<li> cuddAddUnivAbstractRecur()
|
||||
<li> cuddAddOrAbstractRecur()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> addCheckPositiveCube()
|
||||
</ul>]
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -58,10 +86,10 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddAddAbs.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddAddAbs.c,v 1.15 2004/08/13 18:04:45 fabio Exp $";
|
||||
#endif
|
||||
|
||||
static DdNode *two;
|
||||
static DdNode *two;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Macro declarations */
|
||||
|
|
@ -74,7 +102,7 @@ static DdNode *two;
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static int addCheckPositiveCube ARGS((DdManager *manager, DdNode *cube));
|
||||
static int addCheckPositiveCube (DdManager *manager, DdNode *cube);
|
||||
|
||||
/**AutomaticEnd***************************************************************/
|
||||
|
||||
|
|
@ -115,13 +143,13 @@ Cudd_addExistAbstract(
|
|||
}
|
||||
|
||||
do {
|
||||
manager->reordered = 0;
|
||||
res = cuddAddExistAbstractRecur(manager, f, cube);
|
||||
manager->reordered = 0;
|
||||
res = cuddAddExistAbstractRecur(manager, f, cube);
|
||||
} while (manager->reordered == 1);
|
||||
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDeref(manager,two);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(manager,two);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDeref(manager,two);
|
||||
|
|
@ -152,16 +180,16 @@ Cudd_addUnivAbstract(
|
|||
DdNode * f,
|
||||
DdNode * cube)
|
||||
{
|
||||
DdNode *res;
|
||||
DdNode *res;
|
||||
|
||||
if (addCheckPositiveCube(manager, cube) == 0) {
|
||||
(void) fprintf(manager->err,"Error: Can only abstract cubes");
|
||||
return(NULL);
|
||||
(void) fprintf(manager->err,"Error: Can only abstract cubes");
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
do {
|
||||
manager->reordered = 0;
|
||||
res = cuddAddUnivAbstractRecur(manager, f, cube);
|
||||
manager->reordered = 0;
|
||||
res = cuddAddUnivAbstractRecur(manager, f, cube);
|
||||
} while (manager->reordered == 1);
|
||||
|
||||
return(res);
|
||||
|
|
@ -198,8 +226,8 @@ Cudd_addOrAbstract(
|
|||
}
|
||||
|
||||
do {
|
||||
manager->reordered = 0;
|
||||
res = cuddAddOrAbstractRecur(manager, f, cube);
|
||||
manager->reordered = 0;
|
||||
res = cuddAddOrAbstractRecur(manager, f, cube);
|
||||
} while (manager->reordered == 1);
|
||||
return(res);
|
||||
|
||||
|
|
@ -230,38 +258,38 @@ cuddAddExistAbstractRecur(
|
|||
DdNode * f,
|
||||
DdNode * cube)
|
||||
{
|
||||
DdNode *T, *E, *res, *res1, *res2, *zero;
|
||||
DdNode *T, *E, *res, *res1, *res2, *zero;
|
||||
|
||||
statLine(manager);
|
||||
zero = DD_ZERO(manager);
|
||||
|
||||
/* Cube is guaranteed to be a cube at this point. */
|
||||
/* 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) {
|
||||
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);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDeref(manager,res1);
|
||||
cuddDeref(res);
|
||||
cuddDeref(res);
|
||||
return(res);
|
||||
}
|
||||
|
||||
if ((res = cuddCacheLookup2(manager, Cudd_addExistAbstract, f, cube)) != NULL) {
|
||||
return(res);
|
||||
return(res);
|
||||
}
|
||||
|
||||
T = cuddT(f);
|
||||
|
|
@ -269,49 +297,49 @@ cuddAddExistAbstractRecur(
|
|||
|
||||
/* 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);
|
||||
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);
|
||||
}
|
||||
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) {
|
||||
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);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDeref(manager,res1);
|
||||
Cudd_RecursiveDeref(manager,res2);
|
||||
cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res);
|
||||
cuddDeref(res);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
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 */
|
||||
|
||||
|
|
@ -335,7 +363,7 @@ cuddAddUnivAbstractRecur(
|
|||
DdNode * f,
|
||||
DdNode * cube)
|
||||
{
|
||||
DdNode *T, *E, *res, *res1, *res2, *one, *zero;
|
||||
DdNode *T, *E, *res, *res1, *res2, *one, *zero;
|
||||
|
||||
statLine(manager);
|
||||
one = DD_ONE(manager);
|
||||
|
|
@ -345,31 +373,31 @@ cuddAddUnivAbstractRecur(
|
|||
** zero and one are the only constatnts c such that c*c=c.
|
||||
*/
|
||||
if (f == zero || f == one || cube == one) {
|
||||
return(f);
|
||||
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) {
|
||||
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);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDeref(manager,res1);
|
||||
cuddDeref(res);
|
||||
return(res);
|
||||
cuddDeref(res);
|
||||
return(res);
|
||||
}
|
||||
|
||||
if ((res = cuddCacheLookup2(manager, Cudd_addUnivAbstract, f, cube)) != NULL) {
|
||||
return(res);
|
||||
return(res);
|
||||
}
|
||||
|
||||
T = cuddT(f);
|
||||
|
|
@ -377,47 +405,47 @@ cuddAddUnivAbstractRecur(
|
|||
|
||||
/* 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);
|
||||
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);
|
||||
}
|
||||
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) {
|
||||
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);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDeref(manager,res1);
|
||||
Cudd_RecursiveDeref(manager,res2);
|
||||
cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res);
|
||||
cuddDeref(res);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -443,38 +471,24 @@ cuddAddOrAbstractRecur(
|
|||
DdNode * f,
|
||||
DdNode * cube)
|
||||
{
|
||||
DdNode *T, *E, *res, *res1, *res2, *one;
|
||||
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);
|
||||
return(f);
|
||||
}
|
||||
|
||||
/* Abstract a variable that does not appear in f. */
|
||||
if (cuddI(manager,f->index) > cuddI(manager,cube->index)) {
|
||||
res1 = cuddAddOrAbstractRecur(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_addOr, res1, res1);
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDeref(manager,res1);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDeref(manager,res1);
|
||||
cuddDeref(res);
|
||||
return(res);
|
||||
res = cuddAddOrAbstractRecur(manager, f, cuddT(cube));
|
||||
return(res);
|
||||
}
|
||||
|
||||
if ((res = cuddCacheLookup2(manager, Cudd_addOrAbstract, f, cube)) != NULL) {
|
||||
return(res);
|
||||
return(res);
|
||||
}
|
||||
|
||||
T = cuddT(f);
|
||||
|
|
@ -482,51 +496,51 @@ cuddAddOrAbstractRecur(
|
|||
|
||||
/* 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);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -567,5 +581,8 @@ addCheckPositiveCube(
|
|||
|
||||
} /* end of addCheckPositiveCube */
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,47 +7,75 @@
|
|||
Synopsis [Apply functions for ADDs and their operators.]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_addApply()
|
||||
<li> Cudd_addMonadicApply()
|
||||
<li> Cudd_addPlus()
|
||||
<li> Cudd_addTimes()
|
||||
<li> Cudd_addThreshold()
|
||||
<li> Cudd_addSetNZ()
|
||||
<li> Cudd_addDivide()
|
||||
<li> Cudd_addMinus()
|
||||
<li> Cudd_addMinimum()
|
||||
<li> Cudd_addMaximum()
|
||||
<li> Cudd_addOneZeroMaximum()
|
||||
<li> Cudd_addDiff()
|
||||
<li> Cudd_addAgreement()
|
||||
<li> Cudd_addOr()
|
||||
<li> Cudd_addNand()
|
||||
<li> Cudd_addNor()
|
||||
<li> Cudd_addXor()
|
||||
<li> Cudd_addXnor()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddAddApplyRecur()
|
||||
<li> cuddAddMonadicApplyRecur()
|
||||
</ul>]
|
||||
<ul>
|
||||
<li> Cudd_addApply()
|
||||
<li> Cudd_addMonadicApply()
|
||||
<li> Cudd_addPlus()
|
||||
<li> Cudd_addTimes()
|
||||
<li> Cudd_addThreshold()
|
||||
<li> Cudd_addSetNZ()
|
||||
<li> Cudd_addDivide()
|
||||
<li> Cudd_addMinus()
|
||||
<li> Cudd_addMinimum()
|
||||
<li> Cudd_addMaximum()
|
||||
<li> Cudd_addOneZeroMaximum()
|
||||
<li> Cudd_addDiff()
|
||||
<li> Cudd_addAgreement()
|
||||
<li> Cudd_addOr()
|
||||
<li> Cudd_addNand()
|
||||
<li> Cudd_addNor()
|
||||
<li> Cudd_addXor()
|
||||
<li> Cudd_addXnor()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddAddApplyRecur()
|
||||
<li> cuddAddMonadicApplyRecur()
|
||||
</ul>]
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at Boulder.
|
||||
The University of Colorado at Boulder makes no warranty about the
|
||||
suitability of this software for any purpose. It is presented on an
|
||||
AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -68,7 +96,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddAddApply.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddAddApply.c,v 1.18 2009/02/19 16:15:26 fabio Exp $";
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -109,15 +137,15 @@ static char rcsid[] DD_UNUSED = "$Id: cuddAddApply.c,v 1.1.1.1 2003/02/24 22:23:
|
|||
DdNode *
|
||||
Cudd_addApply(
|
||||
DdManager * dd,
|
||||
DdNode * (*op)(DdManager *, DdNode **, DdNode **),
|
||||
DD_AOP op,
|
||||
DdNode * f,
|
||||
DdNode * g)
|
||||
{
|
||||
DdNode *res;
|
||||
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = cuddAddApplyRecur(dd,op,f,g);
|
||||
dd->reordered = 0;
|
||||
res = cuddAddApplyRecur(dd,op,f,g);
|
||||
} while (dd->reordered == 1);
|
||||
return(res);
|
||||
|
||||
|
|
@ -150,13 +178,13 @@ Cudd_addPlus(
|
|||
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);
|
||||
value = cuddV(F)+cuddV(G);
|
||||
res = cuddUniqueConst(dd,value);
|
||||
return(res);
|
||||
}
|
||||
if (F > G) { /* swap f and g */
|
||||
*f = G;
|
||||
*g = F;
|
||||
*f = G;
|
||||
*g = F;
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -191,13 +219,13 @@ Cudd_addTimes(
|
|||
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);
|
||||
value = cuddV(F)*cuddV(G);
|
||||
res = cuddUniqueConst(dd,value);
|
||||
return(res);
|
||||
}
|
||||
if (F > G) { /* swap f and g */
|
||||
*f = G;
|
||||
*g = F;
|
||||
*f = G;
|
||||
*g = F;
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -227,11 +255,11 @@ Cudd_addThreshold(
|
|||
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));
|
||||
}
|
||||
if (cuddV(F) >= cuddV(G)) {
|
||||
return(F);
|
||||
} else {
|
||||
return(DD_ZERO(dd));
|
||||
}
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -296,9 +324,9 @@ Cudd_addDivide(
|
|||
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);
|
||||
value = cuddV(F)/cuddV(G);
|
||||
res = cuddUniqueConst(dd,value);
|
||||
return(res);
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -332,9 +360,9 @@ Cudd_addMinus(
|
|||
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);
|
||||
value = cuddV(F)-cuddV(G);
|
||||
res = cuddUniqueConst(dd,value);
|
||||
return(res);
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -371,15 +399,15 @@ Cudd_addMinimum(
|
|||
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 (cuddV(F) <= cuddV(G)) {
|
||||
return(F);
|
||||
} else {
|
||||
return(G);
|
||||
}
|
||||
}
|
||||
if (F > G) { /* swap f and g */
|
||||
*f = G;
|
||||
*g = F;
|
||||
*f = G;
|
||||
*g = F;
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -416,15 +444,15 @@ Cudd_addMaximum(
|
|||
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 (cuddV(F) >= cuddV(G)) {
|
||||
return(F);
|
||||
} else {
|
||||
return(G);
|
||||
}
|
||||
}
|
||||
if (F > G) { /* swap f and g */
|
||||
*f = G;
|
||||
*g = F;
|
||||
*f = G;
|
||||
*g = F;
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -453,13 +481,13 @@ Cudd_addOneZeroMaximum(
|
|||
|
||||
if (*f == *g) return(DD_ZERO(dd));
|
||||
if (*g == DD_PLUS_INFINITY(dd))
|
||||
return DD_ZERO(dd);
|
||||
return DD_ZERO(dd);
|
||||
if (cuddIsConstant(*f) && cuddIsConstant(*g)) {
|
||||
if (cuddV(*f) > cuddV(*g)) {
|
||||
return(DD_ONE(dd));
|
||||
} else {
|
||||
return(DD_ZERO(dd));
|
||||
}
|
||||
if (cuddV(*f) > cuddV(*g)) {
|
||||
return(DD_ONE(dd));
|
||||
} else {
|
||||
return(DD_ZERO(dd));
|
||||
}
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
|
|
@ -492,15 +520,15 @@ Cudd_addDiff(
|
|||
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)) {
|
||||
if (cuddV(F) < cuddV(G)) {
|
||||
return(F);
|
||||
} else {
|
||||
return(G);
|
||||
}
|
||||
} else {
|
||||
return(DD_PLUS_INFINITY(dd));
|
||||
}
|
||||
} else {
|
||||
return(DD_PLUS_INFINITY(dd));
|
||||
}
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -563,8 +591,8 @@ Cudd_addOr(
|
|||
if (cuddIsConstant(G)) return(F);
|
||||
if (F == G) return(F);
|
||||
if (F > G) { /* swap f and g */
|
||||
*f = G;
|
||||
*g = F;
|
||||
*f = G;
|
||||
*g = F;
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -595,8 +623,8 @@ Cudd_addNand(
|
|||
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;
|
||||
*f = G;
|
||||
*g = F;
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -627,8 +655,8 @@ Cudd_addNor(
|
|||
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;
|
||||
*f = G;
|
||||
*g = F;
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -661,8 +689,8 @@ Cudd_addXor(
|
|||
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;
|
||||
*f = G;
|
||||
*g = F;
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -695,8 +723,8 @@ Cudd_addXnor(
|
|||
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;
|
||||
*f = G;
|
||||
*g = F;
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -718,14 +746,14 @@ Cudd_addXnor(
|
|||
DdNode *
|
||||
Cudd_addMonadicApply(
|
||||
DdManager * dd,
|
||||
DdNode * (*op)(DdManager *, DdNode *),
|
||||
DD_MAOP op,
|
||||
DdNode * f)
|
||||
{
|
||||
DdNode *res;
|
||||
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = cuddAddMonadicApplyRecur(dd,op,f);
|
||||
dd->reordered = 0;
|
||||
res = cuddAddMonadicApplyRecur(dd,op,f);
|
||||
} while (dd->reordered == 1);
|
||||
return(res);
|
||||
|
||||
|
|
@ -751,9 +779,9 @@ Cudd_addLog(
|
|||
DdNode * f)
|
||||
{
|
||||
if (cuddIsConstant(f)) {
|
||||
CUDD_VALUE_TYPE value = log(cuddV(f));
|
||||
DdNode *res = cuddUniqueConst(dd,value);
|
||||
return(res);
|
||||
CUDD_VALUE_TYPE value = log(cuddV(f));
|
||||
DdNode *res = cuddUniqueConst(dd,value);
|
||||
return(res);
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -780,16 +808,16 @@ Cudd_addLog(
|
|||
DdNode *
|
||||
cuddAddApplyRecur(
|
||||
DdManager * dd,
|
||||
DdNode * (*op)(DdManager *, DdNode **, DdNode **),
|
||||
DD_AOP op,
|
||||
DdNode * f,
|
||||
DdNode * g)
|
||||
{
|
||||
DdNode *res,
|
||||
*fv, *fvn, *gv, *gvn,
|
||||
*T, *E;
|
||||
*fv, *fvn, *gv, *gvn,
|
||||
*T, *E;
|
||||
unsigned int ford, gord;
|
||||
unsigned int index;
|
||||
DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *);
|
||||
DD_CTFP cacheOp;
|
||||
|
||||
/* Check terminal cases. Op may swap f and g to increase the
|
||||
* cache hit rate.
|
||||
|
|
@ -799,7 +827,7 @@ cuddAddApplyRecur(
|
|||
if (res != NULL) return(res);
|
||||
|
||||
/* Check cache. */
|
||||
cacheOp = (DdNode *(*)(DdManager *, DdNode *, DdNode *)) op;
|
||||
cacheOp = (DD_CTFP) op;
|
||||
res = cuddCacheLookup2(dd,cacheOp,f,g);
|
||||
if (res != NULL) return(res);
|
||||
|
||||
|
|
@ -807,18 +835,18 @@ cuddAddApplyRecur(
|
|||
ford = cuddI(dd,f->index);
|
||||
gord = cuddI(dd,g->index);
|
||||
if (ford <= gord) {
|
||||
index = f->index;
|
||||
fv = cuddT(f);
|
||||
fvn = cuddE(f);
|
||||
index = f->index;
|
||||
fv = cuddT(f);
|
||||
fvn = cuddE(f);
|
||||
} else {
|
||||
index = g->index;
|
||||
fv = fvn = f;
|
||||
index = g->index;
|
||||
fv = fvn = f;
|
||||
}
|
||||
if (gord <= ford) {
|
||||
gv = cuddT(g);
|
||||
gvn = cuddE(g);
|
||||
gv = cuddT(g);
|
||||
gvn = cuddE(g);
|
||||
} else {
|
||||
gv = gvn = g;
|
||||
gv = gvn = g;
|
||||
}
|
||||
|
||||
T = cuddAddApplyRecur(dd,op,fv,gv);
|
||||
|
|
@ -827,16 +855,16 @@ cuddAddApplyRecur(
|
|||
|
||||
E = cuddAddApplyRecur(dd,op,fvn,gvn);
|
||||
if (E == NULL) {
|
||||
Cudd_RecursiveDeref(dd,T);
|
||||
return(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);
|
||||
Cudd_RecursiveDeref(dd, T);
|
||||
Cudd_RecursiveDeref(dd, E);
|
||||
return(NULL);
|
||||
}
|
||||
cuddDeref(T);
|
||||
cuddDeref(E);
|
||||
|
|
@ -864,11 +892,10 @@ cuddAddApplyRecur(
|
|||
DdNode *
|
||||
cuddAddMonadicApplyRecur(
|
||||
DdManager * dd,
|
||||
DdNode * (*op)(DdManager *, DdNode *),
|
||||
DD_MAOP op,
|
||||
DdNode * f)
|
||||
{
|
||||
DdNode *res, *ft, *fe, *T, *E;
|
||||
unsigned int ford;
|
||||
unsigned int index;
|
||||
|
||||
/* Check terminal cases. */
|
||||
|
|
@ -881,7 +908,6 @@ cuddAddMonadicApplyRecur(
|
|||
if (res != NULL) return(res);
|
||||
|
||||
/* Recursive step. */
|
||||
ford = cuddI(dd,f->index);
|
||||
index = f->index;
|
||||
ft = cuddT(f);
|
||||
fe = cuddE(f);
|
||||
|
|
@ -892,16 +918,16 @@ cuddAddMonadicApplyRecur(
|
|||
|
||||
E = cuddAddMonadicApplyRecur(dd,op,fe);
|
||||
if (E == NULL) {
|
||||
Cudd_RecursiveDeref(dd,T);
|
||||
return(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);
|
||||
Cudd_RecursiveDeref(dd, T);
|
||||
Cudd_RecursiveDeref(dd, E);
|
||||
return(NULL);
|
||||
}
|
||||
cuddDeref(T);
|
||||
cuddDeref(E);
|
||||
|
|
@ -918,5 +944,6 @@ cuddAddMonadicApplyRecur(
|
|||
/* Definition of static functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -8,22 +8,49 @@
|
|||
extract the i-th bit.]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_addFindMax()
|
||||
<li> Cudd_addFindMin()
|
||||
<li> Cudd_addIthBit()
|
||||
</ul>
|
||||
Static functions included in this module:
|
||||
<ul>
|
||||
<li> addDoIthBit()
|
||||
</ul>]
|
||||
<ul>
|
||||
<li> Cudd_addFindMax()
|
||||
<li> Cudd_addFindMin()
|
||||
<li> Cudd_addIthBit()
|
||||
</ul>
|
||||
Static functions included in this module:
|
||||
<ul>
|
||||
<li> addDoIthBit()
|
||||
</ul>]
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -33,6 +60,7 @@
|
|||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -53,7 +81,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddAddFind.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddAddFind.c,v 1.8 2004/08/13 18:04:45 fabio Exp $";
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -61,6 +89,9 @@ static char rcsid[] DD_UNUSED = "$Id: cuddAddFind.c,v 1.1.1.1 2003/02/24 22:23:5
|
|||
/* Macro declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**AutomaticStart*************************************************************/
|
||||
|
||||
|
|
@ -68,10 +99,13 @@ static char rcsid[] DD_UNUSED = "$Id: cuddAddFind.c,v 1.1.1.1 2003/02/24 22:23:5
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static DdNode * addDoIthBit ARGS((DdManager *dd, DdNode *f, DdNode *index));
|
||||
static DdNode * addDoIthBit (DdManager *dd, DdNode *f, DdNode *index);
|
||||
|
||||
/**AutomaticEnd***************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Definition of exported functions */
|
||||
|
|
@ -95,12 +129,12 @@ Cudd_addFindMax(
|
|||
|
||||
statLine(dd);
|
||||
if (cuddIsConstant(f)) {
|
||||
return(f);
|
||||
return(f);
|
||||
}
|
||||
|
||||
res = cuddCacheLookup1(dd,Cudd_addFindMax,f);
|
||||
if (res != NULL) {
|
||||
return(res);
|
||||
return(res);
|
||||
}
|
||||
|
||||
t = Cudd_addFindMax(dd,cuddT(f));
|
||||
|
|
@ -135,12 +169,12 @@ Cudd_addFindMin(
|
|||
|
||||
statLine(dd);
|
||||
if (cuddIsConstant(f)) {
|
||||
return(f);
|
||||
return(f);
|
||||
}
|
||||
|
||||
res = cuddCacheLookup1(dd,Cudd_addFindMin,f);
|
||||
if (res != NULL) {
|
||||
return(res);
|
||||
return(res);
|
||||
}
|
||||
|
||||
t = Cudd_addFindMin(dd,cuddT(f));
|
||||
|
|
@ -192,13 +226,13 @@ Cudd_addIthBit(
|
|||
cuddRef(index);
|
||||
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = addDoIthBit(dd, f, index);
|
||||
dd->reordered = 0;
|
||||
res = addDoIthBit(dd, f, index);
|
||||
} while (dd->reordered == 1);
|
||||
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDeref(dd, index);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(dd, index);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDeref(dd, index);
|
||||
|
|
@ -244,9 +278,9 @@ addDoIthBit(
|
|||
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));
|
||||
mask = 1 << ((int) cuddV(index));
|
||||
value = (int) cuddV(f);
|
||||
return((value & mask) == 0 ? DD_ZERO(dd) : DD_ONE(dd));
|
||||
}
|
||||
|
||||
/* Check cache. */
|
||||
|
|
@ -263,16 +297,16 @@ addDoIthBit(
|
|||
|
||||
E = addDoIthBit(dd,fvn,index);
|
||||
if (E == NULL) {
|
||||
Cudd_RecursiveDeref(dd, T);
|
||||
return(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);
|
||||
Cudd_RecursiveDeref(dd, T);
|
||||
Cudd_RecursiveDeref(dd, E);
|
||||
return(NULL);
|
||||
}
|
||||
cuddDeref(T);
|
||||
cuddDeref(E);
|
||||
|
|
@ -284,5 +318,7 @@ addDoIthBit(
|
|||
|
||||
} /* end of addDoIthBit */
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,20 +7,47 @@
|
|||
Synopsis [Function to compute the scalar inverse of an ADD.]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_addScalarInverse()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddAddScalarInverseRecur()
|
||||
</ul>]
|
||||
<ul>
|
||||
<li> Cudd_addScalarInverse()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddAddScalarInverseRecur()
|
||||
</ul>]
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -31,6 +58,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -51,7 +79,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddAddInv.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddAddInv.c,v 1.9 2004/08/13 18:04:45 fabio Exp $";
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -97,12 +125,12 @@ Cudd_addScalarInverse(
|
|||
DdNode *res;
|
||||
|
||||
if (!cuddIsConstant(epsilon)) {
|
||||
(void) fprintf(dd->err,"Invalid epsilon\n");
|
||||
return(NULL);
|
||||
(void) fprintf(dd->err,"Invalid epsilon\n");
|
||||
return(NULL);
|
||||
}
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = cuddAddScalarInverseRecur(dd,f,epsilon);
|
||||
dd->reordered = 0;
|
||||
res = cuddAddScalarInverseRecur(dd,f,epsilon);
|
||||
} while (dd->reordered == 1);
|
||||
return(res);
|
||||
|
||||
|
|
@ -135,10 +163,10 @@ cuddAddScalarInverseRecur(
|
|||
|
||||
statLine(dd);
|
||||
if (cuddIsConstant(f)) {
|
||||
if (ddAbs(cuddV(f)) < cuddV(epsilon)) return(NULL);
|
||||
value = 1.0 / cuddV(f);
|
||||
res = cuddUniqueConst(dd,value);
|
||||
return(res);
|
||||
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);
|
||||
|
|
@ -150,17 +178,19 @@ cuddAddScalarInverseRecur(
|
|||
|
||||
e = cuddAddScalarInverseRecur(dd,cuddE(f),epsilon);
|
||||
if (e == NULL) {
|
||||
Cudd_RecursiveDeref(dd, t);
|
||||
return(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);
|
||||
Cudd_RecursiveDeref(dd, t);
|
||||
Cudd_RecursiveDeref(dd, e);
|
||||
return(NULL);
|
||||
}
|
||||
cuddDeref(t);
|
||||
cuddDeref(e);
|
||||
|
||||
cuddCacheInsert2(dd,Cudd_addScalarInverse,f,epsilon,res);
|
||||
|
||||
|
|
@ -173,5 +203,7 @@ cuddAddScalarInverseRecur(
|
|||
/* Definition of static functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,29 +7,56 @@
|
|||
Synopsis [ADD ITE function and satellites.]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_addIte()
|
||||
<li> Cudd_addIteConstant()
|
||||
<li> Cudd_addEvalConst()
|
||||
<li> Cudd_addCmpl()
|
||||
<li> Cudd_addLeq()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddAddIteRecur()
|
||||
<li> cuddAddCmplRecur()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> addVarToConst()
|
||||
</ul>]
|
||||
<ul>
|
||||
<li> Cudd_addIte()
|
||||
<li> Cudd_addIteConstant()
|
||||
<li> Cudd_addEvalConst()
|
||||
<li> Cudd_addCmpl()
|
||||
<li> Cudd_addLeq()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddAddIteRecur()
|
||||
<li> cuddAddCmplRecur()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> addVarToConst()
|
||||
</ul>]
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -39,6 +66,7 @@
|
|||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -59,7 +87,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddAddIte.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddAddIte.c,v 1.15 2004/08/13 18:04:45 fabio Exp $";
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -74,7 +102,7 @@ static char rcsid[] DD_UNUSED = "$Id: cuddAddIte.c,v 1.1.1.1 2003/02/24 22:23:50
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static void addVarToConst ARGS((DdNode *f, DdNode **gp, DdNode **hp, DdNode *one, DdNode *zero));
|
||||
static void addVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *one, DdNode *zero);
|
||||
|
||||
/**AutomaticEnd***************************************************************/
|
||||
|
||||
|
|
@ -107,8 +135,8 @@ Cudd_addIte(
|
|||
DdNode *res;
|
||||
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = cuddAddIteRecur(dd,f,g,h);
|
||||
dd->reordered = 0;
|
||||
res = cuddAddIteRecur(dd,f,g,h);
|
||||
} while (dd->reordered == 1);
|
||||
return(res);
|
||||
|
||||
|
|
@ -144,7 +172,7 @@ Cudd_addIteConstant(
|
|||
|
||||
statLine(dd);
|
||||
/* Trivial cases. */
|
||||
if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */
|
||||
if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */
|
||||
return(g);
|
||||
}
|
||||
if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */
|
||||
|
|
@ -155,7 +183,7 @@ Cudd_addIteConstant(
|
|||
addVarToConst(f,&g,&h,one,zero);
|
||||
|
||||
/* Check remaining one variable cases. */
|
||||
if (g == h) { /* ITE(F,G,G) = G */
|
||||
if (g == h) { /* ITE(F,G,G) = G */
|
||||
return(g);
|
||||
}
|
||||
if (cuddIsConstant(g) && cuddIsConstant(h)) {
|
||||
|
|
@ -169,7 +197,7 @@ Cudd_addIteConstant(
|
|||
|
||||
/* 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);
|
||||
return(DD_NON_CONSTANT);
|
||||
}
|
||||
|
||||
/* Check cache. */
|
||||
|
|
@ -180,7 +208,7 @@ Cudd_addIteConstant(
|
|||
|
||||
/* Compute cofactors. */
|
||||
if (topf <= v) {
|
||||
v = ddMin(topf,v); /* v = top_var(F,G,H) */
|
||||
v = ddMin(topf,v); /* v = top_var(F,G,H) */
|
||||
Fv = cuddT(f); Fnv = cuddE(f);
|
||||
} else {
|
||||
Fv = Fnv = f;
|
||||
|
|
@ -199,13 +227,13 @@ Cudd_addIteConstant(
|
|||
/* 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);
|
||||
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, DD_NON_CONSTANT);
|
||||
return(DD_NON_CONSTANT);
|
||||
}
|
||||
cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, t);
|
||||
return(t);
|
||||
|
|
@ -279,24 +307,24 @@ Cudd_addEvalConst(
|
|||
|
||||
/* 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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
cuddCacheInsert2(dd,Cudd_addEvalConst,f,g,t);
|
||||
return(t);
|
||||
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);
|
||||
e = Cudd_addEvalConst(dd,Fnv,Gnv);
|
||||
cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, e);
|
||||
return(e);
|
||||
}
|
||||
|
||||
} /* end of Cudd_addEvalConst */
|
||||
|
|
@ -323,8 +351,8 @@ Cudd_addCmpl(
|
|||
DdNode *res;
|
||||
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = cuddAddCmplRecur(dd,f);
|
||||
dd->reordered = 0;
|
||||
res = cuddAddCmplRecur(dd,f);
|
||||
} while (dd->reordered == 1);
|
||||
return(res);
|
||||
|
||||
|
|
@ -358,39 +386,38 @@ Cudd_addLeq(
|
|||
|
||||
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 (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,(DdNode * (*)(DdManager *, DdNode *,
|
||||
DdNode *))Cudd_addLeq,f,g);
|
||||
tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_addLeq,f,g);
|
||||
if (tmp != NULL) {
|
||||
return(tmp == DD_ONE(dd));
|
||||
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);
|
||||
fv = cuddT(f); fvn = cuddE(f);
|
||||
} else {
|
||||
fv = fvn = f;
|
||||
fv = fvn = f;
|
||||
}
|
||||
if (topg <= topf) {
|
||||
gv = cuddT(g); gvn = cuddE(g);
|
||||
gv = cuddT(g); gvn = cuddE(g);
|
||||
} else {
|
||||
gv = gvn = g;
|
||||
gv = gvn = g;
|
||||
}
|
||||
|
||||
res = Cudd_addLeq(dd,fvn,gvn) && Cudd_addLeq(dd,fv,gv);
|
||||
|
||||
/* Store result in cache and return. */
|
||||
cuddCacheInsert2(dd,(DdNode * (*)(DdManager *, DdNode *, DdNode *))
|
||||
Cudd_addLeq,f,g,Cudd_NotCond(DD_ONE(dd),res==0));
|
||||
cuddCacheInsert2(dd,(DD_CTFP) Cudd_addLeq,f,g,
|
||||
Cudd_NotCond(DD_ONE(dd),res==0));
|
||||
return(res);
|
||||
|
||||
} /* end of Cudd_addLeq */
|
||||
|
|
@ -424,13 +451,13 @@ cuddAddIteRecur(
|
|||
DdNode *one,*zero;
|
||||
DdNode *r,*Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*t,*e;
|
||||
unsigned int topf,topg,toph,v;
|
||||
int index = 0; // Suppress "might be used uninitialized"
|
||||
int index;
|
||||
|
||||
statLine(dd);
|
||||
/* Trivial cases. */
|
||||
|
||||
/* One variable cases. */
|
||||
if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */
|
||||
if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */
|
||||
return(g);
|
||||
}
|
||||
if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */
|
||||
|
|
@ -441,11 +468,11 @@ cuddAddIteRecur(
|
|||
addVarToConst(f,&g,&h,one,zero);
|
||||
|
||||
/* Check remaining one variable cases. */
|
||||
if (g == h) { /* ITE(F,G,G) = G */
|
||||
if (g == h) { /* ITE(F,G,G) = G */
|
||||
return(g);
|
||||
}
|
||||
|
||||
if (g == one) { /* ITE(F,1,0) = F */
|
||||
if (g == one) { /* ITE(F,1,0) = F */
|
||||
if (h == zero) return(f);
|
||||
}
|
||||
|
||||
|
|
@ -456,12 +483,12 @@ cuddAddIteRecur(
|
|||
|
||||
/* 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);
|
||||
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);
|
||||
r = cuddUniqueInter(dd,(int)f->index,h,g);
|
||||
return(r);
|
||||
}
|
||||
|
||||
/* Check cache. */
|
||||
|
|
@ -472,20 +499,20 @@ cuddAddIteRecur(
|
|||
|
||||
/* Compute cofactors. */
|
||||
if (topf <= v) {
|
||||
v = ddMin(topf,v); /* v = top_var(F,G,H) */
|
||||
index = f->index;
|
||||
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;
|
||||
index = g->index;
|
||||
Gv = cuddT(g); Gnv = cuddE(g);
|
||||
} else {
|
||||
Gv = Gnv = g;
|
||||
}
|
||||
if (toph == v) {
|
||||
index = h->index;
|
||||
index = h->index;
|
||||
Hv = cuddT(h); Hnv = cuddE(h);
|
||||
} else {
|
||||
Hv = Hnv = h;
|
||||
|
|
@ -498,16 +525,16 @@ cuddAddIteRecur(
|
|||
|
||||
e = cuddAddIteRecur(dd,Fnv,Gnv,Hnv);
|
||||
if (e == NULL) {
|
||||
Cudd_RecursiveDeref(dd,t);
|
||||
return(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);
|
||||
Cudd_RecursiveDeref(dd,t);
|
||||
Cudd_RecursiveDeref(dd,e);
|
||||
return(NULL);
|
||||
}
|
||||
cuddDeref(t);
|
||||
cuddDeref(e);
|
||||
|
|
@ -545,14 +572,14 @@ cuddAddCmplRecur(
|
|||
|
||||
if (cuddIsConstant(f)) {
|
||||
if (f == zero) {
|
||||
return(one);
|
||||
} else {
|
||||
return(zero);
|
||||
}
|
||||
return(one);
|
||||
} else {
|
||||
return(zero);
|
||||
}
|
||||
}
|
||||
r = cuddCacheLookup1(dd,Cudd_addCmpl,f);
|
||||
if (r != NULL) {
|
||||
return(r);
|
||||
return(r);
|
||||
}
|
||||
Fv = cuddT(f);
|
||||
Fnv = cuddE(f);
|
||||
|
|
@ -561,15 +588,15 @@ cuddAddCmplRecur(
|
|||
cuddRef(t);
|
||||
e = cuddAddCmplRecur(dd,Fnv);
|
||||
if (e == NULL) {
|
||||
Cudd_RecursiveDeref(dd,t);
|
||||
return(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);
|
||||
Cudd_RecursiveDeref(dd, t);
|
||||
Cudd_RecursiveDeref(dd, e);
|
||||
return(NULL);
|
||||
}
|
||||
cuddDeref(t);
|
||||
cuddDeref(e);
|
||||
|
|
@ -606,13 +633,15 @@ addVarToConst(
|
|||
DdNode *h = *hp;
|
||||
|
||||
if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */
|
||||
*gp = one;
|
||||
*gp = one;
|
||||
}
|
||||
|
||||
if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */
|
||||
*hp = zero;
|
||||
*hp = zero;
|
||||
}
|
||||
|
||||
} /* end of addVarToConst */
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -4,35 +4,63 @@
|
|||
|
||||
PackageName [cudd]
|
||||
|
||||
Synopsis [function to compute the negation of an ADD.]
|
||||
Synopsis [Function to compute the negation of an ADD.]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_addNegate()
|
||||
<li> Cudd_addRoundOff()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddAddNegateRecur()
|
||||
<li> cuddAddRoundOffRecur()
|
||||
</ul> ]
|
||||
<ul>
|
||||
<li> Cudd_addNegate()
|
||||
<li> Cudd_addRoundOff()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddAddNegateRecur()
|
||||
<li> cuddAddRoundOffRecur()
|
||||
</ul> ]
|
||||
|
||||
Author [Fabio Somenzi, Balakrishna Kumthekar]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "util_hack.h"
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -53,7 +81,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddAddNeg.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddAddNeg.c,v 1.12 2009/02/20 02:14:58 fabio Exp $";
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -96,7 +124,7 @@ Cudd_addNegate(
|
|||
DdNode *res;
|
||||
|
||||
do {
|
||||
res = cuddAddNegateRecur(dd,f);
|
||||
res = cuddAddNegateRecur(dd,f);
|
||||
} while (dd->reordered == 1);
|
||||
return(res);
|
||||
|
||||
|
|
@ -126,7 +154,7 @@ Cudd_addRoundOff(
|
|||
double trunc = pow(10.0,(double)N);
|
||||
|
||||
do {
|
||||
res = cuddAddRoundOffRecur(dd,f,trunc);
|
||||
res = cuddAddRoundOffRecur(dd,f,trunc);
|
||||
} while (dd->reordered == 1);
|
||||
return(res);
|
||||
|
||||
|
|
@ -154,14 +182,14 @@ cuddAddNegateRecur(
|
|||
DdNode * f)
|
||||
{
|
||||
DdNode *res,
|
||||
*fv, *fvn,
|
||||
*T, *E;
|
||||
*fv, *fvn,
|
||||
*T, *E;
|
||||
|
||||
statLine(dd);
|
||||
/* Check terminal cases. */
|
||||
if (cuddIsConstant(f)) {
|
||||
res = cuddUniqueConst(dd,-cuddV(f));
|
||||
return(res);
|
||||
res = cuddUniqueConst(dd,-cuddV(f));
|
||||
return(res);
|
||||
}
|
||||
|
||||
/* Check cache */
|
||||
|
|
@ -177,15 +205,15 @@ cuddAddNegateRecur(
|
|||
|
||||
E = cuddAddNegateRecur(dd,fvn);
|
||||
if (E == NULL) {
|
||||
Cudd_RecursiveDeref(dd,T);
|
||||
return(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);
|
||||
Cudd_RecursiveDeref(dd, T);
|
||||
Cudd_RecursiveDeref(dd, E);
|
||||
return(NULL);
|
||||
}
|
||||
cuddDeref(T);
|
||||
cuddDeref(E);
|
||||
|
|
@ -217,15 +245,15 @@ cuddAddRoundOffRecur(
|
|||
|
||||
DdNode *res, *fv, *fvn, *T, *E;
|
||||
double n;
|
||||
DdNode *(*cacheOp)(DdManager *, DdNode *);
|
||||
|
||||
DD_CTFP1 cacheOp;
|
||||
|
||||
statLine(dd);
|
||||
if (cuddIsConstant(f)) {
|
||||
n = ceil(cuddV(f)*trunc)/trunc;
|
||||
res = cuddUniqueConst(dd,n);
|
||||
return(res);
|
||||
res = cuddUniqueConst(dd,n);
|
||||
return(res);
|
||||
}
|
||||
cacheOp = (DdNode *(*)(DdManager *, DdNode *)) Cudd_addRoundOff;
|
||||
cacheOp = (DD_CTFP1) Cudd_addRoundOff;
|
||||
res = cuddCacheLookup1(dd,cacheOp,f);
|
||||
if (res != NULL) {
|
||||
return(res);
|
||||
|
|
@ -241,14 +269,14 @@ cuddAddRoundOffRecur(
|
|||
E = cuddAddRoundOffRecur(dd,fvn,trunc);
|
||||
if (E == NULL) {
|
||||
Cudd_RecursiveDeref(dd,T);
|
||||
return(NULL);
|
||||
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);
|
||||
Cudd_RecursiveDeref(dd,E);
|
||||
return(NULL);
|
||||
}
|
||||
cuddDeref(T);
|
||||
cuddDeref(E);
|
||||
|
|
@ -256,12 +284,13 @@ cuddAddRoundOffRecur(
|
|||
/* Store result. */
|
||||
cuddCacheInsert1(dd,cacheOp,f,res);
|
||||
return(res);
|
||||
|
||||
|
||||
} /* end of cuddAddRoundOffRecur */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Definition of static functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -8,21 +8,48 @@
|
|||
functions in ADD form.]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_addWalsh()
|
||||
<li> Cudd_addResidue()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> addWalshInt()
|
||||
</ul>]
|
||||
<ul>
|
||||
<li> Cudd_addWalsh()
|
||||
<li> Cudd_addResidue()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> addWalshInt()
|
||||
</ul>]
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -33,6 +60,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -53,7 +81,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddAddWalsh.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddAddWalsh.c,v 1.10 2008/04/17 21:17:11 fabio Exp $";
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -68,7 +96,7 @@ static char rcsid[] DD_UNUSED = "$Id: cuddAddWalsh.c,v 1.1.1.1 2003/02/24 22:23:
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static DdNode * addWalshInt ARGS((DdManager *dd, DdNode **x, DdNode **y, int n));
|
||||
static DdNode * addWalshInt (DdManager *dd, DdNode **x, DdNode **y, int n);
|
||||
|
||||
/**AutomaticEnd***************************************************************/
|
||||
|
||||
|
|
@ -98,8 +126,8 @@ Cudd_addWalsh(
|
|||
DdNode *res;
|
||||
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = addWalshInt(dd, x, y, n);
|
||||
dd->reordered = 0;
|
||||
res = addWalshInt(dd, x, y, n);
|
||||
} while (dd->reordered == 1);
|
||||
return(res);
|
||||
|
||||
|
|
@ -137,8 +165,8 @@ Cudd_addResidue(
|
|||
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 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;
|
||||
|
||||
|
|
@ -151,89 +179,89 @@ Cudd_addResidue(
|
|||
/* Allocate and initialize working arrays. */
|
||||
array[0] = ABC_ALLOC(DdNode *,m);
|
||||
if (array[0] == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
}
|
||||
array[1] = ABC_ALLOC(DdNode *,m);
|
||||
if (array[1] == NULL) {
|
||||
ABC_FREE(array[0]);
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
ABC_FREE(array[0]);
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
}
|
||||
for (i = 0; i < m; i++) {
|
||||
array[0][i] = array[1][i] = NULL;
|
||||
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]);
|
||||
tmp = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) i);
|
||||
if (tmp == NULL) {
|
||||
for (j = 0; j < i; j++) {
|
||||
Cudd_RecursiveDeref(dd,array[1][j]);
|
||||
}
|
||||
ABC_FREE(array[0]);
|
||||
ABC_FREE(array[1]);
|
||||
return(NULL);
|
||||
}
|
||||
ABC_FREE(array[0]);
|
||||
ABC_FREE(array[1]);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(tmp);
|
||||
array[1][i] = tmp;
|
||||
cuddRef(tmp);
|
||||
array[1][i] = tmp;
|
||||
}
|
||||
|
||||
/* Main iteration. */
|
||||
residue = 1; /* residue of 2**0 */
|
||||
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]);
|
||||
/* 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;
|
||||
}
|
||||
ABC_FREE(array[0]);
|
||||
ABC_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]);
|
||||
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]);
|
||||
}
|
||||
ABC_FREE(array[0]);
|
||||
ABC_FREE(array[1]);
|
||||
return(NULL);
|
||||
}
|
||||
for (j = 0; j < m; j++) {
|
||||
Cudd_RecursiveDeref(dd,array[previous][j]);
|
||||
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]);
|
||||
}
|
||||
ABC_FREE(array[0]);
|
||||
ABC_FREE(array[1]);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(tmp);
|
||||
array[thisOne][i] = tmp;
|
||||
}
|
||||
ABC_FREE(array[0]);
|
||||
ABC_FREE(array[1]);
|
||||
return(NULL);
|
||||
/* 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;
|
||||
}
|
||||
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]);
|
||||
Cudd_RecursiveDeref(dd,array[(n - 1) & 1][i]);
|
||||
}
|
||||
res = array[(n - 1) & 1][0];
|
||||
|
||||
|
|
@ -274,8 +302,7 @@ addWalshInt(
|
|||
int n)
|
||||
{
|
||||
DdNode *one, *minusone;
|
||||
DdNode *t = NULL; // Suppress "might be used uninitialized"
|
||||
DdNode *u, *t1, *u1, *v, *w;
|
||||
DdNode *t, *u, *t1, *u1, *v, *w;
|
||||
int i;
|
||||
|
||||
one = DD_ONE(dd);
|
||||
|
|
@ -287,84 +314,86 @@ addWalshInt(
|
|||
cuddRef(minusone);
|
||||
v = Cudd_addIte(dd, y[n-1], minusone, one);
|
||||
if (v == NULL) {
|
||||
Cudd_RecursiveDeref(dd, minusone);
|
||||
return(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 (u == NULL) {
|
||||
Cudd_RecursiveDeref(dd, u1);
|
||||
Cudd_RecursiveDeref(dd, t1);
|
||||
Cudd_RecursiveDeref(dd, u);
|
||||
return(NULL);
|
||||
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[i], w, t1);
|
||||
if (u == NULL) {
|
||||
Cudd_RecursiveDeref(dd, u1);
|
||||
Cudd_RecursiveDeref(dd, t1);
|
||||
Cudd_RecursiveDeref(dd, u);
|
||||
Cudd_RecursiveDeref(dd, w);
|
||||
return(NULL);
|
||||
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);
|
||||
}
|
||||
Cudd_RecursiveDeref(dd, u1);
|
||||
Cudd_RecursiveDeref(dd, t1);
|
||||
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 */
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -7,20 +7,48 @@
|
|||
Synopsis [Combined AND and existential abstraction for BDDs]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_bddAndAbstract()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddBddAndAbstractRecur()
|
||||
</ul>]
|
||||
<ul>
|
||||
<li> Cudd_bddAndAbstract()
|
||||
<li> Cudd_bddAndAbstractLimit()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddBddAndAbstractRecur()
|
||||
</ul>]
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -31,6 +59,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -51,7 +80,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddAndAbs.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddAndAbs.c,v 1.19 2004/08/13 18:04:46 fabio Exp $";
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -101,8 +130,8 @@ Cudd_bddAndAbstract(
|
|||
DdNode *res;
|
||||
|
||||
do {
|
||||
manager->reordered = 0;
|
||||
res = cuddBddAndAbstractRecur(manager, f, g, cube);
|
||||
manager->reordered = 0;
|
||||
res = cuddBddAndAbstractRecur(manager, f, g, cube);
|
||||
} while (manager->reordered == 1);
|
||||
return(res);
|
||||
|
||||
|
|
@ -135,10 +164,11 @@ Cudd_bddAndAbstractLimit(
|
|||
{
|
||||
DdNode *res;
|
||||
unsigned int saveLimit = manager->maxLive;
|
||||
|
||||
manager->maxLive = (manager->keys - manager->dead) +
|
||||
(manager->keysZ - manager->deadZ) + limit;
|
||||
do {
|
||||
manager->reordered = 0;
|
||||
manager->maxLive = (manager->keys - manager->dead) +
|
||||
(manager->keysZ - manager->deadZ) + limit;
|
||||
res = cuddBddAndAbstractRecur(manager, f, g, cube);
|
||||
} while (manager->reordered == 1);
|
||||
manager->maxLive = saveLimit;
|
||||
|
|
@ -147,7 +177,6 @@ Cudd_bddAndAbstractLimit(
|
|||
} /* end of Cudd_bddAndAbstractLimit */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Definition of internal functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -184,23 +213,23 @@ cuddBddAndAbstractRecur(
|
|||
|
||||
/* Terminal cases. */
|
||||
if (f == zero || g == zero || f == Cudd_Not(g)) return(zero);
|
||||
if (f == one && g == one) return(one);
|
||||
if (f == one && g == one) return(one);
|
||||
|
||||
if (cube == one) {
|
||||
return(cuddBddAndRecur(manager, f, g));
|
||||
return(cuddBddAndRecur(manager, f, g));
|
||||
}
|
||||
if (f == one || f == g) {
|
||||
return(cuddBddExistAbstractRecur(manager, g, cube));
|
||||
return(cuddBddExistAbstractRecur(manager, g, cube));
|
||||
}
|
||||
if (g == one) {
|
||||
return(cuddBddExistAbstractRecur(manager, f, cube));
|
||||
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;
|
||||
DdNode *tmp = f;
|
||||
f = g;
|
||||
g = tmp;
|
||||
}
|
||||
|
||||
/* Here we can skip the use of cuddI, because the operands are known
|
||||
|
|
@ -214,129 +243,129 @@ cuddBddAndAbstractRecur(
|
|||
topcube = manager->perm[cube->index];
|
||||
|
||||
while (topcube < top) {
|
||||
cube = cuddT(cube);
|
||||
if (cube == one) {
|
||||
return(cuddBddAndRecur(manager, f, g));
|
||||
}
|
||||
topcube = manager->perm[cube->index];
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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;
|
||||
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);
|
||||
}
|
||||
gt = cuddT(G);
|
||||
ge = cuddE(G);
|
||||
if (Cudd_IsComplement(g)) {
|
||||
gt = Cudd_Not(gt);
|
||||
ge = Cudd_Not(ge);
|
||||
}
|
||||
} else {
|
||||
gt = ge = g;
|
||||
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);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
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 {
|
||||
r = cuddUniqueInter(manager,(int)index,t,e);
|
||||
if (r == NULL) {
|
||||
e = cuddBddAndAbstractRecur(manager, fe, ge, Cube);
|
||||
}
|
||||
if (e == NULL) {
|
||||
Cudd_IterDerefBdd(manager, t);
|
||||
Cudd_IterDerefBdd(manager, e);
|
||||
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);
|
||||
}
|
||||
cuddDeref(e);
|
||||
cuddDeref(t);
|
||||
}
|
||||
}
|
||||
|
||||
if (F->ref != 1 || G->ref != 1)
|
||||
cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube, r);
|
||||
cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube, r);
|
||||
return (r);
|
||||
|
||||
} /* end of cuddBddAndAbstractRecur */
|
||||
|
|
@ -346,5 +375,7 @@ cuddBddAndAbstractRecur(
|
|||
/* Definition of static functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,31 +7,58 @@
|
|||
Synopsis [Reordering of DDs based on simulated annealing]
|
||||
|
||||
Description [Internal procedures included in this file:
|
||||
<ul>
|
||||
<li> cuddAnnealing()
|
||||
</ul>
|
||||
Static procedures included in this file:
|
||||
<ul>
|
||||
<li> stopping_criterion()
|
||||
<li> random_generator()
|
||||
<li> ddExchange()
|
||||
<li> ddJumpingAux()
|
||||
<li> ddJumpingUp()
|
||||
<li> ddJumpingDown()
|
||||
<li> siftBackwardProb()
|
||||
<li> copyOrder()
|
||||
<li> restoreOrder()
|
||||
</ul>
|
||||
]
|
||||
<ul>
|
||||
<li> cuddAnnealing()
|
||||
</ul>
|
||||
Static procedures included in this file:
|
||||
<ul>
|
||||
<li> stopping_criterion()
|
||||
<li> random_generator()
|
||||
<li> ddExchange()
|
||||
<li> ddJumpingAux()
|
||||
<li> ddJumpingUp()
|
||||
<li> ddJumpingDown()
|
||||
<li> siftBackwardProb()
|
||||
<li> copyOrder()
|
||||
<li> restoreOrder()
|
||||
</ul>
|
||||
]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
Author [Jae-Young Jang, Jorgen Sivesind]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -41,6 +68,7 @@
|
|||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -68,14 +96,14 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddAnneal.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddAnneal.c,v 1.14 2004/08/13 18:04:46 fabio Exp $";
|
||||
#endif
|
||||
|
||||
#ifdef DD_STATS
|
||||
extern int ddTotalNumberSwapping;
|
||||
extern int ddTotalNISwaps;
|
||||
static int tosses;
|
||||
static int acceptances;
|
||||
extern int ddTotalNumberSwapping;
|
||||
extern int ddTotalNISwaps;
|
||||
static int tosses;
|
||||
static int acceptances;
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -89,15 +117,15 @@ static int acceptances;
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static int stopping_criterion ARGS((int c1, int c2, int c3, int c4, double temp));
|
||||
static double random_generator ARGS(());
|
||||
static int ddExchange ARGS((DdManager *table, int x, int y, double temp));
|
||||
static int ddJumpingAux ARGS((DdManager *table, int x, int x_low, int x_high, double temp));
|
||||
static Move * ddJumpingUp ARGS((DdManager *table, int x, int x_low, int initial_size));
|
||||
static Move * ddJumpingDown ARGS((DdManager *table, int x, int x_high, int initial_size));
|
||||
static int siftBackwardProb ARGS((DdManager *table, Move *moves, int size, double temp));
|
||||
static void copyOrder ARGS((DdManager *table, int *array, int lower, int upper));
|
||||
static int restoreOrder ARGS((DdManager *table, int *array, int lower, int upper));
|
||||
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***************************************************************/
|
||||
|
||||
|
|
@ -136,11 +164,11 @@ cuddAnnealing(
|
|||
int size;
|
||||
int x,y;
|
||||
int result;
|
||||
int c1, c2, c3, c4;
|
||||
int BestCost;
|
||||
int *BestOrder;
|
||||
double NewTemp, temp;
|
||||
double rand1;
|
||||
int c1, c2, c3, c4;
|
||||
int BestCost;
|
||||
int *BestOrder;
|
||||
double NewTemp, temp;
|
||||
double rand1;
|
||||
int innerloop, maxGen;
|
||||
int ecount, ucount, dcount;
|
||||
|
||||
|
|
@ -158,8 +186,8 @@ cuddAnnealing(
|
|||
BestCost = size;
|
||||
BestOrder = ABC_ALLOC(int,nvars);
|
||||
if (BestOrder == NULL) {
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
copyOrder(table,BestOrder,lower,upper);
|
||||
|
||||
|
|
@ -174,76 +202,76 @@ cuddAnnealing(
|
|||
|
||||
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;
|
||||
(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;
|
||||
}
|
||||
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++;
|
||||
/* 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);
|
||||
(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++;
|
||||
} 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);
|
||||
(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++;
|
||||
} 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);
|
||||
(void) fprintf(table->out,
|
||||
"Jump down of %d to %d: size = %d\n",
|
||||
x,y,table->keys - table->isolated);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
ABC_FREE(BestOrder);
|
||||
return(0);
|
||||
}
|
||||
if (!result) {
|
||||
ABC_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);
|
||||
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 */
|
||||
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);
|
||||
(void) fprintf(table->out,"uphill = %d\taccepted = %d\n",
|
||||
tosses,acceptances);
|
||||
fflush(table->out);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -286,11 +314,11 @@ stopping_criterion(
|
|||
double temp)
|
||||
{
|
||||
if (STOP_TEMP < temp) {
|
||||
return(0);
|
||||
return(0);
|
||||
} else if ((c1 == c2) && (c1 == c3) && (c1 == c4)) {
|
||||
return(1);
|
||||
return(1);
|
||||
} else {
|
||||
return(0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
} /* end of stopping_criterion */
|
||||
|
|
@ -308,8 +336,7 @@ stopping_criterion(
|
|||
|
||||
******************************************************************************/
|
||||
static double
|
||||
random_generator(
|
||||
)
|
||||
random_generator(void)
|
||||
{
|
||||
return((double)(Cudd_Random() / 2147483561.0));
|
||||
|
||||
|
|
@ -351,83 +378,83 @@ ddExchange(
|
|||
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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
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 ((double) size > DD_MAX_REORDER_GROWTH * (double) limit_size) {
|
||||
break;
|
||||
} else if (size < limit_size) {
|
||||
limit_size = size;
|
||||
}
|
||||
}
|
||||
|
||||
if (y_next>=x_ref) {
|
||||
|
|
@ -447,16 +474,16 @@ ddExchange(
|
|||
if (!result) goto ddExchangeOutOfMem;
|
||||
|
||||
while (moves != NULL) {
|
||||
move = moves->next;
|
||||
cuddDeallocNode(table, (DdNode *) moves);
|
||||
moves = move;
|
||||
move = moves->next;
|
||||
cuddDeallocMove(table, moves);
|
||||
moves = move;
|
||||
}
|
||||
return(1);
|
||||
|
||||
ddExchangeOutOfMem:
|
||||
while (moves != NULL) {
|
||||
move = moves->next;
|
||||
cuddDeallocNode(table,(DdNode *) moves);
|
||||
cuddDeallocMove(table, moves);
|
||||
moves = move;
|
||||
}
|
||||
return(0);
|
||||
|
|
@ -499,36 +526,36 @@ ddJumpingAux(
|
|||
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;
|
||||
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;
|
||||
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;
|
||||
(void) fprintf(table->err,"Unexpected condition in ddJumping\n");
|
||||
goto ddJumpingAuxOutOfMem;
|
||||
}
|
||||
while (moves != NULL) {
|
||||
move = moves->next;
|
||||
cuddDeallocNode(table, (DdNode *) moves);
|
||||
moves = move;
|
||||
move = moves->next;
|
||||
cuddDeallocMove(table, moves);
|
||||
moves = move;
|
||||
}
|
||||
return(1);
|
||||
|
||||
ddJumpingAuxOutOfMem:
|
||||
while (moves != NULL) {
|
||||
move = moves->next;
|
||||
cuddDeallocNode(table, (DdNode *) moves);
|
||||
moves = move;
|
||||
move = moves->next;
|
||||
cuddDeallocMove(table, moves);
|
||||
moves = move;
|
||||
}
|
||||
return(0);
|
||||
|
||||
|
|
@ -564,30 +591,30 @@ ddJumpingUp(
|
|||
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);
|
||||
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;
|
||||
cuddDeallocNode(table, (DdNode *) moves);
|
||||
moves = move;
|
||||
move = moves->next;
|
||||
cuddDeallocMove(table, moves);
|
||||
moves = move;
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -623,30 +650,30 @@ ddJumpingDown(
|
|||
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);
|
||||
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;
|
||||
cuddDeallocNode(table, (DdNode *) moves);
|
||||
moves = move;
|
||||
move = moves->next;
|
||||
cuddDeallocMove(table, moves);
|
||||
moves = move;
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -681,9 +708,9 @@ siftBackwardProb(
|
|||
|
||||
/* 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 (move->size < best_size) {
|
||||
best_size = move->size;
|
||||
}
|
||||
}
|
||||
|
||||
/* If best_size equals size, the last sifting did not produce any
|
||||
|
|
@ -691,17 +718,17 @@ siftBackwardProb(
|
|||
** this change or not.
|
||||
*/
|
||||
if (best_size == size) {
|
||||
coin = random_generator();
|
||||
coin = random_generator();
|
||||
#ifdef DD_STATS
|
||||
tosses++;
|
||||
tosses++;
|
||||
#endif
|
||||
threshold = exp(-((double)(table->keys - table->isolated - size))/temp);
|
||||
if (coin < threshold) {
|
||||
threshold = exp(-((double)(table->keys - table->isolated - size))/temp);
|
||||
if (coin < threshold) {
|
||||
#ifdef DD_STATS
|
||||
acceptances++;
|
||||
acceptances++;
|
||||
#endif
|
||||
return(1);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Either there was improvement, or we have decided not to
|
||||
|
|
@ -709,9 +736,9 @@ siftBackwardProb(
|
|||
*/
|
||||
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);
|
||||
if (res == best_size) return(1);
|
||||
res = cuddSwapInPlace(table,(int)move->x,(int)move->y);
|
||||
if (!res) return(0);
|
||||
}
|
||||
|
||||
return(1);
|
||||
|
|
@ -743,7 +770,7 @@ copyOrder(
|
|||
|
||||
nvars = upper - lower + 1;
|
||||
for (i = 0; i < nvars; i++) {
|
||||
array[i] = table->invperm[i+lower];
|
||||
array[i] = table->invperm[i+lower];
|
||||
}
|
||||
|
||||
} /* end of copyOrder */
|
||||
|
|
@ -772,22 +799,24 @@ restoreOrder(
|
|||
int nvars = upper - lower + 1;
|
||||
|
||||
for (i = 0; i < nvars; i++) {
|
||||
x = table->perm[array[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);
|
||||
}
|
||||
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 */
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,24 +7,66 @@
|
|||
Synopsis [Arbitrary precision arithmetic functions.]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li>
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> ()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> ()
|
||||
</ul>]
|
||||
<ul>
|
||||
<li> Cudd_ApaNumberOfDigits()
|
||||
<li> Cudd_NewApaNumber()
|
||||
<li> Cudd_ApaCopy()
|
||||
<li> Cudd_ApaAdd()
|
||||
<li> Cudd_ApaSubtract()
|
||||
<li> Cudd_ApaShortDivision()
|
||||
<li> Cudd_ApaIntDivision()
|
||||
<li> Cudd_ApaShiftRight()
|
||||
<li> Cudd_ApaSetToLiteral()
|
||||
<li> Cudd_ApaPowerOfTwo()
|
||||
<li> Cudd_ApaCompare()
|
||||
<li> Cudd_ApaCompareRatios()
|
||||
<li> Cudd_ApaPrintHex()
|
||||
<li> Cudd_ApaPrintDecimal()
|
||||
<li> Cudd_ApaPrintExponential()
|
||||
<li> Cudd_ApaCountMinterm()
|
||||
<li> Cudd_ApaPrintMinterm()
|
||||
<li> Cudd_ApaPrintMintermExp()
|
||||
<li> Cudd_ApaPrintDensity()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddApaCountMintermAux()
|
||||
<li> cuddApaStCountfree()
|
||||
</ul>]
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -34,6 +76,7 @@
|
|||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -51,15 +94,18 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddApa.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddApa.c,v 1.19 2009/03/08 01:27:50 fabio Exp $";
|
||||
#endif
|
||||
|
||||
static DdNode *background, *zero;
|
||||
static DdNode *background, *zero;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Macro declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**AutomaticStart*************************************************************/
|
||||
|
||||
|
|
@ -67,11 +113,15 @@ static DdNode *background, *zero;
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static DdApaNumber cuddApaCountMintermAux ARGS((DdNode * node, int digits, DdApaNumber max, DdApaNumber min, st_table * table));
|
||||
static enum st_retval cuddApaStCountfree ARGS((char * key, char * value, char * arg));
|
||||
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 */
|
||||
|
|
@ -101,11 +151,11 @@ Cudd_ApaNumberOfDigits(
|
|||
|
||||
digits = binaryDigits / DD_APA_BITS;
|
||||
if ((digits * DD_APA_BITS) != binaryDigits)
|
||||
digits++;
|
||||
digits++;
|
||||
return(digits);
|
||||
|
||||
} /* end of Cudd_ApaNumberOfDigits */
|
||||
|
||||
|
||||
|
||||
/**Function********************************************************************
|
||||
|
||||
|
|
@ -149,7 +199,7 @@ Cudd_ApaCopy(
|
|||
int i;
|
||||
|
||||
for (i = 0; i < digits; i++) {
|
||||
dest[i] = source[i];
|
||||
dest[i] = source[i];
|
||||
}
|
||||
|
||||
} /* end of Cudd_ApaCopy */
|
||||
|
|
@ -178,10 +228,10 @@ Cudd_ApaAdd(
|
|||
DdApaDoubleDigit partial = 0;
|
||||
|
||||
for (i = digits - 1; i >= 0; i--) {
|
||||
partial = a[i] + b[i] + DD_MSDIGIT(partial);
|
||||
sum[i] = (DdApaDigit) DD_LSDIGIT(partial);
|
||||
partial = a[i] + b[i] + DD_MSDIGIT(partial);
|
||||
sum[i] = (DdApaDigit) DD_LSDIGIT(partial);
|
||||
}
|
||||
return(DD_MSDIGIT(partial));
|
||||
return((DdApaDigit) DD_MSDIGIT(partial));
|
||||
|
||||
} /* end of Cudd_ApaAdd */
|
||||
|
||||
|
|
@ -210,10 +260,10 @@ Cudd_ApaSubtract(
|
|||
DdApaDoubleDigit partial = DD_APA_BASE;
|
||||
|
||||
for (i = digits - 1; i >= 0; i--) {
|
||||
partial = a[i] - b[i] + DD_MSDIGIT(partial) + DD_APA_MASK;
|
||||
diff[i] = (DdApaDigit) DD_LSDIGIT(partial);
|
||||
partial = DD_MSDIGIT(partial) + DD_APA_MASK + a[i] - b[i];
|
||||
diff[i] = (DdApaDigit) DD_LSDIGIT(partial);
|
||||
}
|
||||
return(DD_MSDIGIT(partial) - 1);
|
||||
return((DdApaDigit) DD_MSDIGIT(partial) - 1);
|
||||
|
||||
} /* end of Cudd_ApaSubtract */
|
||||
|
||||
|
|
@ -242,9 +292,9 @@ Cudd_ApaShortDivision(
|
|||
|
||||
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);
|
||||
partial = remainder * DD_APA_BASE + dividend[i];
|
||||
quotient[i] = (DdApaDigit) (partial/(DdApaDoubleDigit)divisor);
|
||||
remainder = (DdApaDigit) (partial % divisor);
|
||||
}
|
||||
|
||||
return(remainder);
|
||||
|
|
@ -283,9 +333,9 @@ Cudd_ApaIntDivision(
|
|||
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));
|
||||
partial = (double) remainder * DD_APA_BASE + dividend[i];
|
||||
quotient[i] = (DdApaDigit) (partial / ddiv);
|
||||
remainder = (unsigned int) (partial - ((double)quotient[i] * ddiv));
|
||||
}
|
||||
|
||||
return(remainder);
|
||||
|
|
@ -317,7 +367,7 @@ Cudd_ApaShiftRight(
|
|||
int i;
|
||||
|
||||
for (i = digits - 1; i > 0; i--) {
|
||||
b[i] = (a[i] >> 1) | ((a[i-1] & 1) << (DD_APA_BITS - 1));
|
||||
b[i] = (a[i] >> 1) | ((a[i-1] & 1) << (DD_APA_BITS - 1));
|
||||
}
|
||||
b[0] = (a[0] >> 1) | (in << (DD_APA_BITS - 1));
|
||||
|
||||
|
|
@ -344,7 +394,7 @@ Cudd_ApaSetToLiteral(
|
|||
int i;
|
||||
|
||||
for (i = 0; i < digits - 1; i++)
|
||||
number[i] = 0;
|
||||
number[i] = 0;
|
||||
number[digits - 1] = literal;
|
||||
|
||||
} /* end of Cudd_ApaSetToLiteral */
|
||||
|
|
@ -373,7 +423,7 @@ Cudd_ApaPowerOfTwo(
|
|||
int index;
|
||||
|
||||
for (i = 0; i < digits; i++)
|
||||
number[i] = 0;
|
||||
number[i] = 0;
|
||||
i = digits - 1 - power / DD_APA_BITS;
|
||||
if (i < 0) return;
|
||||
index = power & (DD_APA_BITS - 1);
|
||||
|
|
@ -407,14 +457,14 @@ Cudd_ApaCompare(
|
|||
|
||||
/* Find first non-zero in both numbers. */
|
||||
for (firstNZ = 0; firstNZ < digitsFirst; firstNZ++)
|
||||
if (first[firstNZ] != 0) break;
|
||||
if (first[firstNZ] != 0) break;
|
||||
for (secondNZ = 0; secondNZ < digitsSecond; secondNZ++)
|
||||
if (second[secondNZ] != 0) break;
|
||||
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);
|
||||
if (first[firstNZ + i] > second[secondNZ + i]) return(1);
|
||||
else if (first[firstNZ + i] < second[secondNZ + i]) return(-1);
|
||||
}
|
||||
return(0);
|
||||
|
||||
|
|
@ -453,11 +503,13 @@ Cudd_ApaCompareRatios(
|
|||
second = Cudd_NewApaNumber(digitsSecond);
|
||||
secondRem = Cudd_ApaIntDivision(digitsSecond,secondNum,secondDen,second);
|
||||
result = Cudd_ApaCompare(digitsFirst,first,digitsSecond,second);
|
||||
ABC_FREE(first);
|
||||
ABC_FREE(second);
|
||||
if (result == 0) {
|
||||
if ((double)firstRem/firstDen > (double)secondRem/secondDen)
|
||||
return(1);
|
||||
else if ((double)firstRem/firstDen < (double)secondRem/secondDen)
|
||||
return(-1);
|
||||
if ((double)firstRem/firstDen > (double)secondRem/secondDen)
|
||||
return(1);
|
||||
else if ((double)firstRem/firstDen < (double)secondRem/secondDen)
|
||||
return(-1);
|
||||
}
|
||||
return(result);
|
||||
|
||||
|
|
@ -485,9 +537,9 @@ Cudd_ApaPrintHex(
|
|||
int i, result;
|
||||
|
||||
for (i = 0; i < digits; i++) {
|
||||
result = fprintf(fp,DD_APA_HEXPRINT,number[i]);
|
||||
if (result == EOF)
|
||||
return(0);
|
||||
result = fprintf(fp,DD_APA_HEXPRINT,number[i]);
|
||||
if (result == EOF)
|
||||
return(0);
|
||||
}
|
||||
return(1);
|
||||
|
||||
|
|
@ -518,33 +570,33 @@ Cudd_ApaPrintDecimal(
|
|||
unsigned char *decimal;
|
||||
int leadingzero;
|
||||
int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1;
|
||||
|
||||
|
||||
work = Cudd_NewApaNumber(digits);
|
||||
if (work == NULL)
|
||||
return(0);
|
||||
return(0);
|
||||
decimal = ABC_ALLOC(unsigned char, decimalDigits);
|
||||
if (decimal == NULL) {
|
||||
ABC_FREE(work);
|
||||
return(0);
|
||||
ABC_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] = remainder;
|
||||
remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work);
|
||||
decimal[i] = (unsigned char) remainder;
|
||||
}
|
||||
ABC_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) {
|
||||
ABC_FREE(decimal);
|
||||
return(0);
|
||||
leadingzero = leadingzero && (decimal[i] == 0);
|
||||
if ((!leadingzero) || (i == (decimalDigits - 1))) {
|
||||
result = fprintf(fp,"%1d",decimal[i]);
|
||||
if (result == EOF) {
|
||||
ABC_FREE(decimal);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ABC_FREE(decimal);
|
||||
return(1);
|
||||
|
||||
|
|
@ -575,36 +627,36 @@ Cudd_ApaPrintExponential(
|
|||
DdApaNumber work;
|
||||
unsigned char *decimal;
|
||||
int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1;
|
||||
|
||||
|
||||
work = Cudd_NewApaNumber(digits);
|
||||
if (work == NULL)
|
||||
return(0);
|
||||
return(0);
|
||||
decimal = ABC_ALLOC(unsigned char, decimalDigits);
|
||||
if (decimal == NULL) {
|
||||
ABC_FREE(work);
|
||||
return(0);
|
||||
ABC_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] = remainder;
|
||||
if (remainder != 0) first = i; /* keep track of MS non-zero */
|
||||
remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work);
|
||||
decimal[i] = (unsigned char) remainder;
|
||||
if (remainder != 0) first = i; /* keep track of MS non-zero */
|
||||
}
|
||||
ABC_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) {
|
||||
ABC_FREE(decimal);
|
||||
return(0);
|
||||
}
|
||||
result = fprintf(fp,"%s%1d",i == first+1 ? "." : "", decimal[i]);
|
||||
if (result == EOF) {
|
||||
ABC_FREE(decimal);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
ABC_FREE(decimal);
|
||||
result = fprintf(fp,"e+%d",decimalDigits - first - 1);
|
||||
if (result == EOF) {
|
||||
return(0);
|
||||
return(0);
|
||||
}
|
||||
return(1);
|
||||
|
||||
|
|
@ -635,9 +687,9 @@ Cudd_ApaCountMinterm(
|
|||
int nvars,
|
||||
int * digits)
|
||||
{
|
||||
DdApaNumber max, min;
|
||||
DdApaNumber max, min;
|
||||
st_table *table;
|
||||
DdApaNumber i,count;
|
||||
DdApaNumber i,count;
|
||||
|
||||
background = manager->background;
|
||||
zero = Cudd_Not(manager->one);
|
||||
|
|
@ -645,46 +697,46 @@ Cudd_ApaCountMinterm(
|
|||
*digits = Cudd_ApaNumberOfDigits(nvars+1);
|
||||
max = Cudd_NewApaNumber(*digits);
|
||||
if (max == NULL) {
|
||||
return(NULL);
|
||||
return(NULL);
|
||||
}
|
||||
Cudd_ApaPowerOfTwo(*digits,max,nvars);
|
||||
min = Cudd_NewApaNumber(*digits);
|
||||
if (min == NULL) {
|
||||
ABC_FREE(max);
|
||||
return(NULL);
|
||||
ABC_FREE(max);
|
||||
return(NULL);
|
||||
}
|
||||
Cudd_ApaSetToLiteral(*digits,min,0);
|
||||
table = st_init_table(st_ptrcmp, st_ptrhash);;
|
||||
table = st_init_table(st_ptrcmp,st_ptrhash);
|
||||
if (table == NULL) {
|
||||
ABC_FREE(max);
|
||||
ABC_FREE(min);
|
||||
return(NULL);
|
||||
ABC_FREE(max);
|
||||
ABC_FREE(min);
|
||||
return(NULL);
|
||||
}
|
||||
i = cuddApaCountMintermAux(Cudd_Regular(node),*digits,max,min,table);
|
||||
if (i == NULL) {
|
||||
ABC_FREE(max);
|
||||
ABC_FREE(min);
|
||||
st_foreach(table, (ST_PFSR)cuddApaStCountfree, NULL);
|
||||
st_free_table(table);
|
||||
return(NULL);
|
||||
ABC_FREE(max);
|
||||
ABC_FREE(min);
|
||||
st_foreach(table, cuddApaStCountfree, NULL);
|
||||
st_free_table(table);
|
||||
return(NULL);
|
||||
}
|
||||
count = Cudd_NewApaNumber(*digits);
|
||||
if (count == NULL) {
|
||||
ABC_FREE(max);
|
||||
ABC_FREE(min);
|
||||
st_foreach(table, (ST_PFSR)cuddApaStCountfree, NULL);
|
||||
st_free_table(table);
|
||||
if (Cudd_Regular(node)->ref == 1) ABC_FREE(i);
|
||||
return(NULL);
|
||||
ABC_FREE(max);
|
||||
ABC_FREE(min);
|
||||
st_foreach(table, cuddApaStCountfree, NULL);
|
||||
st_free_table(table);
|
||||
if (Cudd_Regular(node)->ref == 1) ABC_FREE(i);
|
||||
return(NULL);
|
||||
}
|
||||
if (Cudd_IsComplement(node)) {
|
||||
(void) Cudd_ApaSubtract(*digits,max,i,count);
|
||||
(void) Cudd_ApaSubtract(*digits,max,i,count);
|
||||
} else {
|
||||
Cudd_ApaCopy(*digits,i,count);
|
||||
Cudd_ApaCopy(*digits,i,count);
|
||||
}
|
||||
ABC_FREE(max);
|
||||
ABC_FREE(min);
|
||||
st_foreach(table, (ST_PFSR)cuddApaStCountfree, NULL);
|
||||
st_foreach(table, cuddApaStCountfree, NULL);
|
||||
st_free_table(table);
|
||||
if (Cudd_Regular(node)->ref == 1) ABC_FREE(i);
|
||||
return(count);
|
||||
|
|
@ -718,11 +770,11 @@ Cudd_ApaPrintMinterm(
|
|||
|
||||
count = Cudd_ApaCountMinterm(dd,node,nvars,&digits);
|
||||
if (count == NULL)
|
||||
return(0);
|
||||
return(0);
|
||||
result = Cudd_ApaPrintDecimal(fp,digits,count);
|
||||
ABC_FREE(count);
|
||||
if (fprintf(fp,"\n") == EOF) {
|
||||
return(0);
|
||||
return(0);
|
||||
}
|
||||
return(result);
|
||||
|
||||
|
|
@ -758,11 +810,11 @@ Cudd_ApaPrintMintermExp(
|
|||
|
||||
count = Cudd_ApaCountMinterm(dd,node,nvars,&digits);
|
||||
if (count == NULL)
|
||||
return(0);
|
||||
return(0);
|
||||
result = Cudd_ApaPrintExponential(fp,digits,count,precision);
|
||||
ABC_FREE(count);
|
||||
if (fprintf(fp,"\n") == EOF) {
|
||||
return(0);
|
||||
return(0);
|
||||
}
|
||||
return(result);
|
||||
|
||||
|
|
@ -796,7 +848,7 @@ Cudd_ApaPrintDensity(
|
|||
|
||||
count = Cudd_ApaCountMinterm(dd,node,nvars,&digits);
|
||||
if (count == NULL)
|
||||
return(0);
|
||||
return(0);
|
||||
size = Cudd_DagSize(node);
|
||||
density = Cudd_NewApaNumber(digits);
|
||||
remainder = Cudd_ApaIntDivision(digits,count,size,density);
|
||||
|
|
@ -805,7 +857,7 @@ Cudd_ApaPrintDensity(
|
|||
ABC_FREE(density);
|
||||
fractional = (unsigned int)((double)remainder / size * 1000000);
|
||||
if (fprintf(fp,".%u\n", fractional) == EOF) {
|
||||
return(0);
|
||||
return(0);
|
||||
}
|
||||
return(result);
|
||||
|
||||
|
|
@ -852,18 +904,18 @@ cuddApaCountMintermAux(
|
|||
st_table * table)
|
||||
{
|
||||
DdNode *Nt, *Ne;
|
||||
DdApaNumber mint, mint1, mint2;
|
||||
DdApaDigit carryout;
|
||||
DdApaNumber mint, mint1, mint2;
|
||||
DdApaDigit carryout;
|
||||
|
||||
if (cuddIsConstant(node)) {
|
||||
if (node == background || node == zero) {
|
||||
return(min);
|
||||
} else {
|
||||
return(max);
|
||||
if (node == background || node == zero) {
|
||||
return(min);
|
||||
} else {
|
||||
return(max);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node->ref > 1 && st_lookup(table, (char *)node, (char **)&mint)) {
|
||||
return(mint);
|
||||
if (node->ref > 1 && st_lookup(table, (const char *)node, (char **)&mint)) {
|
||||
return(mint);
|
||||
}
|
||||
|
||||
Nt = cuddT(node); Ne = cuddE(node);
|
||||
|
|
@ -872,20 +924,20 @@ cuddApaCountMintermAux(
|
|||
if (mint1 == NULL) return(NULL);
|
||||
mint2 = cuddApaCountMintermAux(Cudd_Regular(Ne), digits, max, min, table);
|
||||
if (mint2 == NULL) {
|
||||
if (Nt->ref == 1) ABC_FREE(mint1);
|
||||
return(NULL);
|
||||
if (Nt->ref == 1) ABC_FREE(mint1);
|
||||
return(NULL);
|
||||
}
|
||||
mint = Cudd_NewApaNumber(digits);
|
||||
if (mint == NULL) {
|
||||
if (Nt->ref == 1) ABC_FREE(mint1);
|
||||
if (Cudd_Regular(Ne)->ref == 1) ABC_FREE(mint2);
|
||||
return(NULL);
|
||||
if (Nt->ref == 1) ABC_FREE(mint1);
|
||||
if (Cudd_Regular(Ne)->ref == 1) ABC_FREE(mint2);
|
||||
return(NULL);
|
||||
}
|
||||
if (Cudd_IsComplement(Ne)) {
|
||||
(void) Cudd_ApaSubtract(digits,max,mint2,mint);
|
||||
carryout = Cudd_ApaAdd(digits,mint1,mint,mint);
|
||||
(void) Cudd_ApaSubtract(digits,max,mint2,mint);
|
||||
carryout = Cudd_ApaAdd(digits,mint1,mint,mint);
|
||||
} else {
|
||||
carryout = Cudd_ApaAdd(digits,mint1,mint2,mint);
|
||||
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
|
||||
|
|
@ -893,12 +945,12 @@ cuddApaCountMintermAux(
|
|||
** freed here. */
|
||||
if (Nt->ref == 1) ABC_FREE(mint1);
|
||||
if (Cudd_Regular(Ne)->ref == 1) ABC_FREE(mint2);
|
||||
|
||||
|
||||
if (node->ref > 1) {
|
||||
if (st_insert(table, (char *)node, (char *)mint) == ST_OUT_OF_MEM) {
|
||||
ABC_FREE(mint);
|
||||
return(NULL);
|
||||
}
|
||||
if (st_insert(table, (char *)node, (char *)mint) == ST_OUT_OF_MEM) {
|
||||
ABC_FREE(mint);
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
return(mint);
|
||||
|
||||
|
|
@ -922,7 +974,7 @@ cuddApaStCountfree(
|
|||
char * value,
|
||||
char * arg)
|
||||
{
|
||||
DdApaNumber d;
|
||||
DdApaNumber d;
|
||||
|
||||
d = (DdApaNumber) value;
|
||||
ABC_FREE(d);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -7,31 +7,58 @@
|
|||
Synopsis [Quantification functions for BDDs.]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_bddExistAbstract()
|
||||
<li> Cudd_bddXorExistAbstract()
|
||||
<li> Cudd_bddUnivAbstract()
|
||||
<li> Cudd_bddBooleanDiff()
|
||||
<li> Cudd_bddVarIsDependent()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddBddExistAbstractRecur()
|
||||
<li> cuddBddXorExistAbstractRecur()
|
||||
<li> cuddBddBooleanDiffRecur()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> bddCheckPositiveCube()
|
||||
</ul>
|
||||
]
|
||||
<ul>
|
||||
<li> Cudd_bddExistAbstract()
|
||||
<li> Cudd_bddXorExistAbstract()
|
||||
<li> Cudd_bddUnivAbstract()
|
||||
<li> Cudd_bddBooleanDiff()
|
||||
<li> Cudd_bddVarIsDependent()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddBddExistAbstractRecur()
|
||||
<li> cuddBddXorExistAbstractRecur()
|
||||
<li> cuddBddBooleanDiffRecur()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> bddCheckPositiveCube()
|
||||
</ul>
|
||||
]
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -42,6 +69,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -62,7 +90,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddBddAbs.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddBddAbs.c,v 1.26 2004/08/13 18:04:46 fabio Exp $";
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -76,7 +104,7 @@ static char rcsid[] DD_UNUSED = "$Id: cuddBddAbs.c,v 1.1.1.1 2003/02/24 22:23:51
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static int bddCheckPositiveCube ARGS((DdManager *manager, DdNode *cube));
|
||||
static int bddCheckPositiveCube (DdManager *manager, DdNode *cube);
|
||||
|
||||
/**AutomaticEnd***************************************************************/
|
||||
|
||||
|
|
@ -108,14 +136,14 @@ Cudd_bddExistAbstract(
|
|||
|
||||
if (bddCheckPositiveCube(manager, cube) == 0) {
|
||||
(void) fprintf(manager->err,
|
||||
"Error: Can only abstract positive cubes\n");
|
||||
manager->errorCode = CUDD_INVALID_ARG;
|
||||
"Error: Can only abstract positive cubes\n");
|
||||
manager->errorCode = CUDD_INVALID_ARG;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
do {
|
||||
manager->reordered = 0;
|
||||
res = cuddBddExistAbstractRecur(manager, f, cube);
|
||||
manager->reordered = 0;
|
||||
res = cuddBddExistAbstractRecur(manager, f, cube);
|
||||
} while (manager->reordered == 1);
|
||||
|
||||
return(res);
|
||||
|
|
@ -148,14 +176,14 @@ Cudd_bddXorExistAbstract(
|
|||
|
||||
if (bddCheckPositiveCube(manager, cube) == 0) {
|
||||
(void) fprintf(manager->err,
|
||||
"Error: Can only abstract positive cubes\n");
|
||||
manager->errorCode = CUDD_INVALID_ARG;
|
||||
"Error: Can only abstract positive cubes\n");
|
||||
manager->errorCode = CUDD_INVALID_ARG;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
do {
|
||||
manager->reordered = 0;
|
||||
res = cuddBddXorExistAbstractRecur(manager, f, g, cube);
|
||||
manager->reordered = 0;
|
||||
res = cuddBddXorExistAbstractRecur(manager, f, g, cube);
|
||||
} while (manager->reordered == 1);
|
||||
|
||||
return(res);
|
||||
|
|
@ -181,18 +209,18 @@ Cudd_bddUnivAbstract(
|
|||
DdNode * f,
|
||||
DdNode * cube)
|
||||
{
|
||||
DdNode *res;
|
||||
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);
|
||||
(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);
|
||||
manager->reordered = 0;
|
||||
res = cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube);
|
||||
} while (manager->reordered == 1);
|
||||
if (res != NULL) res = Cudd_Not(res);
|
||||
|
||||
|
|
@ -229,8 +257,8 @@ Cudd_bddBooleanDiff(
|
|||
var = manager->vars[x];
|
||||
|
||||
do {
|
||||
manager->reordered = 0;
|
||||
res = cuddBddBooleanDiffRecur(manager, Cudd_Regular(f), var);
|
||||
manager->reordered = 0;
|
||||
res = cuddBddBooleanDiffRecur(manager, Cudd_Regular(f), var);
|
||||
} while (manager->reordered == 1);
|
||||
|
||||
return(res);
|
||||
|
|
@ -254,13 +282,13 @@ Cudd_bddBooleanDiff(
|
|||
******************************************************************************/
|
||||
int
|
||||
Cudd_bddVarIsDependent(
|
||||
DdManager *dd, /* manager */
|
||||
DdNode *f, /* function */
|
||||
DdNode *var /* variable */)
|
||||
DdManager *dd, /* manager */
|
||||
DdNode *f, /* function */
|
||||
DdNode *var /* variable */)
|
||||
{
|
||||
DdNode *F, *res, *zero, *ft, *fe;
|
||||
unsigned topf, level;
|
||||
DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *);
|
||||
DD_CTFP cacheOp;
|
||||
int retval;
|
||||
|
||||
zero = Cudd_Not(DD_ONE(dd));
|
||||
|
|
@ -274,14 +302,13 @@ Cudd_bddVarIsDependent(
|
|||
/* 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);
|
||||
return(0);
|
||||
}
|
||||
|
||||
cacheOp =
|
||||
(DdNode *(*)(DdManager *, DdNode *, DdNode *)) Cudd_bddVarIsDependent;
|
||||
cacheOp = (DD_CTFP) Cudd_bddVarIsDependent;
|
||||
res = cuddCacheLookup2(dd,cacheOp,f,var);
|
||||
if (res != NULL) {
|
||||
return(res != zero);
|
||||
return(res != zero);
|
||||
}
|
||||
|
||||
/* Compute cofactors. */
|
||||
|
|
@ -289,10 +316,10 @@ Cudd_bddVarIsDependent(
|
|||
fe = Cudd_NotCond(cuddE(F), f != F);
|
||||
|
||||
if (topf == level) {
|
||||
retval = Cudd_bddLeq(dd,ft,Cudd_Not(fe));
|
||||
retval = Cudd_bddLeq(dd,ft,Cudd_Not(fe));
|
||||
} else {
|
||||
retval = Cudd_bddVarIsDependent(dd,ft,var) &&
|
||||
Cudd_bddVarIsDependent(dd,fe,var);
|
||||
retval = Cudd_bddVarIsDependent(dd,ft,var) &&
|
||||
Cudd_bddVarIsDependent(dd,fe,var);
|
||||
}
|
||||
|
||||
cuddCacheInsert2(dd,cacheOp,f,var,Cudd_NotCond(zero,retval));
|
||||
|
|
@ -327,13 +354,13 @@ cuddBddExistAbstractRecur(
|
|||
DdNode * f,
|
||||
DdNode * cube)
|
||||
{
|
||||
DdNode *F, *T, *E, *res, *res1, *res2, *one;
|
||||
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. */
|
||||
/* Cube is guaranteed to be a cube at this point. */
|
||||
if (cube == one || F == one) {
|
||||
return(f);
|
||||
}
|
||||
|
|
@ -341,78 +368,78 @@ cuddBddExistAbstractRecur(
|
|||
|
||||
/* 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);
|
||||
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);
|
||||
return(res);
|
||||
}
|
||||
|
||||
/* Compute the cofactors of f. */
|
||||
T = cuddT(F); E = cuddE(F);
|
||||
if (f != F) {
|
||||
T = Cudd_Not(T); E = Cudd_Not(E);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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) {
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
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
|
||||
/* 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);
|
||||
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 */
|
||||
|
||||
|
|
@ -448,39 +475,39 @@ cuddBddXorExistAbstractRecur(
|
|||
|
||||
/* Terminal cases. */
|
||||
if (f == g) {
|
||||
return(zero);
|
||||
return(zero);
|
||||
}
|
||||
if (f == Cudd_Not(g)) {
|
||||
return(one);
|
||||
return(one);
|
||||
}
|
||||
if (cube == one) {
|
||||
return(cuddBddXorRecur(manager, f, g));
|
||||
return(cuddBddXorRecur(manager, f, g));
|
||||
}
|
||||
if (f == one) {
|
||||
return(cuddBddExistAbstractRecur(manager, Cudd_Not(g), cube));
|
||||
return(cuddBddExistAbstractRecur(manager, Cudd_Not(g), cube));
|
||||
}
|
||||
if (g == one) {
|
||||
return(cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube));
|
||||
return(cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube));
|
||||
}
|
||||
if (f == zero) {
|
||||
return(cuddBddExistAbstractRecur(manager, g, cube));
|
||||
return(cuddBddExistAbstractRecur(manager, g, cube));
|
||||
}
|
||||
if (g == zero) {
|
||||
return(cuddBddExistAbstractRecur(manager, f, cube));
|
||||
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;
|
||||
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);
|
||||
return(r);
|
||||
}
|
||||
|
||||
/* Here we can skip the use of cuddI, because the operands are known
|
||||
|
|
@ -494,38 +521,38 @@ cuddBddXorExistAbstractRecur(
|
|||
topcube = manager->perm[cube->index];
|
||||
|
||||
if (topcube < top) {
|
||||
return(cuddBddXorExistAbstractRecur(manager, f, g, cuddT(cube)));
|
||||
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);
|
||||
}
|
||||
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;
|
||||
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);
|
||||
}
|
||||
gv = cuddT(G);
|
||||
gnv = cuddE(G);
|
||||
if (Cudd_IsComplement(g)) {
|
||||
gv = Cudd_Not(gv);
|
||||
gnv = Cudd_Not(gnv);
|
||||
}
|
||||
} else {
|
||||
gv = gnv = g;
|
||||
gv = gnv = g;
|
||||
}
|
||||
|
||||
if (topcube == top) {
|
||||
Cube = cuddT(cube);
|
||||
Cube = cuddT(cube);
|
||||
} else {
|
||||
Cube = cube;
|
||||
Cube = cube;
|
||||
}
|
||||
|
||||
t = cuddBddXorExistAbstractRecur(manager, fv, gv, Cube);
|
||||
|
|
@ -535,53 +562,53 @@ cuddBddXorExistAbstractRecur(
|
|||
** 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);
|
||||
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);
|
||||
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 (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);
|
||||
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) {
|
||||
cuddRef(r);
|
||||
Cudd_IterDerefBdd(manager, t);
|
||||
Cudd_IterDerefBdd(manager, e);
|
||||
return(NULL);
|
||||
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);
|
||||
cuddDeref(e);
|
||||
cuddDeref(t);
|
||||
}
|
||||
cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, r);
|
||||
return (r);
|
||||
|
|
@ -613,15 +640,15 @@ cuddBddBooleanDiffRecur(
|
|||
|
||||
statLine(manager);
|
||||
if (cuddI(manager,f->index) > manager->perm[var->index]) {
|
||||
/* f does not depend on var. */
|
||||
return(Cudd_Not(DD_ONE(manager)));
|
||||
/* 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));
|
||||
res = cuddBddXorRecur(manager, cuddT(f), cuddE(f));
|
||||
return(res);
|
||||
}
|
||||
|
||||
|
|
@ -630,7 +657,7 @@ cuddBddBooleanDiffRecur(
|
|||
/* Check the cache. */
|
||||
res = cuddCacheLookup2(manager, cuddBddBooleanDiffRecur, f, var);
|
||||
if (res != NULL) {
|
||||
return(res);
|
||||
return(res);
|
||||
}
|
||||
|
||||
/* Compute the cofactors of f. */
|
||||
|
|
@ -641,17 +668,17 @@ cuddBddBooleanDiffRecur(
|
|||
cuddRef(res1);
|
||||
res2 = cuddBddBooleanDiffRecur(manager, Cudd_Regular(E), var);
|
||||
if (res2 == NULL) {
|
||||
Cudd_IterDerefBdd(manager, res1);
|
||||
return(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);
|
||||
Cudd_IterDerefBdd(manager, res1);
|
||||
Cudd_IterDerefBdd(manager, res2);
|
||||
return(NULL);
|
||||
}
|
||||
cuddDeref(res1);
|
||||
cuddDeref(res2);
|
||||
|
|
@ -690,5 +717,7 @@ bddCheckPositiveCube(
|
|||
|
||||
} /* end of bddCheckPositiveCube */
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,26 +7,53 @@
|
|||
Synopsis [Correlation between BDDs.]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_bddCorrelation()
|
||||
<li> Cudd_bddCorrelationWeights()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> bddCorrelationAux()
|
||||
<li> bddCorrelationWeightsAux()
|
||||
<li> CorrelCompare()
|
||||
<li> CorrelHash()
|
||||
<li> CorrelCleanUp()
|
||||
</ul>
|
||||
]
|
||||
<ul>
|
||||
<li> Cudd_bddCorrelation()
|
||||
<li> Cudd_bddCorrelationWeights()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> bddCorrelationAux()
|
||||
<li> bddCorrelationWeightsAux()
|
||||
<li> CorrelCompare()
|
||||
<li> CorrelHash()
|
||||
<li> CorrelCleanUp()
|
||||
</ul>
|
||||
]
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -37,6 +64,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -62,17 +90,20 @@ typedef struct hashEntry {
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddBddCorr.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddBddCorr.c,v 1.14 2004/08/13 18:04:46 fabio Exp $";
|
||||
#endif
|
||||
|
||||
#ifdef CORREL_STATS
|
||||
static int num_calls;
|
||||
static int num_calls;
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Macro declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**AutomaticStart*************************************************************/
|
||||
|
||||
|
|
@ -80,14 +111,18 @@ static int num_calls;
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static double bddCorrelationAux ARGS((DdManager *dd, DdNode *f, DdNode *g, st_table *table));
|
||||
static double bddCorrelationWeightsAux ARGS((DdManager *dd, DdNode *f, DdNode *g, double *prob, st_table *table));
|
||||
static int CorrelCompare ARGS((const char *key1, const char *key2));
|
||||
static int CorrelHash ARGS((const char *key, int modulus));
|
||||
static enum st_retval CorrelCleanUp ARGS((char *key, char *value, char *arg));
|
||||
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 (const char *key, int modulus);
|
||||
static enum st_retval CorrelCleanUp (char *key, char *value, char *arg);
|
||||
|
||||
/**AutomaticEnd***************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Definition of exported functions */
|
||||
|
|
@ -116,7 +151,7 @@ Cudd_bddCorrelation(
|
|||
{
|
||||
|
||||
st_table *table;
|
||||
double correlation;
|
||||
double correlation;
|
||||
|
||||
#ifdef CORREL_STATS
|
||||
num_calls = 0;
|
||||
|
|
@ -125,7 +160,7 @@ Cudd_bddCorrelation(
|
|||
table = st_init_table(CorrelCompare,CorrelHash);
|
||||
if (table == NULL) return((double)CUDD_OUT_OF_MEM);
|
||||
correlation = bddCorrelationAux(manager,f,g,table);
|
||||
st_foreach(table, (ST_PFSR)CorrelCleanUp, NIL(char));
|
||||
st_foreach(table, CorrelCleanUp, NIL(char));
|
||||
st_free_table(table);
|
||||
return(correlation);
|
||||
|
||||
|
|
@ -159,7 +194,7 @@ Cudd_bddCorrelationWeights(
|
|||
{
|
||||
|
||||
st_table *table;
|
||||
double correlation;
|
||||
double correlation;
|
||||
|
||||
#ifdef CORREL_STATS
|
||||
num_calls = 0;
|
||||
|
|
@ -168,7 +203,7 @@ Cudd_bddCorrelationWeights(
|
|||
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, (ST_PFSR)CorrelCleanUp, NIL(char));
|
||||
st_foreach(table, CorrelCleanUp, NIL(char));
|
||||
st_free_table(table);
|
||||
return(correlation);
|
||||
|
||||
|
|
@ -205,9 +240,9 @@ bddCorrelationAux(
|
|||
DdNode * g,
|
||||
st_table * table)
|
||||
{
|
||||
DdNode *Fv, *Fnv, *G, *Gv, *Gnv;
|
||||
double min, *pmin, min1, min2, *dummy;
|
||||
HashEntry *entry;
|
||||
DdNode *Fv, *Fnv, *G, *Gv, *Gnv;
|
||||
double min, *pmin, min1, min2, *dummy;
|
||||
HashEntry *entry;
|
||||
unsigned int topF, topG;
|
||||
|
||||
statLine(dd);
|
||||
|
|
@ -224,19 +259,19 @@ bddCorrelationAux(
|
|||
** (f' EXNOR g') = (f EXNOR g).
|
||||
*/
|
||||
if (f > g) {
|
||||
DdNode *tmp = f;
|
||||
f = g; g = tmp;
|
||||
DdNode *tmp = f;
|
||||
f = g; g = tmp;
|
||||
}
|
||||
if (Cudd_IsComplement(f)) {
|
||||
f = Cudd_Not(f);
|
||||
g = Cudd_Not(g);
|
||||
f = Cudd_Not(f);
|
||||
g = Cudd_Not(g);
|
||||
}
|
||||
/* From now on, f is regular. */
|
||||
|
||||
entry = ABC_ALLOC(HashEntry,1);
|
||||
if (entry == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(CUDD_OUT_OF_MEM);
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(CUDD_OUT_OF_MEM);
|
||||
}
|
||||
entry->f = f; entry->g = g;
|
||||
|
||||
|
|
@ -244,10 +279,10 @@ bddCorrelationAux(
|
|||
** correlation(f,g') = 1 - correlation(f,g)
|
||||
** to minimize the risk of cancellation.
|
||||
*/
|
||||
if (st_lookup(table, (char *)entry, (char **)&dummy)) {
|
||||
min = *dummy;
|
||||
ABC_FREE(entry);
|
||||
return(min);
|
||||
if (st_lookup(table, (const char *)entry, (char **)&dummy)) {
|
||||
min = *dummy;
|
||||
ABC_FREE(entry);
|
||||
return(min);
|
||||
}
|
||||
|
||||
G = Cudd_Regular(g);
|
||||
|
|
@ -256,33 +291,33 @@ bddCorrelationAux(
|
|||
if (topG <= topF) { Gv = cuddT(G); Gnv = cuddE(G); } else { Gv = Gnv = G; }
|
||||
|
||||
if (g != G) {
|
||||
Gv = Cudd_Not(Gv);
|
||||
Gnv = Cudd_Not(Gnv);
|
||||
Gv = Cudd_Not(Gv);
|
||||
Gnv = Cudd_Not(Gnv);
|
||||
}
|
||||
|
||||
min1 = bddCorrelationAux(dd, Fv, Gv, table) / 2.0;
|
||||
if (min1 == (double)CUDD_OUT_OF_MEM) {
|
||||
ABC_FREE(entry);
|
||||
return(CUDD_OUT_OF_MEM);
|
||||
ABC_FREE(entry);
|
||||
return(CUDD_OUT_OF_MEM);
|
||||
}
|
||||
min2 = bddCorrelationAux(dd, Fnv, Gnv, table) / 2.0;
|
||||
if (min2 == (double)CUDD_OUT_OF_MEM) {
|
||||
ABC_FREE(entry);
|
||||
return(CUDD_OUT_OF_MEM);
|
||||
ABC_FREE(entry);
|
||||
return(CUDD_OUT_OF_MEM);
|
||||
}
|
||||
min = (min1+min2);
|
||||
|
||||
pmin = ABC_ALLOC(double,1);
|
||||
if (pmin == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return((double)CUDD_OUT_OF_MEM);
|
||||
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) {
|
||||
ABC_FREE(entry);
|
||||
ABC_FREE(pmin);
|
||||
return((double)CUDD_OUT_OF_MEM);
|
||||
ABC_FREE(entry);
|
||||
ABC_FREE(pmin);
|
||||
return((double)CUDD_OUT_OF_MEM);
|
||||
}
|
||||
return(min);
|
||||
|
||||
|
|
@ -308,10 +343,10 @@ bddCorrelationWeightsAux(
|
|||
double * prob,
|
||||
st_table * table)
|
||||
{
|
||||
DdNode *Fv, *Fnv, *G, *Gv, *Gnv;
|
||||
double min, *pmin, min1, min2, *dummy;
|
||||
HashEntry *entry;
|
||||
int topF, topG, index;
|
||||
DdNode *Fv, *Fnv, *G, *Gv, *Gnv;
|
||||
double min, *pmin, min1, min2, *dummy;
|
||||
HashEntry *entry;
|
||||
int topF, topG, index;
|
||||
|
||||
statLine(dd);
|
||||
#ifdef CORREL_STATS
|
||||
|
|
@ -327,19 +362,19 @@ bddCorrelationWeightsAux(
|
|||
** (f' EXNOR g') = (f EXNOR g).
|
||||
*/
|
||||
if (f > g) {
|
||||
DdNode *tmp = f;
|
||||
f = g; g = tmp;
|
||||
DdNode *tmp = f;
|
||||
f = g; g = tmp;
|
||||
}
|
||||
if (Cudd_IsComplement(f)) {
|
||||
f = Cudd_Not(f);
|
||||
g = Cudd_Not(g);
|
||||
f = Cudd_Not(f);
|
||||
g = Cudd_Not(g);
|
||||
}
|
||||
/* From now on, f is regular. */
|
||||
|
||||
entry = ABC_ALLOC(HashEntry,1);
|
||||
if (entry == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return((double)CUDD_OUT_OF_MEM);
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return((double)CUDD_OUT_OF_MEM);
|
||||
}
|
||||
entry->f = f; entry->g = g;
|
||||
|
||||
|
|
@ -347,51 +382,51 @@ bddCorrelationWeightsAux(
|
|||
** correlation(f,g') = 1 - correlation(f,g)
|
||||
** to minimize the risk of cancellation.
|
||||
*/
|
||||
if (st_lookup(table, (char *)entry, (char **)&dummy)) {
|
||||
min = *dummy;
|
||||
ABC_FREE(entry);
|
||||
return(min);
|
||||
if (st_lookup(table, (const char *)entry, (char **)&dummy)) {
|
||||
min = *dummy;
|
||||
ABC_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;
|
||||
Fv = cuddT(f); Fnv = cuddE(f);
|
||||
index = f->index;
|
||||
} else {
|
||||
Fv = Fnv = f;
|
||||
index = G->index;
|
||||
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);
|
||||
Gv = Cudd_Not(Gv);
|
||||
Gnv = Cudd_Not(Gnv);
|
||||
}
|
||||
|
||||
min1 = bddCorrelationWeightsAux(dd, Fv, Gv, prob, table) * prob[index];
|
||||
if (min1 == (double)CUDD_OUT_OF_MEM) {
|
||||
ABC_FREE(entry);
|
||||
return((double)CUDD_OUT_OF_MEM);
|
||||
ABC_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) {
|
||||
ABC_FREE(entry);
|
||||
return((double)CUDD_OUT_OF_MEM);
|
||||
ABC_FREE(entry);
|
||||
return((double)CUDD_OUT_OF_MEM);
|
||||
}
|
||||
min = (min1+min2);
|
||||
|
||||
pmin = ABC_ALLOC(double,1);
|
||||
if (pmin == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return((double)CUDD_OUT_OF_MEM);
|
||||
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) {
|
||||
ABC_FREE(entry);
|
||||
ABC_FREE(pmin);
|
||||
return((double)CUDD_OUT_OF_MEM);
|
||||
ABC_FREE(entry);
|
||||
ABC_FREE(pmin);
|
||||
return((double)CUDD_OUT_OF_MEM);
|
||||
}
|
||||
return(min);
|
||||
|
||||
|
|
@ -440,10 +475,10 @@ CorrelHash(
|
|||
const char * key,
|
||||
int modulus)
|
||||
{
|
||||
const HashEntry *entry;
|
||||
HashEntry *entry;
|
||||
int val = 0;
|
||||
|
||||
entry = (const HashEntry *) key;
|
||||
entry = (HashEntry *) key;
|
||||
#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
|
||||
val = ((int) ((long)entry->f))*997 + ((int) ((long)entry->g));
|
||||
#else
|
||||
|
|
@ -471,7 +506,7 @@ CorrelCleanUp(
|
|||
char * value,
|
||||
char * arg)
|
||||
{
|
||||
double *d;
|
||||
double *d;
|
||||
HashEntry *entry;
|
||||
|
||||
entry = (HashEntry *) key;
|
||||
|
|
@ -482,5 +517,7 @@ CorrelCleanUp(
|
|||
|
||||
} /* end of CorrelCleanUp */
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -8,48 +8,76 @@
|
|||
different managers.]
|
||||
|
||||
Description [External procedures included in this file:
|
||||
<ul>
|
||||
<li> Cudd_addBddThreshold()
|
||||
<li> Cudd_addBddStrictThreshold()
|
||||
<li> Cudd_addBddInterval()
|
||||
<li> Cudd_addBddIthBit()
|
||||
<li> Cudd_BddToAdd()
|
||||
<li> Cudd_addBddPattern()
|
||||
<li> Cudd_bddTransfer()
|
||||
</ul>
|
||||
Internal procedures included in this file:
|
||||
<ul>
|
||||
<li> cuddBddTransfer()
|
||||
<li> cuddAddBddDoPattern()
|
||||
</ul>
|
||||
Static procedures included in this file:
|
||||
<ul>
|
||||
<li> addBddDoThreshold()
|
||||
<li> addBddDoStrictThreshold()
|
||||
<li> addBddDoInterval()
|
||||
<li> addBddDoIthBit()
|
||||
<li> ddBddToAddRecur()
|
||||
<li> cuddBddTransferRecur()
|
||||
</ul>
|
||||
]
|
||||
<ul>
|
||||
<li> Cudd_addBddThreshold()
|
||||
<li> Cudd_addBddStrictThreshold()
|
||||
<li> Cudd_addBddInterval()
|
||||
<li> Cudd_addBddIthBit()
|
||||
<li> Cudd_BddToAdd()
|
||||
<li> Cudd_addBddPattern()
|
||||
<li> Cudd_bddTransfer()
|
||||
</ul>
|
||||
Internal procedures included in this file:
|
||||
<ul>
|
||||
<li> cuddBddTransfer()
|
||||
<li> cuddAddBddDoPattern()
|
||||
</ul>
|
||||
Static procedures included in this file:
|
||||
<ul>
|
||||
<li> addBddDoThreshold()
|
||||
<li> addBddDoStrictThreshold()
|
||||
<li> addBddDoInterval()
|
||||
<li> addBddDoIthBit()
|
||||
<li> ddBddToAddRecur()
|
||||
<li> cuddBddTransferRecur()
|
||||
</ul>
|
||||
]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [ This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -70,7 +98,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddBridge.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddBridge.c,v 1.19 2008/04/25 06:42:55 fabio Exp $";
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -78,21 +106,29 @@ static char rcsid[] DD_UNUSED = "$Id: cuddBridge.c,v 1.1.1.1 2003/02/24 22:23:51
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**AutomaticStart*************************************************************/
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static DdNode * addBddDoThreshold ARGS((DdManager *dd, DdNode *f, DdNode *val));
|
||||
static DdNode * addBddDoStrictThreshold ARGS((DdManager *dd, DdNode *f, DdNode *val));
|
||||
static DdNode * addBddDoInterval ARGS((DdManager *dd, DdNode *f, DdNode *l, DdNode *u));
|
||||
static DdNode * addBddDoIthBit ARGS((DdManager *dd, DdNode *f, DdNode *index));
|
||||
static DdNode * ddBddToAddRecur ARGS((DdManager *dd, DdNode *B));
|
||||
static DdNode * cuddBddTransferRecur ARGS((DdManager *ddS, DdManager *ddD, DdNode *f, st_table *table));
|
||||
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 */
|
||||
|
|
@ -128,13 +164,13 @@ Cudd_addBddThreshold(
|
|||
cuddRef(val);
|
||||
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = addBddDoThreshold(dd, f, val);
|
||||
dd->reordered = 0;
|
||||
res = addBddDoThreshold(dd, f, val);
|
||||
} while (dd->reordered == 1);
|
||||
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDeref(dd, val);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(dd, val);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDeref(dd, val);
|
||||
|
|
@ -173,13 +209,13 @@ Cudd_addBddStrictThreshold(
|
|||
cuddRef(val);
|
||||
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = addBddDoStrictThreshold(dd, f, val);
|
||||
dd->reordered = 0;
|
||||
res = addBddDoStrictThreshold(dd, f, val);
|
||||
} while (dd->reordered == 1);
|
||||
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDeref(dd, val);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(dd, val);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDeref(dd, val);
|
||||
|
|
@ -223,20 +259,20 @@ Cudd_addBddInterval(
|
|||
cuddRef(l);
|
||||
u = cuddUniqueConst(dd,upper);
|
||||
if (u == NULL) {
|
||||
Cudd_RecursiveDeref(dd,l);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(dd,l);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(u);
|
||||
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = addBddDoInterval(dd, f, l, u);
|
||||
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);
|
||||
Cudd_RecursiveDeref(dd, l);
|
||||
Cudd_RecursiveDeref(dd, u);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDeref(dd, l);
|
||||
|
|
@ -280,13 +316,13 @@ Cudd_addBddIthBit(
|
|||
cuddRef(index);
|
||||
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = addBddDoIthBit(dd, f, index);
|
||||
dd->reordered = 0;
|
||||
res = addBddDoIthBit(dd, f, index);
|
||||
} while (dd->reordered == 1);
|
||||
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDeref(dd, index);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(dd, index);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDeref(dd, index);
|
||||
|
|
@ -317,8 +353,8 @@ Cudd_BddToAdd(
|
|||
DdNode *res;
|
||||
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = ddBddToAddRecur(dd, B);
|
||||
dd->reordered = 0;
|
||||
res = ddBddToAddRecur(dd, B);
|
||||
} while (dd->reordered ==1);
|
||||
return(res);
|
||||
|
||||
|
|
@ -347,8 +383,8 @@ Cudd_addBddPattern(
|
|||
DdNode *res;
|
||||
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = cuddAddBddDoPattern(dd, f);
|
||||
dd->reordered = 0;
|
||||
res = cuddAddBddDoPattern(dd, f);
|
||||
} while (dd->reordered == 1);
|
||||
return(res);
|
||||
|
||||
|
|
@ -377,8 +413,8 @@ Cudd_bddTransfer(
|
|||
{
|
||||
DdNode *res;
|
||||
do {
|
||||
ddDestination->reordered = 0;
|
||||
res = cuddBddTransfer(ddSource, ddDestination, f);
|
||||
ddDestination->reordered = 0;
|
||||
res = cuddBddTransfer(ddSource, ddDestination, f);
|
||||
} while (ddDestination->reordered == 1);
|
||||
return(res);
|
||||
|
||||
|
|
@ -414,7 +450,7 @@ cuddBddTransfer(
|
|||
st_generator *gen = NULL;
|
||||
DdNode *key, *value;
|
||||
|
||||
table = st_init_table(st_ptrcmp, st_ptrhash);;
|
||||
table = st_init_table(st_ptrcmp,st_ptrhash);
|
||||
if (table == NULL) goto failure;
|
||||
res = cuddBddTransferRecur(ddS, ddD, f, table);
|
||||
if (res != NULL) cuddRef(res);
|
||||
|
|
@ -424,8 +460,8 @@ cuddBddTransfer(
|
|||
** reordering. */
|
||||
gen = st_init_gen(table);
|
||||
if (gen == NULL) goto failure;
|
||||
while (st_gen(gen, (const char **) &key, (char **) &value)) {
|
||||
Cudd_RecursiveDeref(ddD, value);
|
||||
while (st_gen(gen, (const char **)&key, (char **)&value)) {
|
||||
Cudd_RecursiveDeref(ddD, value);
|
||||
}
|
||||
st_free_gen(gen); gen = NULL;
|
||||
st_free_table(table); table = NULL;
|
||||
|
|
@ -434,8 +470,8 @@ cuddBddTransfer(
|
|||
return(res);
|
||||
|
||||
failure:
|
||||
/* No need to free gen because it is always NULL here. */
|
||||
if (table != NULL) st_free_table(table);
|
||||
if (gen != NULL) st_free_gen(gen);
|
||||
return(NULL);
|
||||
|
||||
} /* end of cuddBddTransfer */
|
||||
|
|
@ -465,7 +501,7 @@ cuddAddBddDoPattern(
|
|||
statLine(dd);
|
||||
/* Check terminal case. */
|
||||
if (cuddIsConstant(f)) {
|
||||
return(Cudd_NotCond(DD_ONE(dd),f == DD_ZERO(dd)));
|
||||
return(Cudd_NotCond(DD_ONE(dd),f == DD_ZERO(dd)));
|
||||
}
|
||||
|
||||
/* Check cache. */
|
||||
|
|
@ -482,25 +518,25 @@ cuddAddBddDoPattern(
|
|||
|
||||
E = cuddAddBddDoPattern(dd,fvn);
|
||||
if (E == NULL) {
|
||||
Cudd_RecursiveDeref(dd, T);
|
||||
return(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);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
|
@ -543,7 +579,7 @@ addBddDoThreshold(
|
|||
statLine(dd);
|
||||
/* Check terminal case. */
|
||||
if (cuddIsConstant(f)) {
|
||||
return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(val)));
|
||||
return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(val)));
|
||||
}
|
||||
|
||||
/* Check cache. */
|
||||
|
|
@ -560,25 +596,25 @@ addBddDoThreshold(
|
|||
|
||||
E = addBddDoThreshold(dd,fvn,val);
|
||||
if (E == NULL) {
|
||||
Cudd_RecursiveDeref(dd, T);
|
||||
return(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);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
|
@ -616,7 +652,7 @@ addBddDoStrictThreshold(
|
|||
statLine(dd);
|
||||
/* Check terminal case. */
|
||||
if (cuddIsConstant(f)) {
|
||||
return(Cudd_NotCond(DD_ONE(dd),cuddV(f) <= cuddV(val)));
|
||||
return(Cudd_NotCond(DD_ONE(dd),cuddV(f) <= cuddV(val)));
|
||||
}
|
||||
|
||||
/* Check cache. */
|
||||
|
|
@ -633,25 +669,25 @@ addBddDoStrictThreshold(
|
|||
|
||||
E = addBddDoStrictThreshold(dd,fvn,val);
|
||||
if (E == NULL) {
|
||||
Cudd_RecursiveDeref(dd, T);
|
||||
return(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);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
|
@ -690,7 +726,7 @@ addBddDoInterval(
|
|||
statLine(dd);
|
||||
/* Check terminal case. */
|
||||
if (cuddIsConstant(f)) {
|
||||
return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(l) || cuddV(f) > cuddV(u)));
|
||||
return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(l) || cuddV(f) > cuddV(u)));
|
||||
}
|
||||
|
||||
/* Check cache. */
|
||||
|
|
@ -707,25 +743,25 @@ addBddDoInterval(
|
|||
|
||||
E = addBddDoInterval(dd,fvn,l,u);
|
||||
if (E == NULL) {
|
||||
Cudd_RecursiveDeref(dd, T);
|
||||
return(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);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
|
@ -764,9 +800,9 @@ addBddDoIthBit(
|
|||
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));
|
||||
mask = 1 << ((int) cuddV(index));
|
||||
value = (int) cuddV(f);
|
||||
return(Cudd_NotCond(DD_ONE(dd),(value & mask) == 0));
|
||||
}
|
||||
|
||||
/* Check cache. */
|
||||
|
|
@ -783,25 +819,25 @@ addBddDoIthBit(
|
|||
|
||||
E = addBddDoIthBit(dd,fvn,index);
|
||||
if (E == NULL) {
|
||||
Cudd_RecursiveDeref(dd, T);
|
||||
return(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);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
|
@ -839,24 +875,24 @@ ddBddToAddRecur(
|
|||
one = DD_ONE(dd);
|
||||
|
||||
if (Cudd_IsConstant(B)) {
|
||||
if (B == one) {
|
||||
res = one;
|
||||
} else {
|
||||
res = DD_ZERO(dd);
|
||||
}
|
||||
return(res);
|
||||
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));
|
||||
complement = 1;
|
||||
Bt = cuddT(Cudd_Regular(B));
|
||||
Be = cuddE(Cudd_Regular(B));
|
||||
} else {
|
||||
Bt = cuddT(B);
|
||||
Be = cuddE(B);
|
||||
Bt = cuddT(B);
|
||||
Be = cuddE(B);
|
||||
}
|
||||
|
||||
T = ddBddToAddRecur(dd, Bt);
|
||||
|
|
@ -865,32 +901,32 @@ ddBddToAddRecur(
|
|||
|
||||
E = ddBddToAddRecur(dd, Be);
|
||||
if (E == NULL) {
|
||||
Cudd_RecursiveDeref(dd, T);
|
||||
return(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);
|
||||
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) {
|
||||
cuddRef(res);
|
||||
res1 = cuddAddCmplRecur(dd, res);
|
||||
if (res1 == NULL) {
|
||||
Cudd_RecursiveDeref(dd, res);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res1);
|
||||
Cudd_RecursiveDeref(dd, res);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res1);
|
||||
Cudd_RecursiveDeref(dd, res);
|
||||
res = res1;
|
||||
cuddDeref(res);
|
||||
res = res1;
|
||||
cuddDeref(res);
|
||||
}
|
||||
|
||||
/* Store result. */
|
||||
|
|
@ -922,7 +958,7 @@ cuddBddTransferRecur(
|
|||
{
|
||||
DdNode *ft, *fe, *t, *e, *var, *res;
|
||||
DdNode *one, *zero;
|
||||
int index;
|
||||
int index;
|
||||
int comple = 0;
|
||||
|
||||
statLine(ddD);
|
||||
|
|
@ -937,8 +973,8 @@ cuddBddTransferRecur(
|
|||
/* Now f is a regular pointer to a non-constant node. */
|
||||
|
||||
/* Check the cache. */
|
||||
if(st_lookup(table, (char *)f, (char **) &res))
|
||||
return(Cudd_NotCond(res,comple));
|
||||
if (st_lookup(table, (const char *)f, (char **)&res))
|
||||
return(Cudd_NotCond(res,comple));
|
||||
|
||||
/* Recursive step. */
|
||||
index = f->index;
|
||||
|
|
@ -960,27 +996,29 @@ cuddBddTransferRecur(
|
|||
zero = Cudd_Not(one);
|
||||
var = cuddUniqueInter(ddD,index,one,zero);
|
||||
if (var == NULL) {
|
||||
Cudd_RecursiveDeref(ddD, t);
|
||||
Cudd_RecursiveDeref(ddD, e);
|
||||
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);
|
||||
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);
|
||||
Cudd_RecursiveDeref(ddD, res);
|
||||
return(NULL);
|
||||
}
|
||||
return(Cudd_NotCond(res,comple));
|
||||
|
||||
} /* end of cuddBddTransferRecur */
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,41 +7,69 @@
|
|||
Synopsis [Functions for cache insertion and lookup.]
|
||||
|
||||
Description [Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddInitCache()
|
||||
<li> cuddCacheInsert()
|
||||
<li> cuddCacheInsert2()
|
||||
<li> cuddCacheLookup()
|
||||
<li> cuddCacheLookupZdd()
|
||||
<li> cuddCacheLookup2()
|
||||
<li> cuddCacheLookup2Zdd()
|
||||
<li> cuddConstantLookup()
|
||||
<li> cuddCacheProfile()
|
||||
<li> cuddCacheResize()
|
||||
<li> cuddCacheFlush()
|
||||
<li> cuddComputeFloorLog2()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
</ul> ]
|
||||
<ul>
|
||||
<li> cuddInitCache()
|
||||
<li> cuddCacheInsert()
|
||||
<li> cuddCacheInsert2()
|
||||
<li> cuddCacheLookup()
|
||||
<li> cuddCacheLookupZdd()
|
||||
<li> cuddCacheLookup2()
|
||||
<li> cuddCacheLookup2Zdd()
|
||||
<li> cuddConstantLookup()
|
||||
<li> cuddCacheProfile()
|
||||
<li> cuddCacheResize()
|
||||
<li> cuddCacheFlush()
|
||||
<li> cuddComputeFloorLog2()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
</ul> ]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [ This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -65,7 +93,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddCache.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddCache.c,v 1.34 2009/02/19 16:17:50 fabio Exp $";
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -123,8 +151,8 @@ cuddInitCache(
|
|||
cacheSize = 1 << logSize;
|
||||
unique->acache = ABC_ALLOC(DdCache,cacheSize+1);
|
||||
if (unique->acache == NULL) {
|
||||
unique->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
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
|
||||
|
|
@ -145,8 +173,8 @@ cuddInitCache(
|
|||
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;
|
||||
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);
|
||||
|
|
@ -163,10 +191,10 @@ cuddInitCache(
|
|||
|
||||
/* Initialize the cache */
|
||||
for (i = 0; (unsigned) i < cacheSize; i++) {
|
||||
unique->cache[i].h = 0; /* unused slots */
|
||||
unique->cache[i].data = NULL; /* invalid entry */
|
||||
unique->cache[i].h = 0; /* unused slots */
|
||||
unique->cache[i].data = NULL; /* invalid entry */
|
||||
#ifdef DD_CACHE_PROFILE
|
||||
unique->cache[i].count = 0;
|
||||
unique->cache[i].count = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -235,7 +263,7 @@ cuddCacheInsert(
|
|||
void
|
||||
cuddCacheInsert2(
|
||||
DdManager * table,
|
||||
DdNode * (*op)(DdManager *, DdNode *, DdNode *),
|
||||
DD_CTFP op,
|
||||
DdNode * f,
|
||||
DdNode * g,
|
||||
DdNode * data)
|
||||
|
|
@ -277,7 +305,7 @@ cuddCacheInsert2(
|
|||
void
|
||||
cuddCacheInsert1(
|
||||
DdManager * table,
|
||||
DdNode * (*op)(DdManager *, DdNode *),
|
||||
DD_CTFP1 op,
|
||||
DdNode * f,
|
||||
DdNode * data)
|
||||
{
|
||||
|
|
@ -343,21 +371,21 @@ cuddCacheLookup(
|
|||
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);
|
||||
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);
|
||||
table->cacheHits > table->cacheMisses * table->minHit) {
|
||||
cuddCacheResize(table);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
|
|
@ -405,21 +433,21 @@ cuddCacheLookupZdd(
|
|||
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);
|
||||
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);
|
||||
table->cacheHits > table->cacheMisses * table->minHit) {
|
||||
cuddCacheResize(table);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
|
|
@ -443,7 +471,7 @@ cuddCacheLookupZdd(
|
|||
DdNode *
|
||||
cuddCacheLookup2(
|
||||
DdManager * table,
|
||||
DdNode * (*op)(DdManager *, DdNode *, DdNode *),
|
||||
DD_CTFP op,
|
||||
DdNode * f,
|
||||
DdNode * g)
|
||||
{
|
||||
|
|
@ -461,20 +489,20 @@ cuddCacheLookup2(
|
|||
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);
|
||||
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);
|
||||
table->cacheHits > table->cacheMisses * table->minHit) {
|
||||
cuddCacheResize(table);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
|
|
@ -497,7 +525,7 @@ cuddCacheLookup2(
|
|||
DdNode *
|
||||
cuddCacheLookup1(
|
||||
DdManager * table,
|
||||
DdNode * (*op)(DdManager *, DdNode *),
|
||||
DD_CTFP1 op,
|
||||
DdNode * f)
|
||||
{
|
||||
int posn;
|
||||
|
|
@ -514,20 +542,20 @@ cuddCacheLookup1(
|
|||
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);
|
||||
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);
|
||||
table->cacheHits > table->cacheMisses * table->minHit) {
|
||||
cuddCacheResize(table);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
|
|
@ -551,7 +579,7 @@ cuddCacheLookup1(
|
|||
DdNode *
|
||||
cuddCacheLookup2Zdd(
|
||||
DdManager * table,
|
||||
DdNode * (*op)(DdManager *, DdNode *, DdNode *),
|
||||
DD_CTFP op,
|
||||
DdNode * f,
|
||||
DdNode * g)
|
||||
{
|
||||
|
|
@ -569,20 +597,20 @@ cuddCacheLookup2Zdd(
|
|||
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);
|
||||
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);
|
||||
table->cacheHits > table->cacheMisses * table->minHit) {
|
||||
cuddCacheResize(table);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
|
|
@ -605,7 +633,7 @@ cuddCacheLookup2Zdd(
|
|||
DdNode *
|
||||
cuddCacheLookup1Zdd(
|
||||
DdManager * table,
|
||||
DdNode * (*op)(DdManager *, DdNode *),
|
||||
DD_CTFP1 op,
|
||||
DdNode * f)
|
||||
{
|
||||
int posn;
|
||||
|
|
@ -622,20 +650,20 @@ cuddCacheLookup1Zdd(
|
|||
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);
|
||||
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);
|
||||
table->cacheHits > table->cacheMisses * table->minHit) {
|
||||
cuddCacheResize(table);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
|
|
@ -688,8 +716,8 @@ cuddConstantLookup(
|
|||
* 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++;
|
||||
en->f == (DdNodePtr)uf && en->g == (DdNodePtr)ug && en->h == uh) {
|
||||
table->cacheHits++;
|
||||
return(en->data);
|
||||
}
|
||||
|
||||
|
|
@ -697,8 +725,8 @@ cuddConstantLookup(
|
|||
table->cacheMisses++;
|
||||
|
||||
if (table->cacheSlack >= 0 &&
|
||||
table->cacheHits > table->cacheMisses * table->minHit) {
|
||||
cuddCacheResize(table);
|
||||
table->cacheHits > table->cacheMisses * table->minHit) {
|
||||
cuddCacheResize(table);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
|
|
@ -746,46 +774,46 @@ cuddCacheProfile(
|
|||
|
||||
hystogramQ = ABC_ALLOC(double, nbins);
|
||||
if (hystogramQ == NULL) {
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
hystogramR = ABC_ALLOC(double, nbins);
|
||||
if (hystogramR == NULL) {
|
||||
ABC_FREE(hystogramQ);
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
ABC_FREE(hystogramQ);
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
for (i = 0; i < nbins; i++) {
|
||||
hystogramQ[i] = 0;
|
||||
hystogramR[i] = 0;
|
||||
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;
|
||||
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);
|
||||
|
|
@ -803,43 +831,43 @@ cuddCacheProfile(
|
|||
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);
|
||||
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]);
|
||||
expected /= totalcount;
|
||||
retval = fprintf(fp,"Cache access hystogram for %d bins", nbins);
|
||||
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]);
|
||||
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);
|
||||
}
|
||||
retval = fprintf(fp,"\n");
|
||||
if (retval == EOF) return(0);
|
||||
}
|
||||
|
||||
ABC_FREE(hystogramQ);
|
||||
ABC_FREE(hystogramR);
|
||||
#else
|
||||
for (i = 0; i < slots; i++) {
|
||||
nzeroes += cache[i].h == 0;
|
||||
nzeroes += cache[i].h == 0;
|
||||
}
|
||||
exUsed = 100.0 *
|
||||
(1.0 - exp(-(table->cacheinserts - table->cacheLastInserts) /
|
||||
(double) slots));
|
||||
(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);
|
||||
100.0 - (double) nzeroes * 100.0 / (double) slots,
|
||||
exUsed);
|
||||
if (retval == EOF) return(0);
|
||||
#endif
|
||||
return(1);
|
||||
|
|
@ -868,8 +896,8 @@ cuddCacheResize(
|
|||
unsigned int slots, oldslots;
|
||||
double offset;
|
||||
int moved = 0;
|
||||
// extern void (*MMoutOfMemory)(long);
|
||||
void (*saveHandler)(long);
|
||||
extern DD_OOMFP MMoutOfMemory;
|
||||
DD_OOMFP saveHandler;
|
||||
#ifndef DD_CACHE_PROFILE
|
||||
ptruint misalignment;
|
||||
DdNodePtr *mem;
|
||||
|
|
@ -882,11 +910,11 @@ cuddCacheResize(
|
|||
|
||||
#ifdef DD_VERBOSE
|
||||
(void) fprintf(table->err,"Resizing the cache from %d to %d entries\n",
|
||||
oldslots, slots);
|
||||
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));
|
||||
"\thits = %g\tmisses = %g\thit ratio = %5.3f\n",
|
||||
table->cacheHits, table->cacheMisses,
|
||||
table->cacheHits / (table->cacheHits + table->cacheMisses));
|
||||
#endif
|
||||
|
||||
saveHandler = MMoutOfMemory;
|
||||
|
|
@ -896,14 +924,14 @@ cuddCacheResize(
|
|||
/* 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");
|
||||
(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;
|
||||
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
|
||||
|
|
@ -923,28 +951,28 @@ cuddCacheResize(
|
|||
|
||||
/* Clear new cache. */
|
||||
for (i = 0; (unsigned) i < slots; i++) {
|
||||
cache[i].data = NULL;
|
||||
cache[i].h = 0;
|
||||
cache[i].data = NULL;
|
||||
cache[i].h = 0;
|
||||
#ifdef DD_CACHE_PROFILE
|
||||
cache[i].count = 0;
|
||||
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;
|
||||
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;
|
||||
entry->count = 1;
|
||||
#endif
|
||||
moved++;
|
||||
}
|
||||
moved++;
|
||||
}
|
||||
}
|
||||
|
||||
ABC_FREE(oldacache);
|
||||
|
|
@ -983,8 +1011,8 @@ cuddCacheFlush(
|
|||
slots = table->cacheSlots;
|
||||
cache = table->cache;
|
||||
for (i = 0; i < slots; i++) {
|
||||
table->cachedeletions += cache[i].data != NULL;
|
||||
cache[i].data = NULL;
|
||||
table->cachedeletions += cache[i].data != NULL;
|
||||
cache[i].data = NULL;
|
||||
}
|
||||
table->cacheLastInserts = table->cacheinserts;
|
||||
|
||||
|
|
@ -1014,8 +1042,8 @@ cuddComputeFloorLog2(
|
|||
assert(value > 0);
|
||||
#endif
|
||||
while (value > 1) {
|
||||
floorLog++;
|
||||
value >>= 1;
|
||||
floorLog++;
|
||||
value >>= 1;
|
||||
}
|
||||
return(floorLog);
|
||||
|
||||
|
|
@ -1024,5 +1052,7 @@ cuddComputeFloorLog2(
|
|||
/*---------------------------------------------------------------------------*/
|
||||
/* Definition of static functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -7,29 +7,56 @@
|
|||
Synopsis [Clipping functions.]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_bddClippingAnd()
|
||||
<li> Cudd_bddClippingAndAbstract()
|
||||
</ul>
|
||||
<ul>
|
||||
<li> Cudd_bddClippingAnd()
|
||||
<li> Cudd_bddClippingAndAbstract()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddBddClippingAnd()
|
||||
<li> cuddBddClippingAndAbstract()
|
||||
</ul>
|
||||
<ul>
|
||||
<li> cuddBddClippingAnd()
|
||||
<li> cuddBddClippingAndAbstract()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddBddClippingAndRecur()
|
||||
<li> cuddBddClipAndAbsRecur()
|
||||
</ul>
|
||||
<ul>
|
||||
<li> cuddBddClippingAndRecur()
|
||||
<li> cuddBddClipAndAbsRecur()
|
||||
</ul>
|
||||
|
||||
SeeAlso []
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -40,6 +67,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -59,7 +87,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddClip.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddClip.c,v 1.8 2004/08/13 18:04:47 fabio Exp $";
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -73,8 +101,8 @@ static char rcsid[] DD_UNUSED = "$Id: cuddClip.c,v 1.1.1.1 2003/02/24 22:23:51 w
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static DdNode * cuddBddClippingAndRecur ARGS((DdManager *manager, DdNode *f, DdNode *g, int distance, int direction));
|
||||
static DdNode * cuddBddClipAndAbsRecur ARGS((DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, int distance, int direction));
|
||||
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***************************************************************/
|
||||
|
||||
|
|
@ -108,8 +136,8 @@ Cudd_bddClippingAnd(
|
|||
DdNode *res;
|
||||
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = cuddBddClippingAnd(dd,f,g,maxDepth,direction);
|
||||
dd->reordered = 0;
|
||||
res = cuddBddClippingAnd(dd,f,g,maxDepth,direction);
|
||||
} while (dd->reordered == 1);
|
||||
return(res);
|
||||
|
||||
|
|
@ -143,8 +171,8 @@ Cudd_bddClippingAndAbstract(
|
|||
DdNode *res;
|
||||
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = cuddBddClippingAndAbstract(dd,f,g,cube,maxDepth,direction);
|
||||
dd->reordered = 0;
|
||||
res = cuddBddClippingAndAbstract(dd,f,g,cube,maxDepth,direction);
|
||||
} while (dd->reordered == 1);
|
||||
return(res);
|
||||
|
||||
|
|
@ -248,7 +276,7 @@ cuddBddClippingAndRecur(
|
|||
DdNode *F, *ft, *fe, *G, *gt, *ge;
|
||||
DdNode *one, *zero, *r, *t, *e;
|
||||
unsigned int topf, topg, index;
|
||||
DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *);
|
||||
DD_CTFP cacheOp;
|
||||
|
||||
statLine(manager);
|
||||
one = DD_ONE(manager);
|
||||
|
|
@ -259,15 +287,15 @@ cuddBddClippingAndRecur(
|
|||
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)));
|
||||
/* 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. */
|
||||
|
|
@ -276,16 +304,16 @@ cuddBddClippingAndRecur(
|
|||
/* Check cache. Try to increase cache efficiency by sorting the
|
||||
** pointers. */
|
||||
if (f > g) {
|
||||
DdNode *tmp = f;
|
||||
f = g; g = tmp;
|
||||
DdNode *tmp = f;
|
||||
f = g; g = tmp;
|
||||
}
|
||||
F = Cudd_Regular(f);
|
||||
G = Cudd_Regular(g);
|
||||
cacheOp = (DdNode *(*)(DdManager *, DdNode *, DdNode *))
|
||||
(direction ? Cudd_bddClippingAnd : cuddBddClippingAnd);
|
||||
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);
|
||||
r = cuddCacheLookup2(manager, cacheOp, f, g);
|
||||
if (r != NULL) return(r);
|
||||
}
|
||||
|
||||
/* Here we can skip the use of cuddI, because the operands are known
|
||||
|
|
@ -296,27 +324,27 @@ cuddBddClippingAndRecur(
|
|||
|
||||
/* 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);
|
||||
}
|
||||
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;
|
||||
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);
|
||||
}
|
||||
gt = cuddT(G);
|
||||
ge = cuddE(G);
|
||||
if (Cudd_IsComplement(g)) {
|
||||
gt = Cudd_Not(gt);
|
||||
ge = Cudd_Not(ge);
|
||||
}
|
||||
} else {
|
||||
gt = ge = g;
|
||||
gt = ge = g;
|
||||
}
|
||||
|
||||
t = cuddBddClippingAndRecur(manager, ft, gt, distance, direction);
|
||||
|
|
@ -324,35 +352,35 @@ cuddBddClippingAndRecur(
|
|||
cuddRef(t);
|
||||
e = cuddBddClippingAndRecur(manager, fe, ge, distance, direction);
|
||||
if (e == NULL) {
|
||||
Cudd_RecursiveDeref(manager, t);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(manager, t);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(e);
|
||||
|
||||
if (t == e) {
|
||||
r = t;
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
cuddCacheInsert2(manager, cacheOp, f, g, r);
|
||||
return(r);
|
||||
|
||||
} /* end of cuddBddClippingAndRecur */
|
||||
|
|
@ -393,15 +421,15 @@ cuddBddClipAndAbsRecur(
|
|||
|
||||
/* Terminal cases. */
|
||||
if (f == zero || g == zero || f == Cudd_Not(g)) return(zero);
|
||||
if (f == one && g == one) return(one);
|
||||
if (f == one && g == one) return(one);
|
||||
if (cube == one) {
|
||||
return(cuddBddClippingAndRecur(manager, f, g, distance, direction));
|
||||
return(cuddBddClippingAndRecur(manager, f, g, distance, direction));
|
||||
}
|
||||
if (f == one || f == g) {
|
||||
return (cuddBddExistAbstractRecur(manager, g, cube));
|
||||
return (cuddBddExistAbstractRecur(manager, g, cube));
|
||||
}
|
||||
if (g == one) {
|
||||
return (cuddBddExistAbstractRecur(manager, f, cube));
|
||||
return (cuddBddExistAbstractRecur(manager, f, cube));
|
||||
}
|
||||
if (distance == 0) return(Cudd_NotCond(one,(direction == 0)));
|
||||
|
||||
|
|
@ -410,19 +438,19 @@ cuddBddClipAndAbsRecur(
|
|||
|
||||
/* Check cache. */
|
||||
if (f > g) { /* Try to increase cache efficiency. */
|
||||
DdNode *tmp = f;
|
||||
f = g; g = tmp;
|
||||
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;
|
||||
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);
|
||||
}
|
||||
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
|
||||
|
|
@ -434,39 +462,39 @@ cuddBddClipAndAbsRecur(
|
|||
topcube = manager->perm[cube->index];
|
||||
|
||||
if (topcube < top) {
|
||||
return(cuddBddClipAndAbsRecur(manager, f, g, cuddT(cube),
|
||||
distance, direction));
|
||||
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);
|
||||
}
|
||||
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;
|
||||
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);
|
||||
}
|
||||
gt = cuddT(G);
|
||||
ge = cuddE(G);
|
||||
if (Cudd_IsComplement(g)) {
|
||||
gt = Cudd_Not(gt);
|
||||
ge = Cudd_Not(ge);
|
||||
}
|
||||
} else {
|
||||
gt = ge = g;
|
||||
gt = ge = g;
|
||||
}
|
||||
|
||||
if (topcube == top) {
|
||||
Cube = cuddT(cube);
|
||||
Cube = cuddT(cube);
|
||||
} else {
|
||||
Cube = cube;
|
||||
Cube = cube;
|
||||
}
|
||||
|
||||
t = cuddBddClipAndAbsRecur(manager, ft, gt, Cube, distance, direction);
|
||||
|
|
@ -476,61 +504,63 @@ cuddBddClipAndAbsRecur(
|
|||
** 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);
|
||||
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);
|
||||
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 (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);
|
||||
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) {
|
||||
cuddRef(r);
|
||||
Cudd_RecursiveDeref(manager, t);
|
||||
Cudd_RecursiveDeref(manager, e);
|
||||
return(NULL);
|
||||
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);
|
||||
cuddDeref(e);
|
||||
cuddDeref(t);
|
||||
}
|
||||
if (F->ref != 1 || G->ref != 1)
|
||||
cuddCacheInsert(manager, cacheTag, f, g, cube, r);
|
||||
cuddCacheInsert(manager, cacheTag, f, g, cube, r);
|
||||
return (r);
|
||||
|
||||
} /* end of cuddBddClipAndAbsRecur */
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,34 +7,62 @@
|
|||
Synopsis [Cofactoring functions.]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_Cofactor()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddGetBranches()
|
||||
<li> cuddCheckCube()
|
||||
<li> cuddCofactorRecur()
|
||||
</ul>
|
||||
]
|
||||
<ul>
|
||||
<li> Cudd_Cofactor()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddGetBranches()
|
||||
<li> cuddCheckCube()
|
||||
<li> cuddCofactorRecur()
|
||||
</ul>
|
||||
]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [ This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -55,7 +83,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddCof.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddCof.c,v 1.9 2004/08/13 18:04:47 fabio Exp $";
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -101,13 +129,13 @@ Cudd_Cofactor(
|
|||
|
||||
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);
|
||||
(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);
|
||||
dd->reordered = 0;
|
||||
res = cuddCofactorRecur(dd,f,g);
|
||||
} while (dd->reordered == 1);
|
||||
return(res);
|
||||
|
||||
|
|
@ -136,13 +164,13 @@ cuddGetBranches(
|
|||
DdNode ** g1,
|
||||
DdNode ** g0)
|
||||
{
|
||||
DdNode *G = Cudd_Regular(g);
|
||||
DdNode *G = Cudd_Regular(g);
|
||||
|
||||
*g1 = cuddT(G);
|
||||
*g0 = cuddE(G);
|
||||
if (Cudd_IsComplement(g)) {
|
||||
*g1 = Cudd_Not(*g1);
|
||||
*g0 = Cudd_Not(*g0);
|
||||
*g1 = Cudd_Not(*g1);
|
||||
*g0 = Cudd_Not(*g0);
|
||||
}
|
||||
|
||||
} /* end of cuddGetBranches */
|
||||
|
|
@ -224,7 +252,7 @@ cuddCofactorRecur(
|
|||
comple = f != F;
|
||||
r = cuddCacheLookup2(dd,Cudd_Cofactor,F,g);
|
||||
if (r != NULL) {
|
||||
return(Cudd_NotCond(r,comple));
|
||||
return(Cudd_NotCond(r,comple));
|
||||
}
|
||||
|
||||
topf = dd->perm[F->index];
|
||||
|
|
@ -237,57 +265,57 @@ cuddCofactorRecur(
|
|||
** remembers whether we have to complement the result or not.
|
||||
*/
|
||||
if (topf <= topg) {
|
||||
f1 = cuddT(F); f0 = cuddE(F);
|
||||
f1 = cuddT(F); f0 = cuddE(F);
|
||||
} else {
|
||||
f1 = f0 = F;
|
||||
f1 = f0 = F;
|
||||
}
|
||||
if (topg <= topf) {
|
||||
g1 = cuddT(G); g0 = cuddE(G);
|
||||
if (g != G) { g1 = Cudd_Not(g1); g0 = Cudd_Not(g0); }
|
||||
g1 = cuddT(G); g0 = cuddE(G);
|
||||
if (g != G) { g1 = Cudd_Not(g1); g0 = Cudd_Not(g0); }
|
||||
} else {
|
||||
g1 = g0 = g;
|
||||
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);
|
||||
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);
|
||||
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 (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);
|
||||
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);
|
||||
|
|
@ -301,5 +329,7 @@ cuddCofactorRecur(
|
|||
/* Definition of static functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -7,36 +7,63 @@
|
|||
Synopsis [Functions for exact variable reordering.]
|
||||
|
||||
Description [External procedures included in this file:
|
||||
<ul>
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddExact()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<ul>
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddExact()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> getMaxBinomial()
|
||||
<li> gcd()
|
||||
<li> gcd()
|
||||
<li> getMatrix()
|
||||
<li> freeMatrix()
|
||||
<li> freeMatrix()
|
||||
<li> getLevelKeys()
|
||||
<li> ddShuffle()
|
||||
<li> ddSiftUp()
|
||||
<li> updateUB()
|
||||
<li> ddCountRoots()
|
||||
<li> ddClearGlobal()
|
||||
<li> computeLB()
|
||||
<li> updateEntry()
|
||||
<li> pushDown()
|
||||
<li> initSymmInfo()
|
||||
<li> updateUB()
|
||||
<li> ddCountRoots()
|
||||
<li> ddClearGlobal()
|
||||
<li> computeLB()
|
||||
<li> updateEntry()
|
||||
<li> pushDown()
|
||||
<li> initSymmInfo()
|
||||
</ul>]
|
||||
|
||||
Author [Cheng Hua, Fabio Somenzi]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -46,6 +73,7 @@
|
|||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -64,7 +92,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddExact.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddExact.c,v 1.28 2009/02/19 16:19:19 fabio Exp $";
|
||||
#endif
|
||||
|
||||
#ifdef DD_STATS
|
||||
|
|
@ -81,21 +109,20 @@ static int ddTotalShuffles;
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static int getMaxBinomial ARGS((int n));
|
||||
static int gcd ARGS((int x, int y));
|
||||
static DdHalfWord ** getMatrix ARGS((int rows, int cols));
|
||||
static void freeMatrix ARGS((DdHalfWord **matrix));
|
||||
static int getLevelKeys ARGS((DdManager *table, int l));
|
||||
static int ddShuffle ARGS((DdManager *table, DdHalfWord *permutation, int lower, int upper));
|
||||
static int ddSiftUp ARGS((DdManager *table, int x, int xLow));
|
||||
static int updateUB ARGS((DdManager *table, int oldBound, DdHalfWord *bestOrder, int lower, int upper));
|
||||
static int ddCountRoots ARGS((DdManager *table, int lower, int upper));
|
||||
static void ddClearGlobal ARGS((DdManager *table, int lower, int maxlevel));
|
||||
static int computeLB ARGS((DdManager *table, DdHalfWord *order, int roots, int cost, int lower, int upper, int level));
|
||||
static int updateEntry ARGS((DdManager *table, DdHalfWord *order, int level, int cost, DdHalfWord **orders, int *costs, int subsets, char *mask, int lower, int upper));
|
||||
static void pushDown ARGS((DdHalfWord *order, int j, int level));
|
||||
static DdHalfWord * initSymmInfo ARGS((DdManager *table, int lower, int upper));
|
||||
static int checkSymmInfo ARGS((DdManager *table, DdHalfWord *symmInfo, int index, int level));
|
||||
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***************************************************************/
|
||||
|
||||
|
|
@ -131,7 +158,7 @@ cuddExact(
|
|||
int k, i, j;
|
||||
int maxBinomial, oldSubsets, newSubsets;
|
||||
int subsetCost;
|
||||
int size; /* number of variables to be reordered */
|
||||
int size; /* number of variables to be reordered */
|
||||
int unused, nvars, level, result;
|
||||
int upperBound, lowerBound, cost;
|
||||
int roots;
|
||||
|
|
@ -152,13 +179,13 @@ cuddExact(
|
|||
/* 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++;
|
||||
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--;
|
||||
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
|
||||
|
|
@ -179,9 +206,9 @@ cuddExact(
|
|||
** 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++;
|
||||
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. */
|
||||
|
|
@ -218,65 +245,65 @@ cuddExact(
|
|||
*/
|
||||
oldSubsets = 1;
|
||||
for (i = 0; i < size; i++) {
|
||||
oldOrder[0][i] = bestOrder[i] = (DdHalfWord) table->invperm[i+lower];
|
||||
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);
|
||||
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++) {
|
||||
#if 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;
|
||||
(void) fprintf(table->out,"Processing subsets of size %d\n", k);
|
||||
fflush(table->out);
|
||||
#endif
|
||||
oldSubsets = newSubsets;
|
||||
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;
|
||||
|
|
@ -285,9 +312,9 @@ cuddExact(
|
|||
(void) fprintf(table->out,"\n");
|
||||
#endif
|
||||
(void) fprintf(table->out,"#:S_EXACT %8d: total subsets\n",
|
||||
ddTotalSubsets);
|
||||
ddTotalSubsets);
|
||||
(void) fprintf(table->out,"#:H_EXACT %8d: total shuffles",
|
||||
ddTotalShuffles);
|
||||
ddTotalShuffles);
|
||||
#endif
|
||||
|
||||
freeMatrix(newOrder);
|
||||
|
|
@ -320,9 +347,12 @@ cuddExactOutOfMem:
|
|||
|
||||
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 is
|
||||
quite inefficient, but it avoids intermediate overflow problems.
|
||||
Returns the computed value if successful; -1 otherwise.]
|
||||
(n-1)/2 when n is odd. The algorithm used in this procedure avoids
|
||||
intermediate overflow problems. It is based on the identity
|
||||
<pre>
|
||||
binomial(n,k) = n/k * binomial(n-1,k-1).
|
||||
</pre>
|
||||
Returns the computed value if successful; -1 if out of range.]
|
||||
|
||||
SideEffects [None]
|
||||
|
||||
|
|
@ -331,42 +361,24 @@ cuddExactOutOfMem:
|
|||
******************************************************************************/
|
||||
static int
|
||||
getMaxBinomial(
|
||||
int n)
|
||||
int n)
|
||||
{
|
||||
int *numerator;
|
||||
int i, j, k, y, g, result;
|
||||
double i, j, result;
|
||||
|
||||
k = (n & ~1) >> 1;
|
||||
if (n < 0 || n > 33) return(-1); /* error */
|
||||
if (n < 2) return(1);
|
||||
|
||||
numerator = ABC_ALLOC(int,k);
|
||||
if (numerator == NULL) return(-1);
|
||||
|
||||
for (i = 0; i < k; i++)
|
||||
numerator[i] = n - i;
|
||||
|
||||
for (i = k; i > 1; i--) {
|
||||
y = i;
|
||||
for (j = 0; j < k; j++) {
|
||||
if (numerator[j] == 1) continue;
|
||||
g = gcd(numerator[j], y);
|
||||
if (g != 1) {
|
||||
numerator[j] /= g;
|
||||
if (y == g) break;
|
||||
y /= g;
|
||||
}
|
||||
}
|
||||
for (result = (double)((n+3)/2), i = result+1, j=2; i <= n; i++, j++) {
|
||||
result *= i;
|
||||
result /= j;
|
||||
}
|
||||
|
||||
result = 1;
|
||||
for (i = 0; i < k; i++)
|
||||
result *= numerator[i];
|
||||
return((int)result);
|
||||
|
||||
ABC_FREE(numerator);
|
||||
return(result);
|
||||
|
||||
} /* end of getMaxBinomial */
|
||||
} /* end of getMaxBinomial */
|
||||
|
||||
|
||||
#if 0
|
||||
/**Function********************************************************************
|
||||
|
||||
Synopsis [Returns the gcd of two integers.]
|
||||
|
|
@ -393,33 +405,34 @@ gcd(
|
|||
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;
|
||||
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 {
|
||||
a = (a - b) >> 1;
|
||||
if (b & lsbMask) { /* a even, b odd */
|
||||
a >>= 1;
|
||||
} else { /* both even */
|
||||
lsbMask <<= 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********************************************************************
|
||||
|
|
@ -446,9 +459,12 @@ getMatrix(
|
|||
matrix = ABC_ALLOC(DdHalfWord *, rows);
|
||||
if (matrix == NULL) return(NULL);
|
||||
matrix[0] = ABC_ALLOC(DdHalfWord, cols*rows);
|
||||
if (matrix[0] == NULL) return(NULL);
|
||||
if (matrix[0] == NULL) {
|
||||
ABC_FREE(matrix);
|
||||
return(NULL);
|
||||
}
|
||||
for (i = 1; i < rows; i++) {
|
||||
matrix[i] = matrix[i-1] + cols;
|
||||
matrix[i] = matrix[i-1] + cols;
|
||||
}
|
||||
return(matrix);
|
||||
|
||||
|
|
@ -528,18 +544,20 @@ ddShuffle(
|
|||
int lower,
|
||||
int upper)
|
||||
{
|
||||
DdHalfWord index;
|
||||
int level;
|
||||
int position;
|
||||
int numvars;
|
||||
int result;
|
||||
#ifdef DD_STATS
|
||||
long localTime;
|
||||
int initialSize;
|
||||
#ifdef DD_VERBOSE
|
||||
int finalSize;
|
||||
DdHalfWord index;
|
||||
int level;
|
||||
int position;
|
||||
#if 0
|
||||
int numvars;
|
||||
#endif
|
||||
int previousSize;
|
||||
int result;
|
||||
#ifdef DD_STATS
|
||||
long localTime;
|
||||
int initialSize;
|
||||
#ifdef DD_VERBOSE
|
||||
int finalSize;
|
||||
#endif
|
||||
int previousSize;
|
||||
#endif
|
||||
|
||||
#ifdef DD_STATS
|
||||
|
|
@ -547,24 +565,24 @@ ddShuffle(
|
|||
initialSize = table->keys - table->isolated;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
numvars = table->size;
|
||||
|
||||
#if 0
|
||||
(void) fprintf(table->out,"%d:", ddTotalShuffles);
|
||||
for (level = 0; level < numvars; level++) {
|
||||
(void) fprintf(table->out," %d", table->invperm[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];
|
||||
index = permutation[level];
|
||||
position = table->perm[index];
|
||||
#ifdef DD_STATS
|
||||
previousSize = table->keys - table->isolated;
|
||||
previousSize = table->keys - table->isolated;
|
||||
#endif
|
||||
result = ddSiftUp(table,position,level+lower);
|
||||
if (!result) return(0);
|
||||
result = ddSiftUp(table,position,level+lower);
|
||||
if (!result) return(0);
|
||||
}
|
||||
|
||||
#ifdef DD_STATS
|
||||
|
|
@ -572,11 +590,11 @@ ddShuffle(
|
|||
#ifdef DD_VERBOSE
|
||||
finalSize = table->keys - table->isolated;
|
||||
if (finalSize < initialSize) {
|
||||
(void) fprintf(table->out,"-");
|
||||
(void) fprintf(table->out,"-");
|
||||
} else if (finalSize > initialSize) {
|
||||
(void) fprintf(table->out,"+");
|
||||
(void) fprintf(table->out,"+");
|
||||
} else {
|
||||
(void) fprintf(table->out,"=");
|
||||
(void) fprintf(table->out,"=");
|
||||
}
|
||||
if ((ddTotalShuffles & 63) == 0) (void) fprintf(table->out,"\n");
|
||||
fflush(table->out);
|
||||
|
|
@ -612,12 +630,12 @@ ddSiftUp(
|
|||
|
||||
y = cuddNextLow(table,x);
|
||||
while (y >= xLow) {
|
||||
size = cuddSwapInPlace(table,y,x);
|
||||
if (size == 0) {
|
||||
return(0);
|
||||
}
|
||||
x = y;
|
||||
y = cuddNextLow(table,x);
|
||||
size = cuddSwapInPlace(table,y,x);
|
||||
if (size == 0) {
|
||||
return(0);
|
||||
}
|
||||
x = y;
|
||||
y = cuddNextLow(table,x);
|
||||
}
|
||||
return(1);
|
||||
|
||||
|
|
@ -649,14 +667,14 @@ updateUB(
|
|||
|
||||
if (newBound < oldBound) {
|
||||
#ifdef DD_STATS
|
||||
(void) fprintf(table->out,"New upper bound = %d\n", newBound);
|
||||
fflush(table->out);
|
||||
(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);
|
||||
for (i = lower; i <= upper; i++)
|
||||
bestOrder[i-lower] = (DdHalfWord) table->invperm[i];
|
||||
return(newBound);
|
||||
} else {
|
||||
return(oldBound);
|
||||
return(oldBound);
|
||||
}
|
||||
|
||||
} /* end of updateUB */
|
||||
|
|
@ -693,36 +711,36 @@ ddCountRoots(
|
|||
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++;
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
|
|
@ -758,16 +776,16 @@ ddClearGlobal(
|
|||
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;
|
||||
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 */
|
||||
|
||||
|
|
@ -793,13 +811,13 @@ ddClearGlobal(
|
|||
******************************************************************************/
|
||||
static int
|
||||
computeLB(
|
||||
DdManager * table /* manager */,
|
||||
DdHalfWord * order /* optimal order for the subset */,
|
||||
int roots /* roots between lower and upper */,
|
||||
int cost /* minimum cost for the subset */,
|
||||
int lower /* lower level to be reordered */,
|
||||
int upper /* upper level to be reordered */,
|
||||
int level /* offset for the current top bottom var */
|
||||
DdManager * table /* manager */,
|
||||
DdHalfWord * order /* optimal order for the subset */,
|
||||
int roots /* roots between lower and upper */,
|
||||
int cost /* minimum cost for the subset */,
|
||||
int lower /* lower level to be reordered */,
|
||||
int upper /* upper level to be reordered */,
|
||||
int level /* offset for the current top bottom var */
|
||||
)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -813,28 +831,28 @@ computeLB(
|
|||
** Add their sizes to the lower bound.
|
||||
*/
|
||||
for (i = 0; i < lower; i++) {
|
||||
lb += getLevelKeys(table,i);
|
||||
lb += getLevelKeys(table,i);
|
||||
}
|
||||
/* If a variable is in the support, then there is going
|
||||
** to be at least one node labeled by that variable.
|
||||
*/
|
||||
for (i = lower; i <= lower+level; i++) {
|
||||
support = table->subtables[i].keys > 1 ||
|
||||
table->vars[order[i-lower]]->ref > 1;
|
||||
lb1 += support;
|
||||
support = table->subtables[i].keys > 1 ||
|
||||
table->vars[order[i-lower]]->ref > 1;
|
||||
lb1 += support;
|
||||
}
|
||||
|
||||
/* Estimate the number of nodes required to connect the roots to
|
||||
** the nodes in the bottom part. */
|
||||
if (lower+level+1 < table->size) {
|
||||
if (lower+level < upper)
|
||||
ref = table->vars[order[level+1]]->ref;
|
||||
else
|
||||
ref = table->vars[table->invperm[upper+1]]->ref;
|
||||
lb2 = table->subtables[lower+level+1].keys -
|
||||
(ref > (DdHalfWord) 1) - roots;
|
||||
if (lower+level < upper)
|
||||
ref = table->vars[order[level+1]]->ref;
|
||||
else
|
||||
ref = table->vars[table->invperm[upper+1]]->ref;
|
||||
lb2 = table->subtables[lower+level+1].keys -
|
||||
(ref > (DdHalfWord) 1) - roots;
|
||||
} else {
|
||||
lb2 = 0;
|
||||
lb2 = 0;
|
||||
}
|
||||
|
||||
lb += lb1 > lb2 ? lb1 : lb2;
|
||||
|
|
@ -876,25 +894,25 @@ updateEntry(
|
|||
|
||||
/* Build a mask that says what variables are in this subset. */
|
||||
for (i = lower; i <= upper; i++)
|
||||
mask[table->invperm[i]] = 0;
|
||||
mask[table->invperm[i]] = 0;
|
||||
for (i = level; i < size; i++)
|
||||
mask[order[i]] = 1;
|
||||
mask[order[i]] = 1;
|
||||
|
||||
/* Check each subset until a match is found or all subsets are examined. */
|
||||
for (i = 0; i < subsets; i++) {
|
||||
DdHalfWord *subset = orders[i];
|
||||
for (j = level; j < size; j++) {
|
||||
if (mask[subset[j]] == 0)
|
||||
break;
|
||||
DdHalfWord *subset = orders[i];
|
||||
for (j = level; j < size; j++) {
|
||||
if (mask[subset[j]] == 0)
|
||||
break;
|
||||
}
|
||||
if (j == size) /* no mismatches: success */
|
||||
break;
|
||||
}
|
||||
if (j == size) /* no mismatches: success */
|
||||
break;
|
||||
}
|
||||
if (i == subsets || cost < costs[i]) { /* add or replace */
|
||||
for (j = 0; j < size; j++)
|
||||
orders[i][j] = order[j];
|
||||
costs[i] = cost;
|
||||
subsets += (i == subsets);
|
||||
if (i == subsets || cost < costs[i]) { /* add or replace */
|
||||
for (j = 0; j < size; j++)
|
||||
orders[i][j] = order[j];
|
||||
costs[i] = cost;
|
||||
subsets += (i == subsets);
|
||||
}
|
||||
return(subsets);
|
||||
|
||||
|
|
@ -923,7 +941,7 @@ pushDown(
|
|||
|
||||
tmp = order[j];
|
||||
for (i = j; i < level; i++) {
|
||||
order[i] = order[i+1];
|
||||
order[i] = order[i+1];
|
||||
}
|
||||
order[level] = tmp;
|
||||
return;
|
||||
|
|
@ -963,10 +981,10 @@ initSymmInfo(
|
|||
if (symmInfo == NULL) return(NULL);
|
||||
|
||||
for (level = lower; level <= upper; level++) {
|
||||
index = table->invperm[level];
|
||||
next = table->subtables[level].next;
|
||||
nextindex = table->invperm[next];
|
||||
symmInfo[index] = nextindex;
|
||||
index = table->invperm[level];
|
||||
next = table->subtables[level].next;
|
||||
nextindex = table->invperm[next];
|
||||
symmInfo[index] = nextindex;
|
||||
}
|
||||
return(symmInfo);
|
||||
|
||||
|
|
@ -997,13 +1015,14 @@ checkSymmInfo(
|
|||
|
||||
i = symmInfo[index];
|
||||
while (i != index) {
|
||||
if (index < i && table->perm[i] <= level)
|
||||
return(0);
|
||||
i = symmInfo[i];
|
||||
if (index < i && table->perm[i] <= level)
|
||||
return(0);
|
||||
i = symmInfo[i];
|
||||
}
|
||||
return(1);
|
||||
|
||||
} /* end of checkSymmInfo */
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -7,23 +7,23 @@
|
|||
Synopsis [Genetic algorithm for variable reordering.]
|
||||
|
||||
Description [Internal procedures included in this file:
|
||||
<ul>
|
||||
<li> cuddGa()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> make_random()
|
||||
<li> sift_up()
|
||||
<li> build_dd()
|
||||
<li> largest()
|
||||
<li> rand_int()
|
||||
<li> array_hash()
|
||||
<li> array_compare()
|
||||
<li> find_best()
|
||||
<li> find_average_fitness()
|
||||
<li> PMX()
|
||||
<li> roulette()
|
||||
</ul>
|
||||
<ul>
|
||||
<li> cuddGa()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> make_random()
|
||||
<li> sift_up()
|
||||
<li> build_dd()
|
||||
<li> largest()
|
||||
<li> rand_int()
|
||||
<li> array_hash()
|
||||
<li> array_compare()
|
||||
<li> find_best()
|
||||
<li> find_average_fitness()
|
||||
<li> PMX()
|
||||
<li> roulette()
|
||||
</ul>
|
||||
|
||||
The genetic algorithm implemented here is as follows. We start with
|
||||
the current DD order. We sift this order and use this as the
|
||||
|
|
@ -46,10 +46,37 @@
|
|||
|
||||
Author [Curt Musfeldt, Alan Shuler, Fabio Somenzi]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -59,6 +86,7 @@
|
|||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -76,11 +104,11 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddGenetic.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddGenetic.c,v 1.28 2004/08/13 18:04:48 fabio Exp $";
|
||||
#endif
|
||||
|
||||
static int popsize; /* the size of the population */
|
||||
static int numvars; /* the number of input variables in the ckt. */
|
||||
static int popsize; /* the size of the population */
|
||||
static int numvars; /* the number of input variables in the ckt. */
|
||||
/* storedd stores the population orders and sizes. This table has two
|
||||
** extra rows and one extras column. The two extra rows are used for the
|
||||
** offspring produced by a crossover. Each row stores one order and its
|
||||
|
|
@ -90,12 +118,12 @@ static int numvars; /* the number of input variables in the ckt. */
|
|||
** it is a two-dimensional structure.
|
||||
*/
|
||||
static int *storedd;
|
||||
static st_table *computed; /* hash table to identify existing orders */
|
||||
static int *repeat; /* how many times an order is present */
|
||||
static int large; /* stores the index of the population with
|
||||
** the largest number of nodes in the DD */
|
||||
static st_table *computed; /* hash table to identify existing orders */
|
||||
static int *repeat; /* how many times an order is present */
|
||||
static int large; /* stores the index of the population with
|
||||
** the largest number of nodes in the DD */
|
||||
static int result;
|
||||
static int cross; /* the number of crossovers to perform */
|
||||
static int cross; /* the number of crossovers to perform */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Macro declarations */
|
||||
|
|
@ -106,6 +134,9 @@ static int cross; /* the number of crossovers to perform */
|
|||
*/
|
||||
#define STOREDD(i,j) storedd[(i)*(numvars+1)+(j)]
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**AutomaticStart*************************************************************/
|
||||
|
||||
|
|
@ -113,20 +144,25 @@ static int cross; /* the number of crossovers to perform */
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static int make_random ARGS((DdManager *table, int lower));
|
||||
static int sift_up ARGS((DdManager *table, int x, int x_low));
|
||||
static int build_dd ARGS((DdManager *table, int num, int lower, int upper));
|
||||
static int largest ARGS(());
|
||||
static int rand_int ARGS((int a));
|
||||
static int array_hash ARGS((const char *array, int modulus));
|
||||
static int array_compare ARGS((const char *array1, const char *array2));
|
||||
static int find_best ARGS(());
|
||||
static double find_average_fitness ARGS(());
|
||||
static int PMX ARGS((int maxvar));
|
||||
static int roulette ARGS((int *p1, int *p2));
|
||||
static int make_random (DdManager *table, int lower);
|
||||
static int sift_up (DdManager *table, int x, int x_low);
|
||||
static int build_dd (DdManager *table, int num, int lower, int upper);
|
||||
static int largest (void);
|
||||
static int rand_int (int a);
|
||||
static int array_hash (const char *array, int modulus);
|
||||
static int array_compare (const char *array1, const char *array2);
|
||||
static int find_best (void);
|
||||
#ifdef DD_STATS
|
||||
static double find_average_fitness (void);
|
||||
#endif
|
||||
static int PMX (int maxvar);
|
||||
static int roulette (int *p1, int *p2);
|
||||
|
||||
/**AutomaticEnd***************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Definition of exported functions */
|
||||
|
|
@ -158,10 +194,12 @@ cuddGa(
|
|||
int lower /* lowest level to be reordered */,
|
||||
int upper /* highest level to be reorderded */)
|
||||
{
|
||||
int i,n,m; /* dummy/loop vars */
|
||||
int index;
|
||||
double average_fitness;
|
||||
int small; /* index of smallest DD in population */
|
||||
int i,n,m; /* dummy/loop vars */
|
||||
int index;
|
||||
#ifdef DD_STATS
|
||||
double average_fitness;
|
||||
#endif
|
||||
int small; /* index of smallest DD in population */
|
||||
|
||||
/* Do an initial sifting to produce at least one reasonable individual. */
|
||||
if (!cuddSifting(table,lower,upper)) return(0);
|
||||
|
|
@ -169,20 +207,20 @@ cuddGa(
|
|||
/* Get the initial values. */
|
||||
numvars = upper - lower + 1; /* number of variables to be reordered */
|
||||
if (table->populationSize == 0) {
|
||||
popsize = 3 * numvars; /* population size is 3 times # of vars */
|
||||
if (popsize > 120) {
|
||||
popsize = 120; /* Maximum population size is 120 */
|
||||
}
|
||||
popsize = 3 * numvars; /* population size is 3 times # of vars */
|
||||
if (popsize > 120) {
|
||||
popsize = 120; /* Maximum population size is 120 */
|
||||
}
|
||||
} else {
|
||||
popsize = table->populationSize; /* user specified value */
|
||||
popsize = table->populationSize; /* user specified value */
|
||||
}
|
||||
if (popsize < 4) popsize = 4; /* enforce minimum population size */
|
||||
if (popsize < 4) popsize = 4; /* enforce minimum population size */
|
||||
|
||||
/* Allocate population table. */
|
||||
storedd = ABC_ALLOC(int,(popsize+2)*(numvars+1));
|
||||
if (storedd == NULL) {
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Initialize the computed table. This table is made up of two data
|
||||
|
|
@ -195,39 +233,39 @@ cuddGa(
|
|||
*/
|
||||
repeat = ABC_ALLOC(int,popsize);
|
||||
if (repeat == NULL) {
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
ABC_FREE(storedd);
|
||||
return(0);
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
ABC_FREE(storedd);
|
||||
return(0);
|
||||
}
|
||||
for (i = 0; i < popsize; i++) {
|
||||
repeat[i] = 0;
|
||||
repeat[i] = 0;
|
||||
}
|
||||
computed = st_init_table(array_compare,array_hash);
|
||||
if (computed == NULL) {
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
ABC_FREE(storedd);
|
||||
ABC_FREE(repeat);
|
||||
return(0);
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
ABC_FREE(storedd);
|
||||
ABC_FREE(repeat);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Copy the current DD and its size to the population table. */
|
||||
for (i = 0; i < numvars; i++) {
|
||||
STOREDD(0,i) = table->invperm[i+lower]; /* order of initial DD */
|
||||
STOREDD(0,i) = table->invperm[i+lower]; /* order of initial DD */
|
||||
}
|
||||
STOREDD(0,numvars) = table->keys - table->isolated; /* size of initial DD */
|
||||
|
||||
/* Store the initial order in the computed table. */
|
||||
if (st_insert(computed,(char *)storedd,(char *) 0) == ST_OUT_OF_MEM) {
|
||||
ABC_FREE(storedd);
|
||||
ABC_FREE(repeat);
|
||||
st_free_table(computed);
|
||||
return(0);
|
||||
ABC_FREE(storedd);
|
||||
ABC_FREE(repeat);
|
||||
st_free_table(computed);
|
||||
return(0);
|
||||
}
|
||||
repeat[0]++;
|
||||
|
||||
/* Insert the reverse order as second element of the population. */
|
||||
for (i = 0; i < numvars; i++) {
|
||||
STOREDD(1,numvars-1-i) = table->invperm[i+lower]; /* reverse order */
|
||||
STOREDD(1,numvars-1-i) = table->invperm[i+lower]; /* reverse order */
|
||||
}
|
||||
|
||||
/* Now create the random orders. make_random fills the population
|
||||
|
|
@ -236,32 +274,32 @@ cuddGa(
|
|||
** the results in the computed table.
|
||||
*/
|
||||
if (!make_random(table,lower)) {
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
ABC_FREE(storedd);
|
||||
ABC_FREE(repeat);
|
||||
st_free_table(computed);
|
||||
return(0);
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
ABC_FREE(storedd);
|
||||
ABC_FREE(repeat);
|
||||
st_free_table(computed);
|
||||
return(0);
|
||||
}
|
||||
for (i = 1; i < popsize; i++) {
|
||||
result = build_dd(table,i,lower,upper); /* build and sift order */
|
||||
if (!result) {
|
||||
ABC_FREE(storedd);
|
||||
ABC_FREE(repeat);
|
||||
st_free_table(computed);
|
||||
return(0);
|
||||
}
|
||||
if (st_lookup(computed,(char *)&STOREDD(i,0),(char **)&index)) {
|
||||
repeat[index]++;
|
||||
} else {
|
||||
if (st_insert(computed,(char *)&STOREDD(i,0),(char *)(long)i) ==
|
||||
ST_OUT_OF_MEM) {
|
||||
ABC_FREE(storedd);
|
||||
ABC_FREE(repeat);
|
||||
st_free_table(computed);
|
||||
return(0);
|
||||
result = build_dd(table,i,lower,upper); /* build and sift order */
|
||||
if (!result) {
|
||||
ABC_FREE(storedd);
|
||||
ABC_FREE(repeat);
|
||||
st_free_table(computed);
|
||||
return(0);
|
||||
}
|
||||
if (st_lookup_int(computed,(char *)&STOREDD(i,0),&index)) {
|
||||
repeat[index]++;
|
||||
} else {
|
||||
if (st_insert(computed,(char *)&STOREDD(i,0),(char *)(long)i) ==
|
||||
ST_OUT_OF_MEM) {
|
||||
ABC_FREE(storedd);
|
||||
ABC_FREE(repeat);
|
||||
st_free_table(computed);
|
||||
return(0);
|
||||
}
|
||||
repeat[i]++;
|
||||
}
|
||||
repeat[i]++;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
@ -269,103 +307,103 @@ cuddGa(
|
|||
/* Print the initial population. */
|
||||
(void) fprintf(table->out,"Initial population after sifting\n");
|
||||
for (m = 0; m < popsize; m++) {
|
||||
for (i = 0; i < numvars; i++) {
|
||||
(void) fprintf(table->out," %2d",STOREDD(m,i));
|
||||
}
|
||||
(void) fprintf(table->out," : %3d (%d)\n",
|
||||
STOREDD(m,numvars),repeat[m]);
|
||||
for (i = 0; i < numvars; i++) {
|
||||
(void) fprintf(table->out," %2d",STOREDD(m,i));
|
||||
}
|
||||
(void) fprintf(table->out," : %3d (%d)\n",
|
||||
STOREDD(m,numvars),repeat[m]);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
small = find_best();
|
||||
average_fitness = find_average_fitness();
|
||||
#ifdef DD_STATS
|
||||
average_fitness = find_average_fitness();
|
||||
(void) fprintf(table->out,"\nInitial population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness);
|
||||
#endif
|
||||
|
||||
/* Decide how many crossovers should be tried. */
|
||||
if (table->numberXovers == 0) {
|
||||
cross = 3*numvars;
|
||||
if (cross > 60) { /* do a maximum of 50 crossovers */
|
||||
cross = 60;
|
||||
}
|
||||
cross = 3*numvars;
|
||||
if (cross > 60) { /* do a maximum of 50 crossovers */
|
||||
cross = 60;
|
||||
}
|
||||
} else {
|
||||
cross = table->numberXovers; /* use user specified value */
|
||||
cross = table->numberXovers; /* use user specified value */
|
||||
}
|
||||
|
||||
/* Perform the crossovers to get the best order. */
|
||||
for (m = 0; m < cross; m++) {
|
||||
if (!PMX(table->size)) { /* perform one crossover */
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
ABC_FREE(storedd);
|
||||
ABC_FREE(repeat);
|
||||
st_free_table(computed);
|
||||
return(0);
|
||||
}
|
||||
/* The offsprings are left in the last two entries of the
|
||||
** population table. These are now considered in turn.
|
||||
*/
|
||||
for (i = popsize; i <= popsize+1; i++) {
|
||||
result = build_dd(table,i,lower,upper); /* build and sift child */
|
||||
if (!result) {
|
||||
ABC_FREE(storedd);
|
||||
ABC_FREE(repeat);
|
||||
st_free_table(computed);
|
||||
return(0);
|
||||
}
|
||||
large = largest(); /* find the largest DD in population */
|
||||
|
||||
/* If the new child is smaller than the largest DD in the current
|
||||
** population, enter it into the population in place of the
|
||||
** largest DD.
|
||||
*/
|
||||
if (STOREDD(i,numvars) < STOREDD(large,numvars)) {
|
||||
/* Look up the largest DD in the computed table.
|
||||
** Decrease its repetition count. If the repetition count
|
||||
** goes to 0, remove the largest DD from the computed table.
|
||||
*/
|
||||
result = st_lookup(computed,(char *)&STOREDD(large,0),(char
|
||||
**)&index);
|
||||
if (!result) {
|
||||
if (!PMX(table->size)) { /* perform one crossover */
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
ABC_FREE(storedd);
|
||||
ABC_FREE(repeat);
|
||||
st_free_table(computed);
|
||||
return(0);
|
||||
}
|
||||
repeat[index]--;
|
||||
if (repeat[index] == 0) {
|
||||
int *pointer = &STOREDD(index,0);
|
||||
result = st_delete(computed, (const char **)&pointer,NULL);
|
||||
/* The offsprings are left in the last two entries of the
|
||||
** population table. These are now considered in turn.
|
||||
*/
|
||||
for (i = popsize; i <= popsize+1; i++) {
|
||||
result = build_dd(table,i,lower,upper); /* build and sift child */
|
||||
if (!result) {
|
||||
ABC_FREE(storedd);
|
||||
ABC_FREE(repeat);
|
||||
st_free_table(computed);
|
||||
return(0);
|
||||
ABC_FREE(storedd);
|
||||
ABC_FREE(repeat);
|
||||
st_free_table(computed);
|
||||
return(0);
|
||||
}
|
||||
large = largest(); /* find the largest DD in population */
|
||||
|
||||
/* If the new child is smaller than the largest DD in the current
|
||||
** population, enter it into the population in place of the
|
||||
** largest DD.
|
||||
*/
|
||||
if (STOREDD(i,numvars) < STOREDD(large,numvars)) {
|
||||
/* Look up the largest DD in the computed table.
|
||||
** Decrease its repetition count. If the repetition count
|
||||
** goes to 0, remove the largest DD from the computed table.
|
||||
*/
|
||||
result = st_lookup_int(computed,(char *)&STOREDD(large,0),
|
||||
&index);
|
||||
if (!result) {
|
||||
ABC_FREE(storedd);
|
||||
ABC_FREE(repeat);
|
||||
st_free_table(computed);
|
||||
return(0);
|
||||
}
|
||||
repeat[index]--;
|
||||
if (repeat[index] == 0) {
|
||||
int *pointer = &STOREDD(index,0);
|
||||
result = st_delete(computed, (const char **)&pointer, NULL);
|
||||
if (!result) {
|
||||
ABC_FREE(storedd);
|
||||
ABC_FREE(repeat);
|
||||
st_free_table(computed);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
/* Copy the new individual to the entry of the
|
||||
** population table just made available and update the
|
||||
** computed table.
|
||||
*/
|
||||
for (n = 0; n <= numvars; n++) {
|
||||
STOREDD(large,n) = STOREDD(i,n);
|
||||
}
|
||||
if (st_lookup_int(computed,(char *)&STOREDD(large,0),
|
||||
&index)) {
|
||||
repeat[index]++;
|
||||
} else {
|
||||
if (st_insert(computed,(char *)&STOREDD(large,0),
|
||||
(char *)(long)large) == ST_OUT_OF_MEM) {
|
||||
ABC_FREE(storedd);
|
||||
ABC_FREE(repeat);
|
||||
st_free_table(computed);
|
||||
return(0);
|
||||
}
|
||||
repeat[large]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Copy the new individual to the entry of the
|
||||
** population table just made available and update the
|
||||
** computed table.
|
||||
*/
|
||||
for (n = 0; n <= numvars; n++) {
|
||||
STOREDD(large,n) = STOREDD(i,n);
|
||||
}
|
||||
if (st_lookup(computed,(char *)&STOREDD(large,0),(char
|
||||
**)&index)) {
|
||||
repeat[index]++;
|
||||
} else {
|
||||
if (st_insert(computed,(char *)&STOREDD(large,0),
|
||||
(char *)(long)large) == ST_OUT_OF_MEM) {
|
||||
ABC_FREE(storedd);
|
||||
ABC_FREE(repeat);
|
||||
st_free_table(computed);
|
||||
return(0);
|
||||
}
|
||||
repeat[large]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the smallest DD in the population and build it;
|
||||
|
|
@ -412,47 +450,47 @@ make_random(
|
|||
DdManager * table,
|
||||
int lower)
|
||||
{
|
||||
int i,j; /* loop variables */
|
||||
int *used; /* is a number already in a permutation */
|
||||
int next; /* next random number without repetitions */
|
||||
int i,j; /* loop variables */
|
||||
int *used; /* is a number already in a permutation */
|
||||
int next; /* next random number without repetitions */
|
||||
|
||||
used = ABC_ALLOC(int,numvars);
|
||||
if (used == NULL) {
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
#if 0
|
||||
#ifdef DD_STATS
|
||||
(void) fprintf(table->out,"Initial population before sifting\n");
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (j = 0; j < numvars; j++) {
|
||||
(void) fprintf(table->out," %2d",STOREDD(i,j));
|
||||
}
|
||||
(void) fprintf(table->out,"\n");
|
||||
for (j = 0; j < numvars; j++) {
|
||||
(void) fprintf(table->out," %2d",STOREDD(i,j));
|
||||
}
|
||||
(void) fprintf(table->out,"\n");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
for (i = 2; i < popsize; i++) {
|
||||
for (j = 0; j < numvars; j++) {
|
||||
used[j] = 0;
|
||||
}
|
||||
/* Generate a permutation of {0...numvars-1} and use it to
|
||||
** permute the variables in the layesr from lower to upper.
|
||||
*/
|
||||
for (j = 0; j < numvars; j++) {
|
||||
do {
|
||||
next = rand_int(numvars-1);
|
||||
} while (used[next] != 0);
|
||||
used[next] = 1;
|
||||
STOREDD(i,j) = table->invperm[next+lower];
|
||||
}
|
||||
for (j = 0; j < numvars; j++) {
|
||||
used[j] = 0;
|
||||
}
|
||||
/* Generate a permutation of {0...numvars-1} and use it to
|
||||
** permute the variables in the layesr from lower to upper.
|
||||
*/
|
||||
for (j = 0; j < numvars; j++) {
|
||||
do {
|
||||
next = rand_int(numvars-1);
|
||||
} while (used[next] != 0);
|
||||
used[next] = 1;
|
||||
STOREDD(i,j) = table->invperm[next+lower];
|
||||
}
|
||||
#if 0
|
||||
#ifdef DD_STATS
|
||||
/* Print the order just generated. */
|
||||
for (j = 0; j < numvars; j++) {
|
||||
(void) fprintf(table->out," %2d",STOREDD(i,j));
|
||||
}
|
||||
(void) fprintf(table->out,"\n");
|
||||
/* Print the order just generated. */
|
||||
for (j = 0; j < numvars; j++) {
|
||||
(void) fprintf(table->out," %2d",STOREDD(i,j));
|
||||
}
|
||||
(void) fprintf(table->out,"\n");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
|
@ -486,12 +524,12 @@ sift_up(
|
|||
|
||||
y = cuddNextLow(table,x);
|
||||
while (y >= x_low) {
|
||||
size = cuddSwapInPlace(table,y,x);
|
||||
if (size == 0) {
|
||||
return(0);
|
||||
}
|
||||
x = y;
|
||||
y = cuddNextLow(table,x);
|
||||
size = cuddSwapInPlace(table,y,x);
|
||||
if (size == 0) {
|
||||
return(0);
|
||||
}
|
||||
x = y;
|
||||
y = cuddNextLow(table,x);
|
||||
}
|
||||
return(1);
|
||||
|
||||
|
|
@ -518,21 +556,21 @@ build_dd(
|
|||
int lower,
|
||||
int upper)
|
||||
{
|
||||
int i,j; /* loop vars */
|
||||
int position;
|
||||
int index;
|
||||
int limit; /* how large the DD for this order can grow */
|
||||
int size;
|
||||
int i,j; /* loop vars */
|
||||
int position;
|
||||
int index;
|
||||
int limit; /* how large the DD for this order can grow */
|
||||
int size;
|
||||
|
||||
/* Check the computed table. If the order already exists, it
|
||||
** suffices to copy the size from the existing entry.
|
||||
*/
|
||||
if (computed && st_lookup(computed,(char *)&STOREDD(num,0),(char **)&index)) {
|
||||
STOREDD(num,numvars) = STOREDD(index,numvars);
|
||||
if (computed && st_lookup_int(computed,(char *)&STOREDD(num,0),&index)) {
|
||||
STOREDD(num,numvars) = STOREDD(index,numvars);
|
||||
#ifdef DD_STATS
|
||||
(void) fprintf(table->out,"\nCache hit for index %d", index);
|
||||
(void) fprintf(table->out,"\nCache hit for index %d", index);
|
||||
#endif
|
||||
return(1);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* Stop if the DD grows 20 times larges than the reference size. */
|
||||
|
|
@ -544,12 +582,12 @@ build_dd(
|
|||
** up to the second position, and so on.
|
||||
*/
|
||||
for (j = 0; j < numvars; j++) {
|
||||
i = STOREDD(num,j);
|
||||
position = table->perm[i];
|
||||
result = sift_up(table,position,j+lower);
|
||||
if (!result) return(0);
|
||||
size = table->keys - table->isolated;
|
||||
if (size > limit) break;
|
||||
i = STOREDD(num,j);
|
||||
position = table->perm[i];
|
||||
result = sift_up(table,position,j+lower);
|
||||
if (!result) return(0);
|
||||
size = table->keys - table->isolated;
|
||||
if (size > limit) break;
|
||||
}
|
||||
|
||||
/* Sift the DD just built. */
|
||||
|
|
@ -561,7 +599,7 @@ build_dd(
|
|||
|
||||
/* Copy order and size to table. */
|
||||
for (j = 0; j < numvars; j++) {
|
||||
STOREDD(num,j) = table->invperm[lower+j];
|
||||
STOREDD(num,j) = table->invperm[lower+j];
|
||||
}
|
||||
STOREDD(num,numvars) = table->keys - table->isolated; /* size of new DD */
|
||||
return(1);
|
||||
|
|
@ -583,18 +621,17 @@ build_dd(
|
|||
|
||||
******************************************************************************/
|
||||
static int
|
||||
largest(
|
||||
)
|
||||
largest(void)
|
||||
{
|
||||
int i; /* loop var */
|
||||
int i; /* loop var */
|
||||
int big; /* temporary holder to return result */
|
||||
|
||||
big = 0;
|
||||
while (repeat[big] > 1) big++;
|
||||
for (i = big + 1; i < popsize; i++) {
|
||||
if (STOREDD(i,numvars) >= STOREDD(big,numvars) && repeat[i] <= 1) {
|
||||
big = i;
|
||||
}
|
||||
if (STOREDD(i,numvars) >= STOREDD(big,numvars) && repeat[i] <= 1) {
|
||||
big = i;
|
||||
}
|
||||
}
|
||||
return(big);
|
||||
|
||||
|
|
@ -640,12 +677,12 @@ array_hash(
|
|||
{
|
||||
int val = 0;
|
||||
int i;
|
||||
const int *intarray;
|
||||
int *intarray;
|
||||
|
||||
intarray = (const int *) array;
|
||||
intarray = (int *) array;
|
||||
|
||||
for (i = 0; i < numvars; i++) {
|
||||
val = val * 997 + intarray[i];
|
||||
val = val * 997 + intarray[i];
|
||||
}
|
||||
|
||||
return ((val < 0) ? -val : val) % modulus;
|
||||
|
|
@ -677,7 +714,7 @@ array_compare(
|
|||
intarray2 = (int *) array2;
|
||||
|
||||
for (i = 0; i < numvars; i++) {
|
||||
if (intarray1[i] != intarray2[i]) return(1);
|
||||
if (intarray1[i] != intarray2[i]) return(1);
|
||||
}
|
||||
return(0);
|
||||
|
||||
|
|
@ -696,16 +733,15 @@ array_compare(
|
|||
|
||||
******************************************************************************/
|
||||
static int
|
||||
find_best(
|
||||
)
|
||||
find_best(void)
|
||||
{
|
||||
int i,small;
|
||||
|
||||
small = 0;
|
||||
for (i = 1; i < popsize; i++) {
|
||||
if (STOREDD(i,numvars) < STOREDD(small,numvars)) {
|
||||
small = i;
|
||||
}
|
||||
if (STOREDD(i,numvars) < STOREDD(small,numvars)) {
|
||||
small = i;
|
||||
}
|
||||
}
|
||||
return(small);
|
||||
|
||||
|
|
@ -723,21 +759,22 @@ find_best(
|
|||
SeeAlso []
|
||||
|
||||
******************************************************************************/
|
||||
#ifdef DD_STATS
|
||||
static double
|
||||
find_average_fitness(
|
||||
)
|
||||
find_average_fitness(void)
|
||||
{
|
||||
int i;
|
||||
int total_fitness = 0;
|
||||
double average_fitness;
|
||||
|
||||
for (i = 0; i < popsize; i++) {
|
||||
total_fitness += STOREDD(i,numvars);
|
||||
total_fitness += STOREDD(i,numvars);
|
||||
}
|
||||
average_fitness = (double) total_fitness / (double) popsize;
|
||||
return(average_fitness);
|
||||
|
||||
} /* end of find_average_fitness */
|
||||
#endif
|
||||
|
||||
|
||||
/**Function********************************************************************
|
||||
|
|
@ -757,28 +794,28 @@ static int
|
|||
PMX(
|
||||
int maxvar)
|
||||
{
|
||||
int cut1,cut2; /* the two cut positions (random) */
|
||||
int mom,dad; /* the two randomly chosen parents */
|
||||
int *inv1; /* inverse permutations for repair algo */
|
||||
int *inv2;
|
||||
int i; /* loop vars */
|
||||
int u,v; /* aux vars */
|
||||
int cut1,cut2; /* the two cut positions (random) */
|
||||
int mom,dad; /* the two randomly chosen parents */
|
||||
int *inv1; /* inverse permutations for repair algo */
|
||||
int *inv2;
|
||||
int i; /* loop vars */
|
||||
int u,v; /* aux vars */
|
||||
|
||||
inv1 = ABC_ALLOC(int,maxvar);
|
||||
if (inv1 == NULL) {
|
||||
return(0);
|
||||
return(0);
|
||||
}
|
||||
inv2 = ABC_ALLOC(int,maxvar);
|
||||
if (inv2 == NULL) {
|
||||
ABC_FREE(inv1);
|
||||
return(0);
|
||||
ABC_FREE(inv1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Choose two orders from the population using roulette wheel. */
|
||||
if (!roulette(&mom,&dad)) {
|
||||
ABC_FREE(inv1);
|
||||
ABC_FREE(inv2);
|
||||
return(0);
|
||||
ABC_FREE(inv1);
|
||||
ABC_FREE(inv2);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Choose two random cut positions. A cut in position i means that
|
||||
|
|
@ -788,68 +825,68 @@ PMX(
|
|||
*/
|
||||
cut1 = rand_int(numvars-1);
|
||||
do {
|
||||
cut2 = rand_int(numvars-1);
|
||||
cut2 = rand_int(numvars-1);
|
||||
} while (cut1 == cut2);
|
||||
|
||||
#if 0
|
||||
/* Print out the parents. */
|
||||
(void) fprintf(table->out,
|
||||
"Crossover of %d (mom) and %d (dad) between %d and %d\n",
|
||||
mom,dad,cut1,cut2);
|
||||
"Crossover of %d (mom) and %d (dad) between %d and %d\n",
|
||||
mom,dad,cut1,cut2);
|
||||
for (i = 0; i < numvars; i++) {
|
||||
if (i == cut1 || i == cut2) (void) fprintf(table->out,"|");
|
||||
(void) fprintf(table->out,"%2d ",STOREDD(mom,i));
|
||||
if (i == cut1 || i == cut2) (void) fprintf(table->out,"|");
|
||||
(void) fprintf(table->out,"%2d ",STOREDD(mom,i));
|
||||
}
|
||||
(void) fprintf(table->out,"\n");
|
||||
for (i = 0; i < numvars; i++) {
|
||||
if (i == cut1 || i == cut2) (void) fprintf(table->out,"|");
|
||||
(void) fprintf(table->out,"%2d ",STOREDD(dad,i));
|
||||
if (i == cut1 || i == cut2) (void) fprintf(table->out,"|");
|
||||
(void) fprintf(table->out,"%2d ",STOREDD(dad,i));
|
||||
}
|
||||
(void) fprintf(table->out,"\n");
|
||||
#endif
|
||||
|
||||
/* Initialize the inverse permutations: -1 means yet undetermined. */
|
||||
for (i = 0; i < maxvar; i++) {
|
||||
inv1[i] = -1;
|
||||
inv2[i] = -1;
|
||||
inv1[i] = -1;
|
||||
inv2[i] = -1;
|
||||
}
|
||||
|
||||
/* Copy the portions whithin the cuts. */
|
||||
for (i = cut1; i != cut2; i = (i == numvars-1) ? 0 : i+1) {
|
||||
STOREDD(popsize,i) = STOREDD(dad,i);
|
||||
inv1[STOREDD(popsize,i)] = i;
|
||||
STOREDD(popsize+1,i) = STOREDD(mom,i);
|
||||
inv2[STOREDD(popsize+1,i)] = i;
|
||||
STOREDD(popsize,i) = STOREDD(dad,i);
|
||||
inv1[STOREDD(popsize,i)] = i;
|
||||
STOREDD(popsize+1,i) = STOREDD(mom,i);
|
||||
inv2[STOREDD(popsize+1,i)] = i;
|
||||
}
|
||||
|
||||
/* Now apply the repair algorithm outside the cuts. */
|
||||
for (i = cut2; i != cut1; i = (i == numvars-1 ) ? 0 : i+1) {
|
||||
v = i;
|
||||
do {
|
||||
u = STOREDD(mom,v);
|
||||
v = inv1[u];
|
||||
} while (v != -1);
|
||||
STOREDD(popsize,i) = u;
|
||||
inv1[u] = i;
|
||||
v = i;
|
||||
do {
|
||||
u = STOREDD(dad,v);
|
||||
v = inv2[u];
|
||||
} while (v != -1);
|
||||
STOREDD(popsize+1,i) = u;
|
||||
inv2[u] = i;
|
||||
v = i;
|
||||
do {
|
||||
u = STOREDD(mom,v);
|
||||
v = inv1[u];
|
||||
} while (v != -1);
|
||||
STOREDD(popsize,i) = u;
|
||||
inv1[u] = i;
|
||||
v = i;
|
||||
do {
|
||||
u = STOREDD(dad,v);
|
||||
v = inv2[u];
|
||||
} while (v != -1);
|
||||
STOREDD(popsize+1,i) = u;
|
||||
inv2[u] = i;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Print the results of crossover. */
|
||||
for (i = 0; i < numvars; i++) {
|
||||
if (i == cut1 || i == cut2) (void) fprintf(table->out,"|");
|
||||
(void) fprintf(table->out,"%2d ",STOREDD(popsize,i));
|
||||
if (i == cut1 || i == cut2) (void) fprintf(table->out,"|");
|
||||
(void) fprintf(table->out,"%2d ",STOREDD(popsize,i));
|
||||
}
|
||||
(void) fprintf(table->out,"\n");
|
||||
for (i = 0; i < numvars; i++) {
|
||||
if (i == cut1 || i == cut2) (void) fprintf(table->out,"|");
|
||||
(void) fprintf(table->out,"%2d ",STOREDD(popsize+1,i));
|
||||
if (i == cut1 || i == cut2) (void) fprintf(table->out,"|");
|
||||
(void) fprintf(table->out,"%2d ",STOREDD(popsize+1,i));
|
||||
}
|
||||
(void) fprintf(table->out,"\n");
|
||||
#endif
|
||||
|
|
@ -884,14 +921,14 @@ roulette(
|
|||
|
||||
wheel = ABC_ALLOC(double,popsize);
|
||||
if (wheel == NULL) {
|
||||
return(0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* The fitness of an individual is the reciprocal of its size. */
|
||||
wheel[0] = 1.0 / (double) STOREDD(0,numvars);
|
||||
|
||||
for (i = 1; i < popsize; i++) {
|
||||
wheel[i] = wheel[i-1] + 1.0 / (double) STOREDD(i,numvars);
|
||||
wheel[i] = wheel[i-1] + 1.0 / (double) STOREDD(i,numvars);
|
||||
}
|
||||
|
||||
/* Get a random number between 0 and wheel[popsize-1] (that is,
|
||||
|
|
@ -902,7 +939,7 @@ roulette(
|
|||
|
||||
/* Find the lucky element by scanning the wheel. */
|
||||
for (i = 0; i < popsize; i++) {
|
||||
if (spin <= wheel[i]) break;
|
||||
if (spin <= wheel[i]) break;
|
||||
}
|
||||
*p1 = i;
|
||||
|
||||
|
|
@ -910,10 +947,10 @@ roulette(
|
|||
** distinct from the first.
|
||||
*/
|
||||
do {
|
||||
spin = wheel[popsize-1] * (double) Cudd_Random() / 2147483561.0;
|
||||
for (i = 0; i < popsize; i++) {
|
||||
if (spin <= wheel[i]) break;
|
||||
}
|
||||
spin = wheel[popsize-1] * (double) Cudd_Random() / 2147483561.0;
|
||||
for (i = 0; i < popsize; i++) {
|
||||
if (spin <= wheel[i]) break;
|
||||
}
|
||||
} while (i == *p1);
|
||||
*p2 = i;
|
||||
|
||||
|
|
@ -922,5 +959,7 @@ roulette(
|
|||
|
||||
} /* end of roulette */
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -7,17 +7,44 @@
|
|||
Synopsis [Function to read a matrix in Harwell format.]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_addHarwell()
|
||||
</ul>
|
||||
]
|
||||
<ul>
|
||||
<li> Cudd_addHarwell()
|
||||
</ul>
|
||||
]
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -27,6 +54,7 @@
|
|||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -47,7 +75,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddHarwell.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddHarwell.c,v 1.9 2004/08/13 18:04:49 fabio Exp $";
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -116,16 +144,16 @@ Cudd_addHarwell(
|
|||
DdNode *cubex, *cubey, *minterm1;
|
||||
int u, v, err, i, j, nv;
|
||||
double val;
|
||||
DdNode **lx = NULL, **ly = NULL, **lxn = NULL, **lyn = NULL; /* local copies of x, y, xn, yn_ */ /* Suppress "might be used uninitialized */
|
||||
int lnx, lny; /* local copies of nx and ny */
|
||||
DdNode **lx, **ly, **lxn, **lyn; /* local copies of x, y, xn, yn_ */
|
||||
int lnx, lny; /* local copies of nx and ny */
|
||||
char title[73], key[9], mxtype[4], rhstyp[4];
|
||||
int totcrd, ptrcrd, indcrd, valcrd, rhscrd,
|
||||
nrow, ncol, nnzero, neltvl,
|
||||
nrhs, nrhsix;
|
||||
nrhs, nrhsix;
|
||||
int *colptr, *rowind;
|
||||
#if 0
|
||||
int nguess, nexact;
|
||||
int *rhsptr, *rhsind;
|
||||
int *rhsptr, *rhsind;
|
||||
#endif
|
||||
|
||||
if (*nx < 0 || *ny < 0) return(0);
|
||||
|
|
@ -136,7 +164,7 @@ Cudd_addHarwell(
|
|||
/* Read the header */
|
||||
err = fscanf(fp, "%72c %8c", title, key);
|
||||
if (err == EOF) {
|
||||
return(0);
|
||||
return(0);
|
||||
} else if (err != 2) {
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -146,7 +174,7 @@ Cudd_addHarwell(
|
|||
err = fscanf(fp, "%d %d %d %d %d", &totcrd, &ptrcrd, &indcrd,
|
||||
&valcrd, &rhscrd);
|
||||
if (err == EOF) {
|
||||
return(0);
|
||||
return(0);
|
||||
} else if (err != 5) {
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -154,55 +182,55 @@ Cudd_addHarwell(
|
|||
err = fscanf(fp, "%3s %d %d %d %d", mxtype, &nrow, &ncol,
|
||||
&nnzero, &neltvl);
|
||||
if (err == EOF) {
|
||||
return(0);
|
||||
return(0);
|
||||
} else if (err != 5) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Skip FORTRAN formats */
|
||||
if (rhscrd == 0) {
|
||||
err = fscanf(fp, "%*s %*s %*s \n");
|
||||
err = fscanf(fp, "%*s %*s %*s \n");
|
||||
} else {
|
||||
err = fscanf(fp, "%*s %*s %*s %*s \n");
|
||||
err = fscanf(fp, "%*s %*s %*s %*s \n");
|
||||
}
|
||||
if (err == EOF) {
|
||||
return(0);
|
||||
return(0);
|
||||
} else if (err != 0) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Print out some stuff if requested to be verbose */
|
||||
if (pr>0) {
|
||||
(void) fprintf(dd->out,"%s: type %s, %d rows, %d columns, %d entries\n", key,
|
||||
mxtype, nrow, ncol, nnzero);
|
||||
if (pr>1) (void) fprintf(dd->out,"%s\n", title);
|
||||
(void) fprintf(dd->out,"%s: type %s, %d rows, %d columns, %d entries\n", key,
|
||||
mxtype, nrow, ncol, nnzero);
|
||||
if (pr>1) (void) fprintf(dd->out,"%s\n", title);
|
||||
}
|
||||
|
||||
/* Check matrix type */
|
||||
if (mxtype[0] != 'R' || mxtype[1] != 'U' || mxtype[2] != 'A') {
|
||||
(void) fprintf(dd->err,"%s: Illegal matrix type: %s\n",
|
||||
key, mxtype);
|
||||
return(0);
|
||||
(void) fprintf(dd->err,"%s: Illegal matrix type: %s\n",
|
||||
key, mxtype);
|
||||
return(0);
|
||||
}
|
||||
if (neltvl != 0) return(0);
|
||||
|
||||
/* Read optional 5-th line */
|
||||
if (rhscrd != 0) {
|
||||
err = fscanf(fp, "%3c %d %d", rhstyp, &nrhs, &nrhsix);
|
||||
if (err == EOF) {
|
||||
return(0);
|
||||
} else if (err != 3) {
|
||||
return(0);
|
||||
}
|
||||
rhstyp[3] = (char) 0;
|
||||
if (rhstyp[0] != 'F') {
|
||||
(void) fprintf(dd->err,
|
||||
"%s: Sparse right-hand side not yet supported\n", key);
|
||||
return(0);
|
||||
}
|
||||
if (pr>0) (void) fprintf(dd->out,"%d right-hand side(s)\n", nrhs);
|
||||
err = fscanf(fp, "%3c %d %d", rhstyp, &nrhs, &nrhsix);
|
||||
if (err == EOF) {
|
||||
return(0);
|
||||
} else if (err != 3) {
|
||||
return(0);
|
||||
}
|
||||
rhstyp[3] = (char) 0;
|
||||
if (rhstyp[0] != 'F') {
|
||||
(void) fprintf(dd->err,
|
||||
"%s: Sparse right-hand side not yet supported\n", key);
|
||||
return(0);
|
||||
}
|
||||
if (pr>0) (void) fprintf(dd->out,"%d right-hand side(s)\n", nrhs);
|
||||
} else {
|
||||
nrhs = 0;
|
||||
nrhs = 0;
|
||||
}
|
||||
|
||||
/* Compute the number of variables */
|
||||
|
|
@ -210,109 +238,109 @@ Cudd_addHarwell(
|
|||
/* row and column numbers start from 0 */
|
||||
u = nrow - 1;
|
||||
for (i=0; u > 0; i++) {
|
||||
u >>= 1;
|
||||
u >>= 1;
|
||||
}
|
||||
lnx = i;
|
||||
if (nrhs == 0) {
|
||||
v = ncol - 1;
|
||||
v = ncol - 1;
|
||||
} else {
|
||||
v = 2* (ddMax(ncol, nrhs) - 1);
|
||||
v = 2* (ddMax(ncol, nrhs) - 1);
|
||||
}
|
||||
for (i=0; v > 0; i++) {
|
||||
v >>= 1;
|
||||
v >>= 1;
|
||||
}
|
||||
lny = i;
|
||||
|
||||
/* Allocate or reallocate arrays for variables as needed */
|
||||
if (*nx == 0) {
|
||||
if (lnx > 0) {
|
||||
*x = lx = ABC_ALLOC(DdNode *,lnx);
|
||||
if (lx == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
if (lnx > 0) {
|
||||
*x = lx = ABC_ALLOC(DdNode *,lnx);
|
||||
if (lx == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
*xn = lxn = ABC_ALLOC(DdNode *,lnx);
|
||||
if (lxn == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
} else {
|
||||
*x = *xn = NULL;
|
||||
}
|
||||
*xn = lxn = ABC_ALLOC(DdNode *,lnx);
|
||||
if (lxn == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
} else {
|
||||
*x = *xn = NULL;
|
||||
}
|
||||
} else if (lnx > *nx) {
|
||||
*x = lx = ABC_REALLOC(DdNode *, *x, lnx);
|
||||
if (lx == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
*xn = lxn = ABC_REALLOC(DdNode *, *xn, lnx);
|
||||
if (lxn == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
*x = lx = ABC_REALLOC(DdNode *, *x, lnx);
|
||||
if (lx == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
*xn = lxn = ABC_REALLOC(DdNode *, *xn, lnx);
|
||||
if (lxn == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
} else {
|
||||
lx = *x;
|
||||
lxn = *xn;
|
||||
lx = *x;
|
||||
lxn = *xn;
|
||||
}
|
||||
if (*ny == 0) {
|
||||
if (lny >0) {
|
||||
*y = ly = ABC_ALLOC(DdNode *,lny);
|
||||
if (ly == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
if (lny >0) {
|
||||
*y = ly = ABC_ALLOC(DdNode *,lny);
|
||||
if (ly == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
*yn_ = lyn = ABC_ALLOC(DdNode *,lny);
|
||||
if (lyn == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
} else {
|
||||
*y = *yn_ = NULL;
|
||||
}
|
||||
*yn_ = lyn = ABC_ALLOC(DdNode *,lny);
|
||||
if (lyn == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
} else {
|
||||
*y = *yn_ = NULL;
|
||||
}
|
||||
} else if (lny > *ny) {
|
||||
*y = ly = ABC_REALLOC(DdNode *, *y, lny);
|
||||
if (ly == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
*yn_ = lyn = ABC_REALLOC(DdNode *, *yn_, lny);
|
||||
if (lyn == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
*y = ly = ABC_REALLOC(DdNode *, *y, lny);
|
||||
if (ly == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
*yn_ = lyn = ABC_REALLOC(DdNode *, *yn_, lny);
|
||||
if (lyn == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
} else {
|
||||
ly = *y;
|
||||
lyn = *yn_;
|
||||
ly = *y;
|
||||
lyn = *yn_;
|
||||
}
|
||||
|
||||
/* Create new variables as needed */
|
||||
for (i= *nx,nv=bx+(*nx)*sx; i < lnx; i++,nv+=sx) {
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
lx[i] = cuddUniqueInter(dd, nv, one, zero);
|
||||
} while (dd->reordered == 1);
|
||||
if (lx[i] == NULL) return(0);
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
lx[i] = cuddUniqueInter(dd, nv, one, zero);
|
||||
} while (dd->reordered == 1);
|
||||
if (lx[i] == NULL) return(0);
|
||||
cuddRef(lx[i]);
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
lxn[i] = cuddUniqueInter(dd, nv, zero, one);
|
||||
} while (dd->reordered == 1);
|
||||
if (lxn[i] == NULL) return(0);
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
lxn[i] = cuddUniqueInter(dd, nv, zero, one);
|
||||
} while (dd->reordered == 1);
|
||||
if (lxn[i] == NULL) return(0);
|
||||
cuddRef(lxn[i]);
|
||||
}
|
||||
for (i= *ny,nv=by+(*ny)*sy; i < lny; i++,nv+=sy) {
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
ly[i] = cuddUniqueInter(dd, nv, one, zero);
|
||||
} while (dd->reordered == 1);
|
||||
if (ly[i] == NULL) return(0);
|
||||
cuddRef(ly[i]);
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
lyn[i] = cuddUniqueInter(dd, nv, zero, one);
|
||||
} while (dd->reordered == 1);
|
||||
if (lyn[i] == NULL) return(0);
|
||||
cuddRef(lyn[i]);
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
ly[i] = cuddUniqueInter(dd, nv, one, zero);
|
||||
} while (dd->reordered == 1);
|
||||
if (ly[i] == NULL) return(0);
|
||||
cuddRef(ly[i]);
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
lyn[i] = cuddUniqueInter(dd, nv, zero, one);
|
||||
} while (dd->reordered == 1);
|
||||
if (lyn[i] == NULL) return(0);
|
||||
cuddRef(lyn[i]);
|
||||
}
|
||||
|
||||
/* Update matrix parameters */
|
||||
|
|
@ -320,213 +348,213 @@ Cudd_addHarwell(
|
|||
*ny = lny;
|
||||
*m = nrow;
|
||||
if (nrhs == 0) {
|
||||
*n = ncol;
|
||||
*n = ncol;
|
||||
} else {
|
||||
*n = (1 << (lny - 1)) + nrhs;
|
||||
*n = (1 << (lny - 1)) + nrhs;
|
||||
}
|
||||
|
||||
/* Read structure data */
|
||||
colptr = ABC_ALLOC(int, ncol+1);
|
||||
if (colptr == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
rowind = ABC_ALLOC(int, nnzero);
|
||||
if (rowind == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
|
||||
for (i=0; i<ncol+1; i++) {
|
||||
err = fscanf(fp, " %d ", &u);
|
||||
if (err == EOF){
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
} else if (err != 1) {
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
}
|
||||
colptr[i] = u - 1;
|
||||
err = fscanf(fp, " %d ", &u);
|
||||
if (err == EOF){
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
} else if (err != 1) {
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
}
|
||||
colptr[i] = u - 1;
|
||||
}
|
||||
if (colptr[0] != 0) {
|
||||
(void) fprintf(dd->err,"%s: Unexpected colptr[0] (%d)\n",
|
||||
key,colptr[0]);
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
(void) fprintf(dd->err,"%s: Unexpected colptr[0] (%d)\n",
|
||||
key,colptr[0]);
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
}
|
||||
for (i=0; i<nnzero; i++) {
|
||||
err = fscanf(fp, " %d ", &u);
|
||||
if (err == EOF){
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
} else if (err != 1) {
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
}
|
||||
rowind[i] = u - 1;
|
||||
err = fscanf(fp, " %d ", &u);
|
||||
if (err == EOF){
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
} else if (err != 1) {
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
}
|
||||
rowind[i] = u - 1;
|
||||
}
|
||||
|
||||
*E = zero; cuddRef(*E);
|
||||
|
||||
for (j=0; j<ncol; j++) {
|
||||
v = j;
|
||||
cubey = one; cuddRef(cubey);
|
||||
for (nv = lny - 1; nv>=0; nv--) {
|
||||
if (v & 1) {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]);
|
||||
} else {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]);
|
||||
}
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
cubey = w;
|
||||
v >>= 1;
|
||||
}
|
||||
for (i=colptr[j]; i<colptr[j+1]; i++) {
|
||||
u = rowind[i];
|
||||
err = fscanf(fp, " %lf ", &val);
|
||||
if (err == EOF || err != 1){
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
}
|
||||
/* Create new Constant node if necessary */
|
||||
cubex = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) val);
|
||||
if (cubex == NULL) {
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(cubex);
|
||||
|
||||
for (nv = lnx - 1; nv>=0; nv--) {
|
||||
if (u & 1) {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]);
|
||||
} else {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]);
|
||||
}
|
||||
if (w == NULL) {
|
||||
v = j;
|
||||
cubey = one; cuddRef(cubey);
|
||||
for (nv = lny - 1; nv>=0; nv--) {
|
||||
if (v & 1) {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]);
|
||||
} else {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]);
|
||||
}
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
cubey = w;
|
||||
v >>= 1;
|
||||
}
|
||||
for (i=colptr[j]; i<colptr[j+1]; i++) {
|
||||
u = rowind[i];
|
||||
err = fscanf(fp, " %lf ", &val);
|
||||
if (err == EOF || err != 1){
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
}
|
||||
/* Create new Constant node if necessary */
|
||||
cubex = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) val);
|
||||
if (cubex == NULL) {
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(cubex);
|
||||
|
||||
for (nv = lnx - 1; nv>=0; nv--) {
|
||||
if (u & 1) {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]);
|
||||
} else {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]);
|
||||
}
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
Cudd_RecursiveDeref(dd, cubex);
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, cubex);
|
||||
cubex = w;
|
||||
u >>= 1;
|
||||
}
|
||||
minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex);
|
||||
if (minterm1 == NULL) {
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
Cudd_RecursiveDeref(dd, cubex);
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(minterm1);
|
||||
Cudd_RecursiveDeref(dd, cubex);
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1);
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
Cudd_RecursiveDeref(dd, *E);
|
||||
*E = w;
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, cubex);
|
||||
cubex = w;
|
||||
u >>= 1;
|
||||
}
|
||||
minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex);
|
||||
if (minterm1 == NULL) {
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
Cudd_RecursiveDeref(dd, cubex);
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(minterm1);
|
||||
Cudd_RecursiveDeref(dd, cubex);
|
||||
w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1);
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
Cudd_RecursiveDeref(dd, *E);
|
||||
*E = w;
|
||||
}
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
}
|
||||
ABC_FREE(colptr);
|
||||
ABC_FREE(rowind);
|
||||
|
||||
/* Read right-hand sides */
|
||||
for (j=0; j<nrhs; j++) {
|
||||
v = j + (1<< (lny-1));
|
||||
cubey = one; cuddRef(cubey);
|
||||
for (nv = lny - 1; nv>=0; nv--) {
|
||||
if (v & 1) {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]);
|
||||
} else {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]);
|
||||
}
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
cubey = w;
|
||||
v >>= 1;
|
||||
}
|
||||
for (i=0; i<nrow; i++) {
|
||||
u = i;
|
||||
err = fscanf(fp, " %lf ", &val);
|
||||
if (err == EOF || err != 1){
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
return(0);
|
||||
}
|
||||
/* Create new Constant node if necessary */
|
||||
if (val == (double) 0.0) continue;
|
||||
cubex = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) val);
|
||||
if (cubex == NULL) {
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(cubex);
|
||||
|
||||
for (nv = lnx - 1; nv>=0; nv--) {
|
||||
if (u & 1) {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]);
|
||||
} else {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]);
|
||||
}
|
||||
if (w == NULL) {
|
||||
v = j + (1<< (lny-1));
|
||||
cubey = one; cuddRef(cubey);
|
||||
for (nv = lny - 1; nv>=0; nv--) {
|
||||
if (v & 1) {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]);
|
||||
} else {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]);
|
||||
}
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
cubey = w;
|
||||
v >>= 1;
|
||||
}
|
||||
for (i=0; i<nrow; i++) {
|
||||
u = i;
|
||||
err = fscanf(fp, " %lf ", &val);
|
||||
if (err == EOF || err != 1){
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
return(0);
|
||||
}
|
||||
/* Create new Constant node if necessary */
|
||||
if (val == (double) 0.0) continue;
|
||||
cubex = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) val);
|
||||
if (cubex == NULL) {
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(cubex);
|
||||
|
||||
for (nv = lnx - 1; nv>=0; nv--) {
|
||||
if (u & 1) {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]);
|
||||
} else {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]);
|
||||
}
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
Cudd_RecursiveDeref(dd, cubex);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, cubex);
|
||||
cubex = w;
|
||||
u >>= 1;
|
||||
}
|
||||
minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex);
|
||||
if (minterm1 == NULL) {
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
Cudd_RecursiveDeref(dd, cubex);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(minterm1);
|
||||
Cudd_RecursiveDeref(dd, cubex);
|
||||
return(0);
|
||||
w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1);
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
Cudd_RecursiveDeref(dd, *E);
|
||||
*E = w;
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, cubex);
|
||||
cubex = w;
|
||||
u >>= 1;
|
||||
}
|
||||
minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex);
|
||||
if (minterm1 == NULL) {
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
Cudd_RecursiveDeref(dd, cubex);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(minterm1);
|
||||
Cudd_RecursiveDeref(dd, cubex);
|
||||
w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1);
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
Cudd_RecursiveDeref(dd, *E);
|
||||
*E = w;
|
||||
}
|
||||
Cudd_RecursiveDeref(dd, cubey);
|
||||
}
|
||||
|
||||
return(1);
|
||||
|
|
@ -542,5 +570,7 @@ Cudd_addHarwell(
|
|||
/* Definition of static functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,35 +7,61 @@
|
|||
Synopsis [Functions to initialize and shut down the DD manager.]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_Init()
|
||||
<li> Cudd_Quit()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddZddInitUniv()
|
||||
<li> cuddZddFreeUniv()
|
||||
</ul>
|
||||
]
|
||||
<ul>
|
||||
<li> Cudd_Init()
|
||||
<li> Cudd_Quit()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddZddInitUniv()
|
||||
<li> cuddZddFreeUniv()
|
||||
</ul>
|
||||
]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [ This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "util_hack.h"
|
||||
#define CUDD_MAIN
|
||||
#include "cuddInt.h"
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
#undef CUDD_MAIN
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
|
|
@ -57,7 +83,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddInit.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddInit.c,v 1.33 2007/07/01 05:10:50 fabio Exp $";
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -108,19 +134,19 @@ Cudd_Init(
|
|||
DdNode *one, *zero;
|
||||
unsigned int maxCacheSize;
|
||||
unsigned int looseUpTo;
|
||||
// extern void (*MMoutOfMemory)(long);
|
||||
void (*saveHandler)(long);
|
||||
extern DD_OOMFP MMoutOfMemory;
|
||||
DD_OOMFP saveHandler;
|
||||
|
||||
if (maxMemory == 0) {
|
||||
maxMemory = getSoftDataLimit();
|
||||
maxMemory = getSoftDataLimit();
|
||||
}
|
||||
looseUpTo = (unsigned int) ((maxMemory / sizeof(DdNode)) /
|
||||
DD_MAX_LOOSE_FRACTION);
|
||||
DD_MAX_LOOSE_FRACTION);
|
||||
unique = cuddInitTable(numVars,numVarsZ,numSlots,looseUpTo);
|
||||
unique->maxmem = (unsigned) maxMemory / 10 * 9;
|
||||
if (unique == NULL) return(NULL);
|
||||
unique->maxmem = (unsigned long) maxMemory / 10 * 9;
|
||||
maxCacheSize = (unsigned int) ((maxMemory / sizeof(DdCache)) /
|
||||
DD_MAX_CACHE_FRACTION);
|
||||
DD_MAX_CACHE_FRACTION);
|
||||
result = cuddInitCache(unique,cacheSize,maxCacheSize);
|
||||
if (result == 0) return(NULL);
|
||||
|
||||
|
|
@ -129,7 +155,7 @@ Cudd_Init(
|
|||
unique->stash = ABC_ALLOC(char,(maxMemory / DD_STASH_FRACTION) + 4);
|
||||
MMoutOfMemory = saveHandler;
|
||||
if (unique->stash == NULL) {
|
||||
(void) fprintf(unique->err,"Unable to set aside memory\n");
|
||||
(void) fprintf(unique->err,"Unable to set aside memory\n");
|
||||
}
|
||||
|
||||
/* Initialize constants. */
|
||||
|
|
@ -141,9 +167,9 @@ Cudd_Init(
|
|||
cuddRef(unique->zero);
|
||||
#ifdef HAVE_IEEE_754
|
||||
if (DD_PLUS_INF_VAL != DD_PLUS_INF_VAL * 3 ||
|
||||
DD_PLUS_INF_VAL != DD_PLUS_INF_VAL / 3) {
|
||||
(void) fprintf(unique->err,"Warning: Crippled infinite values\n");
|
||||
(void) fprintf(unique->err,"Recompile without -DHAVE_IEEE_754\n");
|
||||
DD_PLUS_INF_VAL != DD_PLUS_INF_VAL / 3) {
|
||||
(void) fprintf(unique->err,"Warning: Crippled infinite values\n");
|
||||
(void) fprintf(unique->err,"Recompile without -DHAVE_IEEE_754\n");
|
||||
}
|
||||
#endif
|
||||
unique->plusinfinity = cuddUniqueConst(unique,DD_PLUS_INF_VAL);
|
||||
|
|
@ -160,17 +186,17 @@ Cudd_Init(
|
|||
/* Create the projection functions. */
|
||||
unique->vars = ABC_ALLOC(DdNodePtr,unique->maxSize);
|
||||
if (unique->vars == NULL) {
|
||||
unique->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
unique->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
}
|
||||
for (i = 0; i < unique->size; i++) {
|
||||
unique->vars[i] = cuddUniqueInter(unique,i,one,zero);
|
||||
if (unique->vars[i] == NULL) return(0);
|
||||
cuddRef(unique->vars[i]);
|
||||
unique->vars[i] = cuddUniqueInter(unique,i,one,zero);
|
||||
if (unique->vars[i] == NULL) return(0);
|
||||
cuddRef(unique->vars[i]);
|
||||
}
|
||||
|
||||
if (unique->sizeZ)
|
||||
cuddZddInitUniv(unique);
|
||||
cuddZddInitUniv(unique);
|
||||
|
||||
unique->memused += sizeof(DdNode *) * unique->maxSize;
|
||||
|
||||
|
|
@ -226,29 +252,29 @@ int
|
|||
cuddZddInitUniv(
|
||||
DdManager * zdd)
|
||||
{
|
||||
DdNode *p, *res;
|
||||
int i;
|
||||
DdNode *p, *res;
|
||||
int i;
|
||||
|
||||
zdd->univ = ABC_ALLOC(DdNodePtr, zdd->sizeZ);
|
||||
if (zdd->univ == NULL) {
|
||||
zdd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
zdd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
|
||||
res = DD_ONE(zdd);
|
||||
cuddRef(res);
|
||||
for (i = zdd->sizeZ - 1; i >= 0; i--) {
|
||||
unsigned int index = zdd->invpermZ[i];
|
||||
p = res;
|
||||
res = cuddUniqueInterZdd(zdd, index, p, p);
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDerefZdd(zdd,p);
|
||||
ABC_FREE(zdd->univ);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(res);
|
||||
cuddDeref(p);
|
||||
zdd->univ[i] = res;
|
||||
unsigned int index = zdd->invpermZ[i];
|
||||
p = res;
|
||||
res = cuddUniqueInterZdd(zdd, index, p, p);
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDerefZdd(zdd,p);
|
||||
ABC_FREE(zdd->univ);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(res);
|
||||
cuddDeref(p);
|
||||
zdd->univ[i] = res;
|
||||
}
|
||||
|
||||
#ifdef DD_VERBOSE
|
||||
|
|
@ -276,8 +302,8 @@ cuddZddFreeUniv(
|
|||
DdManager * zdd)
|
||||
{
|
||||
if (zdd->univ) {
|
||||
Cudd_RecursiveDerefZdd(zdd, zdd->univ[0]);
|
||||
ABC_FREE(zdd->univ);
|
||||
Cudd_RecursiveDerefZdd(zdd, zdd->univ[0]);
|
||||
ABC_FREE(zdd->univ);
|
||||
}
|
||||
|
||||
} /* end of cuddZddFreeUniv */
|
||||
|
|
@ -287,5 +313,7 @@ cuddZddFreeUniv(
|
|||
/* Definition of static functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -7,18 +7,18 @@
|
|||
Synopsis [Functions to manipulate the variable interaction matrix.]
|
||||
|
||||
Description [Internal procedures included in this file:
|
||||
<ul>
|
||||
<li> cuddSetInteract()
|
||||
<li> cuddTestInteract()
|
||||
<li> cuddInitInteract()
|
||||
</ul>
|
||||
<ul>
|
||||
<li> cuddSetInteract()
|
||||
<li> cuddTestInteract()
|
||||
<li> cuddInitInteract()
|
||||
</ul>
|
||||
Static procedures included in this file:
|
||||
<ul>
|
||||
<li> ddSuppInteract()
|
||||
<li> ddClearLocal()
|
||||
<li> ddUpdateInteract()
|
||||
<li> ddClearGlobal()
|
||||
</ul>
|
||||
<ul>
|
||||
<li> ddSuppInteract()
|
||||
<li> ddClearLocal()
|
||||
<li> ddUpdateInteract()
|
||||
<li> ddClearGlobal()
|
||||
</ul>
|
||||
The interaction matrix tells whether two variables are
|
||||
both in the support of some function of the DD. The main use of the
|
||||
interaction matrix is in the in-place swapping. Indeed, if two
|
||||
|
|
@ -40,10 +40,37 @@
|
|||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [ This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -53,6 +80,7 @@
|
|||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -80,7 +108,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddInteract.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddInteract.c,v 1.12 2004/08/13 18:04:49 fabio Exp $";
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -94,10 +122,10 @@ static char rcsid[] DD_UNUSED = "$Id: cuddInteract.c,v 1.1.1.1 2003/02/24 22:23:
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static void ddSuppInteract ARGS((DdNode *f, int *support));
|
||||
static void ddClearLocal ARGS((DdNode *f));
|
||||
static void ddUpdateInteract ARGS((DdManager *table, int *support));
|
||||
static void ddClearGlobal ARGS((DdManager *table));
|
||||
static void ddSuppInteract (DdNode *f, int *support);
|
||||
static void ddClearLocal (DdNode *f);
|
||||
static void ddUpdateInteract (DdManager *table, int *support);
|
||||
static void ddClearGlobal (DdManager *table);
|
||||
|
||||
/**AutomaticEnd***************************************************************/
|
||||
|
||||
|
|
@ -168,9 +196,9 @@ cuddTestInteract(
|
|||
int posn, word, bit, result;
|
||||
|
||||
if (x > y) {
|
||||
int tmp = x;
|
||||
x = y;
|
||||
y = tmp;
|
||||
int tmp = x;
|
||||
x = y;
|
||||
y = tmp;
|
||||
}
|
||||
#ifdef DD_DEBUG
|
||||
assert(x < y);
|
||||
|
|
@ -222,43 +250,43 @@ cuddInitInteract(
|
|||
words = ((n * (n-1)) >> (1 + LOGBPL)) + 1;
|
||||
table->interact = interact = ABC_ALLOC(long,words);
|
||||
if (interact == NULL) {
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
for (i = 0; i < words; i++) {
|
||||
interact[i] = 0;
|
||||
interact[i] = 0;
|
||||
}
|
||||
|
||||
support = ABC_ALLOC(int,n);
|
||||
if (support == NULL) {
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
ABC_FREE(interact);
|
||||
return(0);
|
||||
table->errorCode = CUDD_MEMORY_OUT;
|
||||
ABC_FREE(interact);
|
||||
return(0);
|
||||
}
|
||||
|
||||
for (i = 0; i < n; 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)) {
|
||||
for (k = 0; k < n; k++) {
|
||||
support[k] = 0;
|
||||
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)) {
|
||||
for (k = 0; k < n; k++) {
|
||||
support[k] = 0;
|
||||
}
|
||||
ddSuppInteract(f,support);
|
||||
ddClearLocal(f);
|
||||
ddUpdateInteract(table,support);
|
||||
}
|
||||
f = Cudd_Regular(f->next);
|
||||
}
|
||||
ddSuppInteract(f,support);
|
||||
ddClearLocal(f);
|
||||
ddUpdateInteract(table,support);
|
||||
}
|
||||
f = Cudd_Regular(f->next);
|
||||
}
|
||||
}
|
||||
}
|
||||
ddClearGlobal(table);
|
||||
|
||||
|
|
@ -291,7 +319,7 @@ ddSuppInteract(
|
|||
int * support)
|
||||
{
|
||||
if (cuddIsConstant(f) || Cudd_IsComplement(cuddT(f))) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
support[f->index] = 1;
|
||||
|
|
@ -321,7 +349,7 @@ ddClearLocal(
|
|||
DdNode * f)
|
||||
{
|
||||
if (cuddIsConstant(f) || !Cudd_IsComplement(cuddT(f))) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
/* clear visited flag */
|
||||
cuddT(f) = Cudd_Regular(cuddT(f));
|
||||
|
|
@ -354,13 +382,13 @@ ddUpdateInteract(
|
|||
int n = table->size;
|
||||
|
||||
for (i = 0; i < n-1; i++) {
|
||||
if (support[i] == 1) {
|
||||
for (j = i+1; j < n; j++) {
|
||||
if (support[j] == 1) {
|
||||
cuddSetInteract(table,i,j);
|
||||
if (support[i] == 1) {
|
||||
for (j = i+1; j < n; j++) {
|
||||
if (support[j] == 1) {
|
||||
cuddSetInteract(table,i,j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* end of ddUpdateInteract */
|
||||
|
|
@ -390,18 +418,20 @@ ddClearGlobal(
|
|||
int slots;
|
||||
|
||||
for (i = 0; i < table->size; 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;
|
||||
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 */
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,55 +7,83 @@
|
|||
Synopsis [Functions for local caches.]
|
||||
|
||||
Description [Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddLocalCacheInit()
|
||||
<li> cuddLocalCacheQuit()
|
||||
<li> cuddLocalCacheInsert()
|
||||
<li> cuddLocalCacheLookup()
|
||||
<li> cuddLocalCacheClearDead()
|
||||
<li> cuddLocalCacheClearAll()
|
||||
<li> cuddLocalCacheProfile()
|
||||
<li> cuddHashTableInit()
|
||||
<li> cuddHashTableQuit()
|
||||
<li> cuddHashTableInsert()
|
||||
<li> cuddHashTableLookup()
|
||||
<li> cuddHashTableInsert2()
|
||||
<li> cuddHashTableLookup2()
|
||||
<li> cuddHashTableInsert3()
|
||||
<li> cuddHashTableLookup3()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddLocalCacheResize()
|
||||
<li> ddLCHash()
|
||||
<li> cuddLocalCacheAddToList()
|
||||
<li> cuddLocalCacheRemoveFromList()
|
||||
<li> cuddHashTableResize()
|
||||
<li> cuddHashTableAlloc()
|
||||
</ul> ]
|
||||
<ul>
|
||||
<li> cuddLocalCacheInit()
|
||||
<li> cuddLocalCacheQuit()
|
||||
<li> cuddLocalCacheInsert()
|
||||
<li> cuddLocalCacheLookup()
|
||||
<li> cuddLocalCacheClearDead()
|
||||
<li> cuddLocalCacheClearAll()
|
||||
<li> cuddLocalCacheProfile()
|
||||
<li> cuddHashTableInit()
|
||||
<li> cuddHashTableQuit()
|
||||
<li> cuddHashTableInsert()
|
||||
<li> cuddHashTableLookup()
|
||||
<li> cuddHashTableInsert2()
|
||||
<li> cuddHashTableLookup2()
|
||||
<li> cuddHashTableInsert3()
|
||||
<li> cuddHashTableLookup3()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddLocalCacheResize()
|
||||
<li> ddLCHash()
|
||||
<li> cuddLocalCacheAddToList()
|
||||
<li> cuddLocalCacheRemoveFromList()
|
||||
<li> cuddHashTableResize()
|
||||
<li> cuddHashTableAlloc()
|
||||
</ul> ]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [ This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#define DD_MAX_HASHTABLE_DENSITY 2 /* tells when to resize a table */
|
||||
#define DD_MAX_HASHTABLE_DENSITY 2 /* tells when to resize a table */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Stucture declarations */
|
||||
|
|
@ -72,7 +100,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddLCache.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddLCache.c,v 1.24 2009/03/08 02:49:02 fabio Exp $";
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -92,8 +120,8 @@ static char rcsid[] DD_UNUSED = "$Id: cuddLCache.c,v 1.1.1.1 2003/02/24 22:23:52
|
|||
******************************************************************************/
|
||||
#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
|
||||
#define ddLCHash2(f,g,shift) \
|
||||
((((unsigned)(unsigned long)(f) * DD_P1 + \
|
||||
(unsigned)(unsigned long)(g)) * DD_P2) >> (shift))
|
||||
((((unsigned)(ptruint)(f) * DD_P1 + \
|
||||
(unsigned)(ptruint)(g)) * DD_P2) >> (shift))
|
||||
#else
|
||||
#define ddLCHash2(f,g,shift) \
|
||||
((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (shift))
|
||||
|
|
@ -120,12 +148,12 @@ static char rcsid[] DD_UNUSED = "$Id: cuddLCache.c,v 1.1.1.1 2003/02/24 22:23:52
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static void cuddLocalCacheResize ARGS((DdLocalCache *cache));
|
||||
DD_INLINE static unsigned int ddLCHash ARGS((DdNodePtr *key, unsigned int keysize, int shift));
|
||||
static void cuddLocalCacheAddToList ARGS((DdLocalCache *cache));
|
||||
static void cuddLocalCacheRemoveFromList ARGS((DdLocalCache *cache));
|
||||
static int cuddHashTableResize ARGS((DdHashTable *hash));
|
||||
DD_INLINE static DdHashItem * cuddHashTableAlloc ARGS((DdHashTable *hash));
|
||||
static void cuddLocalCacheResize (DdLocalCache *cache);
|
||||
DD_INLINE static unsigned int ddLCHash (DdNodePtr *key, unsigned int keysize, int shift);
|
||||
static void cuddLocalCacheAddToList (DdLocalCache *cache);
|
||||
static void cuddLocalCacheRemoveFromList (DdLocalCache *cache);
|
||||
static int cuddHashTableResize (DdHashTable *hash);
|
||||
DD_INLINE static DdHashItem * cuddHashTableAlloc (DdHashTable *hash);
|
||||
|
||||
/**AutomaticEnd***************************************************************/
|
||||
|
||||
|
|
@ -163,8 +191,8 @@ cuddLocalCacheInit(
|
|||
|
||||
cache = ABC_ALLOC(DdLocalCache,1);
|
||||
if (cache == NULL) {
|
||||
manager->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
manager->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
}
|
||||
cache->manager = manager;
|
||||
cache->keysize = keySize;
|
||||
|
|
@ -175,11 +203,11 @@ cuddLocalCacheInit(
|
|||
logSize = cuddComputeFloorLog2(ddMax(cacheSize,manager->slots/2));
|
||||
cacheSize = 1 << logSize;
|
||||
cache->item = (DdLocalCacheItem *)
|
||||
ABC_ALLOC(char, cacheSize * cache->itemsize);
|
||||
ABC_ALLOC(char, cacheSize * cache->itemsize);
|
||||
if (cache->item == NULL) {
|
||||
manager->errorCode = CUDD_MEMORY_OUT;
|
||||
ABC_FREE(cache);
|
||||
return(NULL);
|
||||
manager->errorCode = CUDD_MEMORY_OUT;
|
||||
ABC_FREE(cache);
|
||||
return(NULL);
|
||||
}
|
||||
cache->slots = cacheSize;
|
||||
cache->shift = sizeof(int) * 8 - logSize;
|
||||
|
|
@ -219,7 +247,7 @@ cuddLocalCacheQuit(
|
|||
DdLocalCache * cache /* cache to be shut down */)
|
||||
{
|
||||
cache->manager->memused -=
|
||||
cache->slots * cache->itemsize + sizeof(DdLocalCache);
|
||||
cache->slots * cache->itemsize + sizeof(DdLocalCache);
|
||||
cuddLocalCacheRemoveFromList(cache);
|
||||
ABC_FREE(cache->item);
|
||||
ABC_FREE(cache);
|
||||
|
|
@ -251,7 +279,7 @@ cuddLocalCacheInsert(
|
|||
|
||||
posn = ddLCHash(key,cache->keysize,cache->shift);
|
||||
entry = (DdLocalCacheItem *) ((char *) cache->item +
|
||||
posn * cache->itemsize);
|
||||
posn * cache->itemsize);
|
||||
memcpy(entry->key,key,cache->keysize * sizeof(DdNode *));
|
||||
entry->value = value;
|
||||
#ifdef DD_CACHE_PROFILE
|
||||
|
|
@ -285,22 +313,22 @@ cuddLocalCacheLookup(
|
|||
cache->lookUps++;
|
||||
posn = ddLCHash(key,cache->keysize,cache->shift);
|
||||
entry = (DdLocalCacheItem *) ((char *) cache->item +
|
||||
posn * cache->itemsize);
|
||||
posn * cache->itemsize);
|
||||
if (entry->value != NULL &&
|
||||
memcmp(key,entry->key,cache->keysize*sizeof(DdNode *)) == 0) {
|
||||
cache->hits++;
|
||||
value = Cudd_Regular(entry->value);
|
||||
if (value->ref == 0) {
|
||||
cuddReclaim(cache->manager,value);
|
||||
}
|
||||
return(entry->value);
|
||||
memcmp(key,entry->key,cache->keysize*sizeof(DdNode *)) == 0) {
|
||||
cache->hits++;
|
||||
value = Cudd_Regular(entry->value);
|
||||
if (value->ref == 0) {
|
||||
cuddReclaim(cache->manager,value);
|
||||
}
|
||||
return(entry->value);
|
||||
}
|
||||
|
||||
/* Cache miss: decide whether to resize */
|
||||
|
||||
if (cache->slots < cache->maxslots &&
|
||||
cache->hits > cache->lookUps * cache->minHit) {
|
||||
cuddLocalCacheResize(cache);
|
||||
cache->hits > cache->lookUps * cache->minHit) {
|
||||
cuddLocalCacheResize(cache);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
|
|
@ -333,25 +361,27 @@ cuddLocalCacheClearDead(
|
|||
unsigned int i, j;
|
||||
|
||||
while (cache != NULL) {
|
||||
keysize = cache->keysize;
|
||||
itemsize = cache->itemsize;
|
||||
slots = cache->slots;
|
||||
item = cache->item;
|
||||
for (i = 0; i < slots; i++) {
|
||||
if (item->value != NULL && Cudd_Regular(item->value)->ref == 0) {
|
||||
item->value = NULL;
|
||||
} else {
|
||||
key = item->key;
|
||||
for (j = 0; j < keysize; j++) {
|
||||
if (Cudd_Regular(key[j])->ref == 0) {
|
||||
item->value = NULL;
|
||||
break;
|
||||
keysize = cache->keysize;
|
||||
itemsize = cache->itemsize;
|
||||
slots = cache->slots;
|
||||
item = cache->item;
|
||||
for (i = 0; i < slots; i++) {
|
||||
if (item->value != NULL) {
|
||||
if (Cudd_Regular(item->value)->ref == 0) {
|
||||
item->value = NULL;
|
||||
} else {
|
||||
key = item->key;
|
||||
for (j = 0; j < keysize; j++) {
|
||||
if (Cudd_Regular(key[j])->ref == 0) {
|
||||
item->value = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
item = (DdLocalCacheItem *) ((char *) item + itemsize);
|
||||
}
|
||||
}
|
||||
item = (DdLocalCacheItem *) ((char *) item + itemsize);
|
||||
}
|
||||
cache = cache->next;
|
||||
cache = cache->next;
|
||||
}
|
||||
return;
|
||||
|
||||
|
|
@ -377,8 +407,8 @@ cuddLocalCacheClearAll(
|
|||
DdLocalCache *cache = manager->localCaches;
|
||||
|
||||
while (cache != NULL) {
|
||||
memset(cache->item, 0, cache->slots * cache->itemsize);
|
||||
cache = cache->next;
|
||||
memset(cache->item, 0, cache->slots * cache->itemsize);
|
||||
cache = cache->next;
|
||||
}
|
||||
return;
|
||||
|
||||
|
|
@ -427,34 +457,34 @@ cuddLocalCacheProfile(
|
|||
|
||||
hystogram = ABC_ALLOC(long, nbins);
|
||||
if (hystogram == NULL) {
|
||||
return(0);
|
||||
return(0);
|
||||
}
|
||||
for (i = 0; i < nbins; i++) {
|
||||
hystogram[i] = 0;
|
||||
hystogram[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < slots; i++) {
|
||||
entry = (DdLocalCacheItem *) ((char *) cache->item +
|
||||
i * cache->itemsize);
|
||||
thiscount = (long) entry->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;
|
||||
hystogram[bin] += thiscount;
|
||||
entry = (DdLocalCacheItem *) ((char *) cache->item +
|
||||
i * cache->itemsize);
|
||||
thiscount = (long) entry->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;
|
||||
hystogram[bin] += thiscount;
|
||||
}
|
||||
mean /= (double) slots;
|
||||
meansq /= (double) slots;
|
||||
|
|
@ -472,17 +502,17 @@ cuddLocalCacheProfile(
|
|||
if (retval == EOF) return(0);
|
||||
|
||||
if (totalcount) {
|
||||
expected /= totalcount;
|
||||
retval = fprintf(fp,"Cache access hystogram for %d bins", nbins);
|
||||
if (retval == EOF) return(0);
|
||||
retval = fprintf(fp," (expected bin value = %g)\n# ", expected);
|
||||
if (retval == EOF) return(0);
|
||||
for (i = nbins - 1; i>=0; i--) {
|
||||
retval = fprintf(fp,"%ld ", hystogram[i]);
|
||||
expected /= totalcount;
|
||||
retval = fprintf(fp,"Cache access hystogram for %d bins", nbins);
|
||||
if (retval == EOF) return(0);
|
||||
retval = fprintf(fp," (expected bin value = %g)\n# ", expected);
|
||||
if (retval == EOF) return(0);
|
||||
for (i = nbins - 1; i>=0; i--) {
|
||||
retval = fprintf(fp,"%ld ", hystogram[i]);
|
||||
if (retval == EOF) return(0);
|
||||
}
|
||||
retval = fprintf(fp,"\n");
|
||||
if (retval == EOF) return(0);
|
||||
}
|
||||
retval = fprintf(fp,"\n");
|
||||
if (retval == EOF) return(0);
|
||||
}
|
||||
|
||||
ABC_FREE(hystogram);
|
||||
|
|
@ -519,15 +549,15 @@ cuddHashTableInit(
|
|||
#endif
|
||||
hash = ABC_ALLOC(DdHashTable, 1);
|
||||
if (hash == NULL) {
|
||||
manager->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
manager->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
}
|
||||
hash->keysize = keySize;
|
||||
hash->manager = manager;
|
||||
hash->memoryList = NULL;
|
||||
hash->nextFree = NULL;
|
||||
hash->itemsize = (keySize + 1) * sizeof(DdNode *) +
|
||||
sizeof(ptrint) + sizeof(DdHashItem *);
|
||||
sizeof(ptrint) + sizeof(DdHashItem *);
|
||||
/* We have to guarantee that the shift be < 32. */
|
||||
if (initSize < 2) initSize = 2;
|
||||
logSize = cuddComputeFloorLog2(initSize);
|
||||
|
|
@ -535,9 +565,9 @@ cuddHashTableInit(
|
|||
hash->shift = sizeof(int) * 8 - logSize;
|
||||
hash->bucket = ABC_ALLOC(DdHashItem *, hash->numBuckets);
|
||||
if (hash->bucket == NULL) {
|
||||
manager->errorCode = CUDD_MEMORY_OUT;
|
||||
ABC_FREE(hash);
|
||||
return(NULL);
|
||||
manager->errorCode = CUDD_MEMORY_OUT;
|
||||
ABC_FREE(hash);
|
||||
return(NULL);
|
||||
}
|
||||
memset(hash->bucket, 0, hash->numBuckets * sizeof(DdHashItem *));
|
||||
hash->size = 0;
|
||||
|
|
@ -576,18 +606,18 @@ cuddHashTableQuit(
|
|||
unsigned int numBuckets = hash->numBuckets;
|
||||
|
||||
for (i = 0; i < numBuckets; i++) {
|
||||
bucket = hash->bucket[i];
|
||||
while (bucket != NULL) {
|
||||
Cudd_RecursiveDeref(dd, bucket->value);
|
||||
bucket = bucket->next;
|
||||
}
|
||||
bucket = hash->bucket[i];
|
||||
while (bucket != NULL) {
|
||||
Cudd_RecursiveDeref(dd, bucket->value);
|
||||
bucket = bucket->next;
|
||||
}
|
||||
}
|
||||
|
||||
memlist = hash->memoryList;
|
||||
while (memlist != NULL) {
|
||||
nextmem = (DdHashItem **) memlist[0];
|
||||
ABC_FREE(memlist);
|
||||
memlist = nextmem;
|
||||
nextmem = (DdHashItem **) memlist[0];
|
||||
ABC_FREE(memlist);
|
||||
memlist = nextmem;
|
||||
}
|
||||
|
||||
ABC_FREE(hash->bucket);
|
||||
|
|
@ -631,8 +661,8 @@ cuddHashTableInsert(
|
|||
#endif
|
||||
|
||||
if (hash->size > hash->maxsize) {
|
||||
result = cuddHashTableResize(hash);
|
||||
if (result == 0) return(0);
|
||||
result = cuddHashTableResize(hash);
|
||||
if (result == 0) return(0);
|
||||
}
|
||||
item = cuddHashTableAlloc(hash);
|
||||
if (item == NULL) return(0);
|
||||
|
|
@ -641,7 +671,7 @@ cuddHashTableInsert(
|
|||
cuddRef(value);
|
||||
item->count = count;
|
||||
for (i = 0; i < hash->keysize; i++) {
|
||||
item->key[i] = key[i];
|
||||
item->key[i] = key[i];
|
||||
}
|
||||
posn = ddLCHash(key,hash->keysize,hash->shift);
|
||||
item->next = hash->bucket[posn];
|
||||
|
|
@ -688,32 +718,32 @@ cuddHashTableLookup(
|
|||
|
||||
keysize = hash->keysize;
|
||||
while (item != NULL) {
|
||||
DdNodePtr *key2 = item->key;
|
||||
int equal = 1;
|
||||
for (i = 0; i < keysize; i++) {
|
||||
if (key[i] != key2[i]) {
|
||||
equal = 0;
|
||||
break;
|
||||
DdNodePtr *key2 = item->key;
|
||||
int equal = 1;
|
||||
for (i = 0; i < keysize; i++) {
|
||||
if (key[i] != key2[i]) {
|
||||
equal = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (equal) {
|
||||
DdNode *value = item->value;
|
||||
cuddSatDec(item->count);
|
||||
if (item->count == 0) {
|
||||
cuddDeref(value);
|
||||
if (prev == NULL) {
|
||||
hash->bucket[posn] = item->next;
|
||||
} else {
|
||||
prev->next = item->next;
|
||||
if (equal) {
|
||||
DdNode *value = item->value;
|
||||
cuddSatDec(item->count);
|
||||
if (item->count == 0) {
|
||||
cuddDeref(value);
|
||||
if (prev == NULL) {
|
||||
hash->bucket[posn] = item->next;
|
||||
} else {
|
||||
prev->next = item->next;
|
||||
}
|
||||
item->next = hash->nextFree;
|
||||
hash->nextFree = item;
|
||||
hash->size--;
|
||||
}
|
||||
return(value);
|
||||
}
|
||||
item->next = hash->nextFree;
|
||||
hash->nextFree = item;
|
||||
hash->size--;
|
||||
}
|
||||
return(value);
|
||||
}
|
||||
prev = item;
|
||||
item = item->next;
|
||||
prev = item;
|
||||
item = item->next;
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -749,8 +779,8 @@ cuddHashTableInsert1(
|
|||
#endif
|
||||
|
||||
if (hash->size > hash->maxsize) {
|
||||
result = cuddHashTableResize(hash);
|
||||
if (result == 0) return(0);
|
||||
result = cuddHashTableResize(hash);
|
||||
if (result == 0) return(0);
|
||||
}
|
||||
item = cuddHashTableAlloc(hash);
|
||||
if (item == NULL) return(0);
|
||||
|
|
@ -776,7 +806,7 @@ cuddHashTableInsert1(
|
|||
Returns the value associated to the key if there is an entry for the given
|
||||
key in the table; NULL otherwise. If the entry is present, its reference
|
||||
counter is decremented if not saturated. If the counter reaches 0, the
|
||||
value of the entry is dereferenced, and the entry is returned to the ABC_FREE
|
||||
value of the entry is dereferenced, and the entry is returned to the free
|
||||
list.]
|
||||
|
||||
SideEffects [None]
|
||||
|
|
@ -802,25 +832,25 @@ cuddHashTableLookup1(
|
|||
prev = NULL;
|
||||
|
||||
while (item != NULL) {
|
||||
DdNodePtr *key = item->key;
|
||||
if (f == key[0]) {
|
||||
DdNode *value = item->value;
|
||||
cuddSatDec(item->count);
|
||||
if (item->count == 0) {
|
||||
cuddDeref(value);
|
||||
if (prev == NULL) {
|
||||
hash->bucket[posn] = item->next;
|
||||
} else {
|
||||
prev->next = item->next;
|
||||
DdNodePtr *key = item->key;
|
||||
if (f == key[0]) {
|
||||
DdNode *value = item->value;
|
||||
cuddSatDec(item->count);
|
||||
if (item->count == 0) {
|
||||
cuddDeref(value);
|
||||
if (prev == NULL) {
|
||||
hash->bucket[posn] = item->next;
|
||||
} else {
|
||||
prev->next = item->next;
|
||||
}
|
||||
item->next = hash->nextFree;
|
||||
hash->nextFree = item;
|
||||
hash->size--;
|
||||
}
|
||||
return(value);
|
||||
}
|
||||
item->next = hash->nextFree;
|
||||
hash->nextFree = item;
|
||||
hash->size--;
|
||||
}
|
||||
return(value);
|
||||
}
|
||||
prev = item;
|
||||
item = item->next;
|
||||
prev = item;
|
||||
item = item->next;
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -857,8 +887,8 @@ cuddHashTableInsert2(
|
|||
#endif
|
||||
|
||||
if (hash->size > hash->maxsize) {
|
||||
result = cuddHashTableResize(hash);
|
||||
if (result == 0) return(0);
|
||||
result = cuddHashTableResize(hash);
|
||||
if (result == 0) return(0);
|
||||
}
|
||||
item = cuddHashTableAlloc(hash);
|
||||
if (item == NULL) return(0);
|
||||
|
|
@ -885,7 +915,7 @@ cuddHashTableInsert2(
|
|||
Returns the value associated to the key if there is an entry for the given
|
||||
key in the table; NULL otherwise. If the entry is present, its reference
|
||||
counter is decremented if not saturated. If the counter reaches 0, the
|
||||
value of the entry is dereferenced, and the entry is returned to the ABC_FREE
|
||||
value of the entry is dereferenced, and the entry is returned to the free
|
||||
list.]
|
||||
|
||||
SideEffects [None]
|
||||
|
|
@ -912,25 +942,25 @@ cuddHashTableLookup2(
|
|||
prev = NULL;
|
||||
|
||||
while (item != NULL) {
|
||||
DdNodePtr *key = item->key;
|
||||
if ((f == key[0]) && (g == key[1])) {
|
||||
DdNode *value = item->value;
|
||||
cuddSatDec(item->count);
|
||||
if (item->count == 0) {
|
||||
cuddDeref(value);
|
||||
if (prev == NULL) {
|
||||
hash->bucket[posn] = item->next;
|
||||
} else {
|
||||
prev->next = item->next;
|
||||
DdNodePtr *key = item->key;
|
||||
if ((f == key[0]) && (g == key[1])) {
|
||||
DdNode *value = item->value;
|
||||
cuddSatDec(item->count);
|
||||
if (item->count == 0) {
|
||||
cuddDeref(value);
|
||||
if (prev == NULL) {
|
||||
hash->bucket[posn] = item->next;
|
||||
} else {
|
||||
prev->next = item->next;
|
||||
}
|
||||
item->next = hash->nextFree;
|
||||
hash->nextFree = item;
|
||||
hash->size--;
|
||||
}
|
||||
return(value);
|
||||
}
|
||||
item->next = hash->nextFree;
|
||||
hash->nextFree = item;
|
||||
hash->size--;
|
||||
}
|
||||
return(value);
|
||||
}
|
||||
prev = item;
|
||||
item = item->next;
|
||||
prev = item;
|
||||
item = item->next;
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -968,8 +998,8 @@ cuddHashTableInsert3(
|
|||
#endif
|
||||
|
||||
if (hash->size > hash->maxsize) {
|
||||
result = cuddHashTableResize(hash);
|
||||
if (result == 0) return(0);
|
||||
result = cuddHashTableResize(hash);
|
||||
if (result == 0) return(0);
|
||||
}
|
||||
item = cuddHashTableAlloc(hash);
|
||||
if (item == NULL) return(0);
|
||||
|
|
@ -997,7 +1027,7 @@ cuddHashTableInsert3(
|
|||
Returns the value associated to the key if there is an entry for the given
|
||||
key in the table; NULL otherwise. If the entry is present, its reference
|
||||
counter is decremented if not saturated. If the counter reaches 0, the
|
||||
value of the entry is dereferenced, and the entry is returned to the ABC_FREE
|
||||
value of the entry is dereferenced, and the entry is returned to the free
|
||||
list.]
|
||||
|
||||
SideEffects [None]
|
||||
|
|
@ -1025,25 +1055,25 @@ cuddHashTableLookup3(
|
|||
prev = NULL;
|
||||
|
||||
while (item != NULL) {
|
||||
DdNodePtr *key = item->key;
|
||||
if ((f == key[0]) && (g == key[1]) && (h == key[2])) {
|
||||
DdNode *value = item->value;
|
||||
cuddSatDec(item->count);
|
||||
if (item->count == 0) {
|
||||
cuddDeref(value);
|
||||
if (prev == NULL) {
|
||||
hash->bucket[posn] = item->next;
|
||||
} else {
|
||||
prev->next = item->next;
|
||||
DdNodePtr *key = item->key;
|
||||
if ((f == key[0]) && (g == key[1]) && (h == key[2])) {
|
||||
DdNode *value = item->value;
|
||||
cuddSatDec(item->count);
|
||||
if (item->count == 0) {
|
||||
cuddDeref(value);
|
||||
if (prev == NULL) {
|
||||
hash->bucket[posn] = item->next;
|
||||
} else {
|
||||
prev->next = item->next;
|
||||
}
|
||||
item->next = hash->nextFree;
|
||||
hash->nextFree = item;
|
||||
hash->size--;
|
||||
}
|
||||
return(value);
|
||||
}
|
||||
item->next = hash->nextFree;
|
||||
hash->nextFree = item;
|
||||
hash->size--;
|
||||
}
|
||||
return(value);
|
||||
}
|
||||
prev = item;
|
||||
item = item->next;
|
||||
prev = item;
|
||||
item = item->next;
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -1074,8 +1104,8 @@ cuddLocalCacheResize(
|
|||
int i, shift;
|
||||
unsigned int posn;
|
||||
unsigned int slots, oldslots;
|
||||
// extern void (*MMoutOfMemory)(long);
|
||||
void (*saveHandler)(long);
|
||||
extern DD_OOMFP MMoutOfMemory;
|
||||
DD_OOMFP saveHandler;
|
||||
|
||||
olditem = cache->item;
|
||||
oldslots = cache->slots;
|
||||
|
|
@ -1083,28 +1113,28 @@ cuddLocalCacheResize(
|
|||
|
||||
#ifdef DD_VERBOSE
|
||||
(void) fprintf(cache->manager->err,
|
||||
"Resizing local cache from %d to %d entries\n",
|
||||
oldslots, slots);
|
||||
"Resizing local cache from %d to %d entries\n",
|
||||
oldslots, slots);
|
||||
(void) fprintf(cache->manager->err,
|
||||
"\thits = %.0f\tlookups = %.0f\thit ratio = %5.3f\n",
|
||||
cache->hits, cache->lookUps, cache->hits / cache->lookUps);
|
||||
"\thits = %.0f\tlookups = %.0f\thit ratio = %5.3f\n",
|
||||
cache->hits, cache->lookUps, cache->hits / cache->lookUps);
|
||||
#endif
|
||||
|
||||
saveHandler = MMoutOfMemory;
|
||||
MMoutOfMemory = Cudd_OutOfMem;
|
||||
cache->item = item =
|
||||
(DdLocalCacheItem *) ABC_ALLOC(char, slots * cache->itemsize);
|
||||
(DdLocalCacheItem *) ABC_ALLOC(char, slots * cache->itemsize);
|
||||
MMoutOfMemory = saveHandler;
|
||||
/* If we fail to allocate the new table we just give up. */
|
||||
if (item == NULL) {
|
||||
#ifdef DD_VERBOSE
|
||||
(void) fprintf(cache->manager->err,"Resizing failed. Giving up.\n");
|
||||
(void) fprintf(cache->manager->err,"Resizing failed. Giving up.\n");
|
||||
#endif
|
||||
cache->slots = oldslots;
|
||||
cache->item = olditem;
|
||||
/* Do not try to resize again. */
|
||||
cache->maxslots = oldslots - 1;
|
||||
return;
|
||||
cache->slots = oldslots;
|
||||
cache->item = olditem;
|
||||
/* Do not try to resize again. */
|
||||
cache->maxslots = oldslots - 1;
|
||||
return;
|
||||
}
|
||||
shift = --(cache->shift);
|
||||
cache->manager->memused += (slots - oldslots) * cache->itemsize;
|
||||
|
|
@ -1114,14 +1144,14 @@ cuddLocalCacheResize(
|
|||
|
||||
/* Copy from old cache to new one. */
|
||||
for (i = 0; (unsigned) i < oldslots; i++) {
|
||||
old = (DdLocalCacheItem *) ((char *) olditem + i * cache->itemsize);
|
||||
if (old->value != NULL) {
|
||||
posn = ddLCHash(old->key,cache->keysize,slots);
|
||||
entry = (DdLocalCacheItem *) ((char *) item +
|
||||
posn * cache->itemsize);
|
||||
memcpy(entry->key,old->key,cache->keysize*sizeof(DdNode *));
|
||||
entry->value = old->value;
|
||||
}
|
||||
old = (DdLocalCacheItem *) ((char *) olditem + i * cache->itemsize);
|
||||
if (old->value != NULL) {
|
||||
posn = ddLCHash(old->key,cache->keysize,shift);
|
||||
entry = (DdLocalCacheItem *) ((char *) item +
|
||||
posn * cache->itemsize);
|
||||
memcpy(entry->key,old->key,cache->keysize*sizeof(DdNode *));
|
||||
entry->value = old->value;
|
||||
}
|
||||
}
|
||||
|
||||
ABC_FREE(olditem);
|
||||
|
|
@ -1154,11 +1184,11 @@ ddLCHash(
|
|||
unsigned int keysize,
|
||||
int shift)
|
||||
{
|
||||
unsigned int val = (unsigned int) (ptrint) key[0];
|
||||
unsigned int val = (unsigned int) (ptrint) key[0] * DD_P2;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 1; i < keysize; i++) {
|
||||
val = val * DD_P1 + (int) (ptrint) key[i];
|
||||
val = val * DD_P1 + (int) (ptrint) key[i];
|
||||
}
|
||||
|
||||
return(val >> shift);
|
||||
|
|
@ -1219,14 +1249,14 @@ cuddLocalCacheRemoveFromList(
|
|||
nextCache = manager->localCaches;
|
||||
|
||||
while (nextCache != NULL) {
|
||||
if (nextCache == cache) {
|
||||
*prevCache = nextCache->next;
|
||||
return;
|
||||
if (nextCache == cache) {
|
||||
*prevCache = nextCache->next;
|
||||
return;
|
||||
}
|
||||
prevCache = &(nextCache->next);
|
||||
nextCache = nextCache->next;
|
||||
}
|
||||
prevCache = &(nextCache->next);
|
||||
nextCache = nextCache->next;
|
||||
}
|
||||
return; /* should never get here */
|
||||
return; /* should never get here */
|
||||
|
||||
} /* end of cuddLocalCacheRemoveFromList */
|
||||
|
||||
|
|
@ -1264,8 +1294,8 @@ cuddHashTableResize(
|
|||
#endif
|
||||
int shift;
|
||||
int oldNumBuckets = hash->numBuckets;
|
||||
// extern void (*MMoutOfMemory)(long);
|
||||
void (*saveHandler)(long);
|
||||
extern DD_OOMFP MMoutOfMemory;
|
||||
DD_OOMFP saveHandler;
|
||||
|
||||
/* Compute the new size of the table. */
|
||||
numBuckets = oldNumBuckets << 1;
|
||||
|
|
@ -1278,8 +1308,8 @@ cuddHashTableResize(
|
|||
buckets = ABC_ALLOC(DdHashItem *, numBuckets);
|
||||
MMoutOfMemory = saveHandler;
|
||||
if (buckets == NULL) {
|
||||
hash->maxsize <<= 1;
|
||||
return(1);
|
||||
hash->maxsize <<= 1;
|
||||
return(1);
|
||||
}
|
||||
|
||||
hash->bucket = buckets;
|
||||
|
|
@ -1291,53 +1321,53 @@ cuddHashTableResize(
|
|||
#pragma pointer_size restore
|
||||
#endif
|
||||
if (hash->keysize == 1) {
|
||||
for (j = 0; j < oldNumBuckets; j++) {
|
||||
item = oldBuckets[j];
|
||||
while (item != NULL) {
|
||||
next = item->next;
|
||||
key = item->key;
|
||||
posn = ddLCHash2(key[0], key[0], shift);
|
||||
item->next = buckets[posn];
|
||||
buckets[posn] = item;
|
||||
item = next;
|
||||
for (j = 0; j < oldNumBuckets; j++) {
|
||||
item = oldBuckets[j];
|
||||
while (item != NULL) {
|
||||
next = item->next;
|
||||
key = item->key;
|
||||
posn = ddLCHash2(key[0], key[0], shift);
|
||||
item->next = buckets[posn];
|
||||
buckets[posn] = item;
|
||||
item = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (hash->keysize == 2) {
|
||||
for (j = 0; j < oldNumBuckets; j++) {
|
||||
item = oldBuckets[j];
|
||||
while (item != NULL) {
|
||||
next = item->next;
|
||||
key = item->key;
|
||||
posn = ddLCHash2(key[0], key[1], shift);
|
||||
item->next = buckets[posn];
|
||||
buckets[posn] = item;
|
||||
item = next;
|
||||
for (j = 0; j < oldNumBuckets; j++) {
|
||||
item = oldBuckets[j];
|
||||
while (item != NULL) {
|
||||
next = item->next;
|
||||
key = item->key;
|
||||
posn = ddLCHash2(key[0], key[1], shift);
|
||||
item->next = buckets[posn];
|
||||
buckets[posn] = item;
|
||||
item = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (hash->keysize == 3) {
|
||||
for (j = 0; j < oldNumBuckets; j++) {
|
||||
item = oldBuckets[j];
|
||||
while (item != NULL) {
|
||||
next = item->next;
|
||||
key = item->key;
|
||||
posn = ddLCHash3(key[0], key[1], key[2], shift);
|
||||
item->next = buckets[posn];
|
||||
buckets[posn] = item;
|
||||
item = next;
|
||||
for (j = 0; j < oldNumBuckets; j++) {
|
||||
item = oldBuckets[j];
|
||||
while (item != NULL) {
|
||||
next = item->next;
|
||||
key = item->key;
|
||||
posn = ddLCHash3(key[0], key[1], key[2], shift);
|
||||
item->next = buckets[posn];
|
||||
buckets[posn] = item;
|
||||
item = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < oldNumBuckets; j++) {
|
||||
item = oldBuckets[j];
|
||||
while (item != NULL) {
|
||||
next = item->next;
|
||||
posn = ddLCHash(item->key, hash->keysize, shift);
|
||||
item->next = buckets[posn];
|
||||
buckets[posn] = item;
|
||||
item = next;
|
||||
for (j = 0; j < oldNumBuckets; j++) {
|
||||
item = oldBuckets[j];
|
||||
while (item != NULL) {
|
||||
next = item->next;
|
||||
posn = ddLCHash(item->key, hash->keysize, shift);
|
||||
item->next = buckets[posn];
|
||||
buckets[posn] = item;
|
||||
item = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ABC_FREE(oldBuckets);
|
||||
return(1);
|
||||
|
||||
|
|
@ -1365,8 +1395,8 @@ cuddHashTableAlloc(
|
|||
{
|
||||
int i;
|
||||
unsigned int itemsize = hash->itemsize;
|
||||
// extern void (*MMoutOfMemory)(long);
|
||||
void (*saveHandler)(long);
|
||||
extern DD_OOMFP MMoutOfMemory;
|
||||
DD_OOMFP saveHandler;
|
||||
#ifdef __osf__
|
||||
#pragma pointer_size save
|
||||
#pragma pointer_size short
|
||||
|
|
@ -1374,54 +1404,54 @@ cuddHashTableAlloc(
|
|||
DdHashItem **mem, *thisOne, *next, *item;
|
||||
|
||||
if (hash->nextFree == NULL) {
|
||||
saveHandler = MMoutOfMemory;
|
||||
MMoutOfMemory = Cudd_OutOfMem;
|
||||
mem = (DdHashItem **) ABC_ALLOC(char,(DD_MEM_CHUNK+1) * itemsize);
|
||||
MMoutOfMemory = saveHandler;
|
||||
saveHandler = MMoutOfMemory;
|
||||
MMoutOfMemory = Cudd_OutOfMem;
|
||||
mem = (DdHashItem **) ABC_ALLOC(char,(DD_MEM_CHUNK+1) * itemsize);
|
||||
MMoutOfMemory = saveHandler;
|
||||
#ifdef __osf__
|
||||
#pragma pointer_size restore
|
||||
#endif
|
||||
if (mem == NULL) {
|
||||
if (hash->manager->stash != NULL) {
|
||||
ABC_FREE(hash->manager->stash);
|
||||
hash->manager->stash = NULL;
|
||||
/* Inhibit resizing of tables. */
|
||||
hash->manager->maxCacheHard = hash->manager->cacheSlots - 1;
|
||||
hash->manager->cacheSlack = -(int)(hash->manager->cacheSlots + 1);
|
||||
for (i = 0; i < hash->manager->size; i++) {
|
||||
hash->manager->subtables[i].maxKeys <<= 2;
|
||||
}
|
||||
hash->manager->gcFrac = 0.2;
|
||||
hash->manager->minDead =
|
||||
(unsigned) (0.2 * (double) hash->manager->slots);
|
||||
if (mem == NULL) {
|
||||
if (hash->manager->stash != NULL) {
|
||||
ABC_FREE(hash->manager->stash);
|
||||
hash->manager->stash = NULL;
|
||||
/* Inhibit resizing of tables. */
|
||||
hash->manager->maxCacheHard = hash->manager->cacheSlots - 1;
|
||||
hash->manager->cacheSlack = - (int) (hash->manager->cacheSlots + 1);
|
||||
for (i = 0; i < hash->manager->size; i++) {
|
||||
hash->manager->subtables[i].maxKeys <<= 2;
|
||||
}
|
||||
hash->manager->gcFrac = 0.2;
|
||||
hash->manager->minDead =
|
||||
(unsigned) (0.2 * (double) hash->manager->slots);
|
||||
#ifdef __osf__
|
||||
#pragma pointer_size save
|
||||
#pragma pointer_size short
|
||||
#endif
|
||||
mem = (DdHashItem **) ABC_ALLOC(char,(DD_MEM_CHUNK+1) * itemsize);
|
||||
mem = (DdHashItem **) ABC_ALLOC(char,(DD_MEM_CHUNK+1) * itemsize);
|
||||
#ifdef __osf__
|
||||
#pragma pointer_size restore
|
||||
#endif
|
||||
}
|
||||
if (mem == NULL) {
|
||||
(*MMoutOfMemory)((long)((DD_MEM_CHUNK + 1) * itemsize));
|
||||
hash->manager->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
if (mem == NULL) {
|
||||
(*MMoutOfMemory)((DD_MEM_CHUNK + 1) * itemsize);
|
||||
hash->manager->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
|
||||
mem[0] = (DdHashItem *) hash->memoryList;
|
||||
hash->memoryList = mem;
|
||||
|
||||
thisOne = (DdHashItem *) ((char *) mem + itemsize);
|
||||
hash->nextFree = thisOne;
|
||||
for (i = 1; i < DD_MEM_CHUNK; i++) {
|
||||
next = (DdHashItem *) ((char *) thisOne + itemsize);
|
||||
thisOne->next = next;
|
||||
thisOne = next;
|
||||
}
|
||||
}
|
||||
|
||||
mem[0] = (DdHashItem *) hash->memoryList;
|
||||
hash->memoryList = mem;
|
||||
|
||||
thisOne = (DdHashItem *) ((char *) mem + itemsize);
|
||||
hash->nextFree = thisOne;
|
||||
for (i = 1; i < DD_MEM_CHUNK; i++) {
|
||||
next = (DdHashItem *) ((char *) thisOne + itemsize);
|
||||
thisOne->next = next;
|
||||
thisOne = next;
|
||||
}
|
||||
|
||||
thisOne->next = NULL;
|
||||
thisOne->next = NULL;
|
||||
|
||||
}
|
||||
item = hash->nextFree;
|
||||
|
|
@ -1429,5 +1459,7 @@ cuddHashTableAlloc(
|
|||
return(item);
|
||||
|
||||
} /* end of cuddHashTableAlloc */
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -25,28 +25,55 @@
|
|||
|
||||
Internal procedures provided by this module:
|
||||
<ul>
|
||||
<li> cuddLevelQueueInit()
|
||||
<li> cuddLevelQueueQuit()
|
||||
<li> cuddLevelQueueEnqueue()
|
||||
<li> cuddLevelQueueDequeue()
|
||||
</ul>
|
||||
<li> cuddLevelQueueInit()
|
||||
<li> cuddLevelQueueQuit()
|
||||
<li> cuddLevelQueueEnqueue()
|
||||
<li> cuddLevelQueueDequeue()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> hashLookup()
|
||||
<li> hashInsert()
|
||||
<li> hashDelete()
|
||||
<li> hashResize()
|
||||
</ul>
|
||||
]
|
||||
<ul>
|
||||
<li> hashLookup()
|
||||
<li> hashInsert()
|
||||
<li> hashDelete()
|
||||
<li> hashResize()
|
||||
</ul>
|
||||
]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no
|
||||
warranty about the suitability of this software for any
|
||||
purpose. It is presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -56,6 +83,7 @@
|
|||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -74,7 +102,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.13 2009/03/08 02:49:02 fabio Exp $";
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -95,7 +123,7 @@ static char rcsid[] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.1.1.1 2003/02/24 22:23:52
|
|||
******************************************************************************/
|
||||
#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
|
||||
#define lqHash(key,shift) \
|
||||
(((unsigned)(unsigned long)(key) * DD_P1) >> (shift))
|
||||
(((unsigned)(ptruint)(key) * DD_P1) >> (shift))
|
||||
#else
|
||||
#define lqHash(key,shift) \
|
||||
(((unsigned)(key) * DD_P1) >> (shift))
|
||||
|
|
@ -108,10 +136,10 @@ static char rcsid[] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.1.1.1 2003/02/24 22:23:52
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static DdQueueItem * hashLookup ARGS((DdLevelQueue *queue, void *key));
|
||||
static int hashInsert ARGS((DdLevelQueue *queue, DdQueueItem *item));
|
||||
static void hashDelete ARGS((DdLevelQueue *queue, DdQueueItem *item));
|
||||
static int hashResize ARGS((DdLevelQueue *queue));
|
||||
static DdQueueItem * hashLookup (DdLevelQueue *queue, void *key);
|
||||
static int hashInsert (DdLevelQueue *queue, DdQueueItem *item);
|
||||
static void hashDelete (DdLevelQueue *queue, DdQueueItem *item);
|
||||
static int hashResize (DdLevelQueue *queue);
|
||||
|
||||
/**AutomaticEnd***************************************************************/
|
||||
|
||||
|
|
@ -148,7 +176,7 @@ cuddLevelQueueInit(
|
|||
|
||||
queue = ABC_ALLOC(DdLevelQueue,1);
|
||||
if (queue == NULL)
|
||||
return(NULL);
|
||||
return(NULL);
|
||||
#ifdef __osf__
|
||||
#pragma pointer_size save
|
||||
#pragma pointer_size short
|
||||
|
|
@ -159,8 +187,8 @@ cuddLevelQueueInit(
|
|||
#pragma pointer_size restore
|
||||
#endif
|
||||
if (queue->last == NULL) {
|
||||
ABC_FREE(queue);
|
||||
return(NULL);
|
||||
ABC_FREE(queue);
|
||||
return(NULL);
|
||||
}
|
||||
/* Use a hash table to test for uniqueness. */
|
||||
if (numBuckets < 2) numBuckets = 2;
|
||||
|
|
@ -176,9 +204,9 @@ cuddLevelQueueInit(
|
|||
#pragma pointer_size restore
|
||||
#endif
|
||||
if (queue->buckets == NULL) {
|
||||
ABC_FREE(queue->last);
|
||||
ABC_FREE(queue);
|
||||
return(NULL);
|
||||
ABC_FREE(queue->last);
|
||||
ABC_FREE(queue);
|
||||
return(NULL);
|
||||
}
|
||||
#ifdef __osf__
|
||||
#pragma pointer_size save
|
||||
|
|
@ -219,14 +247,14 @@ cuddLevelQueueQuit(
|
|||
DdQueueItem *item;
|
||||
|
||||
while (queue->freelist != NULL) {
|
||||
item = queue->freelist;
|
||||
queue->freelist = item->next;
|
||||
ABC_FREE(item);
|
||||
item = queue->freelist;
|
||||
queue->freelist = item->next;
|
||||
ABC_FREE(item);
|
||||
}
|
||||
while (queue->first != NULL) {
|
||||
item = (DdQueueItem *) queue->first;
|
||||
queue->first = item->next;
|
||||
ABC_FREE(item);
|
||||
item = (DdQueueItem *) queue->first;
|
||||
queue->first = item->next;
|
||||
ABC_FREE(item);
|
||||
}
|
||||
ABC_FREE(queue->buckets);
|
||||
ABC_FREE(queue->last);
|
||||
|
|
@ -268,12 +296,12 @@ cuddLevelQueueEnqueue(
|
|||
|
||||
/* Get a free item from either the free list or the memory manager. */
|
||||
if (queue->freelist == NULL) {
|
||||
item = (DdQueueItem *) ABC_ALLOC(char, queue->itemsize);
|
||||
if (item == NULL)
|
||||
return(NULL);
|
||||
item = (DdQueueItem *) ABC_ALLOC(char, queue->itemsize);
|
||||
if (item == NULL)
|
||||
return(NULL);
|
||||
} else {
|
||||
item = queue->freelist;
|
||||
queue->freelist = item->next;
|
||||
item = queue->freelist;
|
||||
queue->freelist = item->next;
|
||||
}
|
||||
/* Initialize. */
|
||||
memset(item, 0, queue->itemsize);
|
||||
|
|
@ -282,29 +310,29 @@ cuddLevelQueueEnqueue(
|
|||
queue->size++;
|
||||
|
||||
if (queue->last[level]) {
|
||||
/* There are already items for this level in the queue. */
|
||||
item->next = queue->last[level]->next;
|
||||
queue->last[level]->next = item;
|
||||
/* There are already items for this level in the queue. */
|
||||
item->next = queue->last[level]->next;
|
||||
queue->last[level]->next = item;
|
||||
} else {
|
||||
/* There are no items at the current level. Look for the first
|
||||
** non-empty level preceeding this one. */
|
||||
plevel = level;
|
||||
while (plevel != 0 && queue->last[plevel] == NULL)
|
||||
plevel--;
|
||||
if (queue->last[plevel] == NULL) {
|
||||
/* No element precedes this one in the queue. */
|
||||
item->next = (DdQueueItem *) queue->first;
|
||||
queue->first = item;
|
||||
} else {
|
||||
item->next = queue->last[plevel]->next;
|
||||
queue->last[plevel]->next = item;
|
||||
}
|
||||
/* There are no items at the current level. Look for the first
|
||||
** non-empty level preceeding this one. */
|
||||
plevel = level;
|
||||
while (plevel != 0 && queue->last[plevel] == NULL)
|
||||
plevel--;
|
||||
if (queue->last[plevel] == NULL) {
|
||||
/* No element precedes this one in the queue. */
|
||||
item->next = (DdQueueItem *) queue->first;
|
||||
queue->first = item;
|
||||
} else {
|
||||
item->next = queue->last[plevel]->next;
|
||||
queue->last[plevel]->next = item;
|
||||
}
|
||||
}
|
||||
queue->last[level] = item;
|
||||
|
||||
/* Insert entry for the key in the hash table. */
|
||||
if (hashInsert(queue,item) == 0) {
|
||||
return(NULL);
|
||||
return(NULL);
|
||||
}
|
||||
return(item);
|
||||
|
||||
|
|
@ -335,7 +363,7 @@ cuddLevelQueueDequeue(
|
|||
/* Since we delete from the front, if this is the last item for
|
||||
** its level, there are no other items for the same level. */
|
||||
if (queue->last[level] == item)
|
||||
queue->last[level] = NULL;
|
||||
queue->last[level] = NULL;
|
||||
|
||||
queue->first = item->next;
|
||||
/* Put item on the free list. */
|
||||
|
|
@ -378,10 +406,10 @@ hashLookup(
|
|||
item = queue->buckets[posn];
|
||||
|
||||
while (item != NULL) {
|
||||
if (item->key == key) {
|
||||
return(item);
|
||||
}
|
||||
item = item->cnext;
|
||||
if (item->key == key) {
|
||||
return(item);
|
||||
}
|
||||
item = item->cnext;
|
||||
}
|
||||
return(NULL);
|
||||
|
||||
|
|
@ -410,8 +438,8 @@ hashInsert(
|
|||
int posn;
|
||||
|
||||
if (queue->size > queue->maxsize) {
|
||||
result = hashResize(queue);
|
||||
if (result == 0) return(0);
|
||||
result = hashResize(queue);
|
||||
if (result == 0) return(0);
|
||||
}
|
||||
|
||||
posn = lqHash(item->key,queue->shift);
|
||||
|
|
@ -448,16 +476,16 @@ hashDelete(
|
|||
|
||||
if (prevItem == NULL) return;
|
||||
if (prevItem == item) {
|
||||
queue->buckets[posn] = prevItem->cnext;
|
||||
return;
|
||||
queue->buckets[posn] = prevItem->cnext;
|
||||
return;
|
||||
}
|
||||
|
||||
while (prevItem->cnext != NULL) {
|
||||
if (prevItem->cnext == item) {
|
||||
prevItem->cnext = item->cnext;
|
||||
return;
|
||||
}
|
||||
prevItem = prevItem->cnext;
|
||||
if (prevItem->cnext == item) {
|
||||
prevItem->cnext = item->cnext;
|
||||
return;
|
||||
}
|
||||
prevItem = prevItem->cnext;
|
||||
}
|
||||
return;
|
||||
|
||||
|
|
@ -496,8 +524,8 @@ hashResize(
|
|||
#endif
|
||||
int shift;
|
||||
int oldNumBuckets = queue->numBuckets;
|
||||
// extern void (*MMoutOfMemory)(long);
|
||||
void (*saveHandler)(long);
|
||||
extern DD_OOMFP MMoutOfMemory;
|
||||
DD_OOMFP saveHandler;
|
||||
|
||||
/* Compute the new size of the subtable. */
|
||||
numBuckets = oldNumBuckets << 1;
|
||||
|
|
@ -508,9 +536,10 @@ hashResize(
|
|||
#pragma pointer_size short
|
||||
#endif
|
||||
buckets = queue->buckets = ABC_ALLOC(DdQueueItem *, numBuckets);
|
||||
MMoutOfMemory = saveHandler;
|
||||
if (buckets == NULL) {
|
||||
queue->maxsize <<= 1;
|
||||
return(1);
|
||||
queue->maxsize <<= 1;
|
||||
return(1);
|
||||
}
|
||||
|
||||
queue->numBuckets = numBuckets;
|
||||
|
|
@ -521,18 +550,20 @@ hashResize(
|
|||
#pragma pointer_size restore
|
||||
#endif
|
||||
for (j = 0; j < oldNumBuckets; j++) {
|
||||
item = oldBuckets[j];
|
||||
while (item != NULL) {
|
||||
next = item->cnext;
|
||||
posn = lqHash(item->key, shift);
|
||||
item->cnext = buckets[posn];
|
||||
buckets[posn] = item;
|
||||
item = next;
|
||||
}
|
||||
item = oldBuckets[j];
|
||||
while (item != NULL) {
|
||||
next = item->cnext;
|
||||
posn = lqHash(item->key, shift);
|
||||
item->cnext = buckets[posn];
|
||||
buckets[posn] = item;
|
||||
item = next;
|
||||
}
|
||||
}
|
||||
ABC_FREE(oldBuckets);
|
||||
return(1);
|
||||
|
||||
} /* end of hashResize */
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -8,20 +8,47 @@
|
|||
BDDs.]
|
||||
|
||||
Description [External procedures included in this file:
|
||||
<ul>
|
||||
<li> Cudd_bddLiteralSetIntersection()
|
||||
</ul>
|
||||
Internal procedures included in this file:
|
||||
<ul>
|
||||
<li> cuddBddLiteralSetIntersectionRecur()
|
||||
</ul>]
|
||||
<ul>
|
||||
<li> Cudd_bddLiteralSetIntersection()
|
||||
</ul>
|
||||
Internal procedures included in this file:
|
||||
<ul>
|
||||
<li> cuddBddLiteralSetIntersectionRecur()
|
||||
</ul>]
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -32,6 +59,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -49,7 +77,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddLiteral.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddLiteral.c,v 1.8 2004/08/13 18:04:50 fabio Exp $";
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -95,8 +123,8 @@ Cudd_bddLiteralSetIntersection(
|
|||
DdNode *res;
|
||||
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = cuddBddLiteralSetIntersectionRecur(dd,f,g);
|
||||
dd->reordered = 0;
|
||||
res = cuddBddLiteralSetIntersectionRecur(dd,f,g);
|
||||
} while (dd->reordered == 1);
|
||||
return(res);
|
||||
|
||||
|
|
@ -155,27 +183,27 @@ cuddBddLiteralSetIntersectionRecur(
|
|||
** loop will stop when the constant node is reached in both cubes.
|
||||
*/
|
||||
while (topf != topg) {
|
||||
if (topf < topg) { /* move down on f */
|
||||
comple = f != F;
|
||||
f = cuddT(F);
|
||||
if (comple) f = Cudd_Not(f);
|
||||
if (f == zero) {
|
||||
f = cuddE(F);
|
||||
if (comple) f = Cudd_Not(f);
|
||||
if (topf < topg) { /* move down on f */
|
||||
comple = f != F;
|
||||
f = cuddT(F);
|
||||
if (comple) f = Cudd_Not(f);
|
||||
if (f == zero) {
|
||||
f = cuddE(F);
|
||||
if (comple) f = Cudd_Not(f);
|
||||
}
|
||||
F = Cudd_Regular(f);
|
||||
topf = cuddI(dd,F->index);
|
||||
} else if (topg < topf) {
|
||||
comple = g != G;
|
||||
g = cuddT(G);
|
||||
if (comple) g = Cudd_Not(g);
|
||||
if (g == zero) {
|
||||
g = cuddE(G);
|
||||
if (comple) g = Cudd_Not(g);
|
||||
}
|
||||
G = Cudd_Regular(g);
|
||||
topg = cuddI(dd,G->index);
|
||||
}
|
||||
F = Cudd_Regular(f);
|
||||
topf = cuddI(dd,F->index);
|
||||
} else if (topg < topf) {
|
||||
comple = g != G;
|
||||
g = cuddT(G);
|
||||
if (comple) g = Cudd_Not(g);
|
||||
if (g == zero) {
|
||||
g = cuddE(G);
|
||||
if (comple) g = Cudd_Not(g);
|
||||
}
|
||||
G = Cudd_Regular(g);
|
||||
topg = cuddI(dd,G->index);
|
||||
}
|
||||
}
|
||||
|
||||
/* At this point, f == one <=> g == 1. It suffices to test one of them. */
|
||||
|
|
@ -183,7 +211,7 @@ cuddBddLiteralSetIntersectionRecur(
|
|||
|
||||
res = cuddCacheLookup2(dd,Cudd_bddLiteralSetIntersection,f,g);
|
||||
if (res != NULL) {
|
||||
return(res);
|
||||
return(res);
|
||||
}
|
||||
|
||||
/* Here f and g are both non constant and have the same top variable. */
|
||||
|
|
@ -192,39 +220,39 @@ cuddBddLiteralSetIntersectionRecur(
|
|||
phasef = 1;
|
||||
if (comple) fc = Cudd_Not(fc);
|
||||
if (fc == zero) {
|
||||
fc = cuddE(F);
|
||||
phasef = 0;
|
||||
if (comple) fc = Cudd_Not(fc);
|
||||
fc = cuddE(F);
|
||||
phasef = 0;
|
||||
if (comple) fc = Cudd_Not(fc);
|
||||
}
|
||||
comple = g != G;
|
||||
gc = cuddT(G);
|
||||
phaseg = 1;
|
||||
if (comple) gc = Cudd_Not(gc);
|
||||
if (gc == zero) {
|
||||
gc = cuddE(G);
|
||||
phaseg = 0;
|
||||
if (comple) gc = Cudd_Not(gc);
|
||||
gc = cuddE(G);
|
||||
phaseg = 0;
|
||||
if (comple) gc = Cudd_Not(gc);
|
||||
}
|
||||
|
||||
tmp = cuddBddLiteralSetIntersectionRecur(dd,fc,gc);
|
||||
if (tmp == NULL) {
|
||||
return(NULL);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (phasef != phaseg) {
|
||||
res = tmp;
|
||||
res = tmp;
|
||||
} else {
|
||||
cuddRef(tmp);
|
||||
if (phasef == 0) {
|
||||
res = cuddBddAndRecur(dd,Cudd_Not(dd->vars[F->index]),tmp);
|
||||
} else {
|
||||
res = cuddBddAndRecur(dd,dd->vars[F->index],tmp);
|
||||
}
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDeref(dd,tmp);
|
||||
return(NULL);
|
||||
}
|
||||
cuddDeref(tmp); /* Just cuddDeref, because it is included in result */
|
||||
cuddRef(tmp);
|
||||
if (phasef == 0) {
|
||||
res = cuddBddAndRecur(dd,Cudd_Not(dd->vars[F->index]),tmp);
|
||||
} else {
|
||||
res = cuddBddAndRecur(dd,dd->vars[F->index],tmp);
|
||||
}
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDeref(dd,tmp);
|
||||
return(NULL);
|
||||
}
|
||||
cuddDeref(tmp); /* Just cuddDeref, because it is included in result */
|
||||
}
|
||||
|
||||
cuddCacheInsert2(dd,Cudd_bddLiteralSetIntersection,f,g,res);
|
||||
|
|
@ -238,5 +266,7 @@ cuddBddLiteralSetIntersectionRecur(
|
|||
/* Definition of static functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,25 +7,52 @@
|
|||
Synopsis [Matrix multiplication functions.]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_addMatrixMultiply()
|
||||
<li> Cudd_addTimesPlus()
|
||||
<li> Cudd_addTriangle()
|
||||
<li> Cudd_addOuterSum()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> addMMRecur()
|
||||
<li> addTriangleRecur()
|
||||
<li> cuddAddOuterSumRecur()
|
||||
</ul>]
|
||||
<ul>
|
||||
<li> Cudd_addMatrixMultiply()
|
||||
<li> Cudd_addTimesPlus()
|
||||
<li> Cudd_addTriangle()
|
||||
<li> Cudd_addOuterSum()
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> addMMRecur()
|
||||
<li> addTriangleRecur()
|
||||
<li> cuddAddOuterSumRecur()
|
||||
</ul>]
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -36,6 +63,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -56,7 +84,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddMatMult.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddMatMult.c,v 1.17 2004/08/13 18:04:50 fabio Exp $";
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -70,9 +98,9 @@ static char rcsid[] DD_UNUSED = "$Id: cuddMatMult.c,v 1.1.1.1 2003/02/24 22:23:5
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static DdNode * addMMRecur ARGS((DdManager *dd, DdNode *A, DdNode *B, int topP, int *vars));
|
||||
static DdNode * addTriangleRecur ARGS((DdManager *dd, DdNode *f, DdNode *g, int *vars, DdNode *cube));
|
||||
static DdNode * cuddAddOuterSumRecur ARGS((DdManager *dd, DdNode *M, DdNode *r, DdNode *c));
|
||||
static DdNode * addMMRecur (DdManager *dd, DdNode *A, DdNode *B, int topP, int *vars);
|
||||
static DdNode * addTriangleRecur (DdManager *dd, DdNode *f, DdNode *g, int *vars, DdNode *cube);
|
||||
static DdNode * cuddAddOuterSumRecur (DdManager *dd, DdNode *M, DdNode *r, DdNode *c);
|
||||
|
||||
/**AutomaticEnd***************************************************************/
|
||||
|
||||
|
|
@ -115,8 +143,8 @@ Cudd_addMatrixMultiply(
|
|||
nvars = dd->size;
|
||||
vars = ABC_ALLOC(int,nvars);
|
||||
if (vars == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
}
|
||||
for (i = 0; i < nvars; i++) {
|
||||
vars[i] = 0;
|
||||
|
|
@ -126,8 +154,8 @@ Cudd_addMatrixMultiply(
|
|||
}
|
||||
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = addMMRecur(dd,A,B,-1,vars);
|
||||
dd->reordered = 0;
|
||||
res = addMMRecur(dd,A,B,-1,vars);
|
||||
} while (dd->reordered == 1);
|
||||
ABC_FREE(vars);
|
||||
return(res);
|
||||
|
|
@ -168,20 +196,20 @@ Cudd_addTimesPlus(
|
|||
Cudd_Ref(tmp);
|
||||
Cudd_Ref(cube = DD_ONE(dd));
|
||||
for (i = nz-1; i >= 0; i--) {
|
||||
w = Cudd_addIte(dd,z[i],cube,DD_ZERO(dd));
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd,tmp);
|
||||
return(NULL);
|
||||
}
|
||||
Cudd_Ref(w);
|
||||
Cudd_RecursiveDeref(dd,cube);
|
||||
cube = w;
|
||||
w = Cudd_addIte(dd,z[i],cube,DD_ZERO(dd));
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd,tmp);
|
||||
return(NULL);
|
||||
}
|
||||
Cudd_Ref(w);
|
||||
Cudd_RecursiveDeref(dd,cube);
|
||||
cube = w;
|
||||
}
|
||||
res = Cudd_addExistAbstract(dd,tmp,cube);
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDeref(dd,tmp);
|
||||
Cudd_RecursiveDeref(dd,cube);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(dd,tmp);
|
||||
Cudd_RecursiveDeref(dd,cube);
|
||||
return(NULL);
|
||||
}
|
||||
Cudd_Ref(res);
|
||||
Cudd_RecursiveDeref(dd,cube);
|
||||
|
|
@ -225,21 +253,21 @@ Cudd_addTriangle(
|
|||
nvars = dd->size;
|
||||
vars = ABC_ALLOC(int, nvars);
|
||||
if (vars == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
}
|
||||
for (i = 0; i < nvars; i++) vars[i] = -1;
|
||||
for (i = 0; i < nz; i++) vars[z[i]->index] = i;
|
||||
cube = Cudd_addComputeCube(dd, z, NULL, nz);
|
||||
if (cube == NULL) {
|
||||
ABC_FREE(vars);
|
||||
return(NULL);
|
||||
ABC_FREE(vars);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(cube);
|
||||
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = addTriangleRecur(dd, f, g, vars, cube);
|
||||
dd->reordered = 0;
|
||||
res = addTriangleRecur(dd, f, g, vars, cube);
|
||||
} while (dd->reordered == 1);
|
||||
if (res != NULL) cuddRef(res);
|
||||
Cudd_RecursiveDeref(dd,cube);
|
||||
|
|
@ -274,8 +302,8 @@ Cudd_addOuterSum(
|
|||
DdNode *res;
|
||||
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = cuddAddOuterSumRecur(dd, M, r, c);
|
||||
dd->reordered = 0;
|
||||
res = cuddAddOuterSumRecur(dd, M, r, c);
|
||||
} while (dd->reordered == 1);
|
||||
return(res);
|
||||
|
||||
|
|
@ -310,21 +338,21 @@ addMMRecur(
|
|||
int * vars)
|
||||
{
|
||||
DdNode *zero,
|
||||
*At, /* positive cofactor of first operand */
|
||||
*Ae, /* negative cofactor of first operand */
|
||||
*Bt, /* positive cofactor of second operand */
|
||||
*Be, /* negative cofactor of second operand */
|
||||
*t, /* positive cofactor of result */
|
||||
*e, /* negative cofactor of result */
|
||||
*scaled, /* scaled result */
|
||||
*add_scale, /* ADD representing the scaling factor */
|
||||
*res;
|
||||
int i; /* loop index */
|
||||
double scale; /* scaling factor */
|
||||
int index; /* index of the top variable */
|
||||
*At, /* positive cofactor of first operand */
|
||||
*Ae, /* negative cofactor of first operand */
|
||||
*Bt, /* positive cofactor of second operand */
|
||||
*Be, /* negative cofactor of second operand */
|
||||
*t, /* positive cofactor of result */
|
||||
*e, /* negative cofactor of result */
|
||||
*scaled, /* scaled result */
|
||||
*add_scale, /* ADD representing the scaling factor */
|
||||
*res;
|
||||
int i; /* loop index */
|
||||
double scale; /* scaling factor */
|
||||
int index; /* index of the top variable */
|
||||
CUDD_VALUE_TYPE value;
|
||||
unsigned int topA, topB, topV;
|
||||
DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *);
|
||||
DD_CTFP cacheOp;
|
||||
|
||||
statLine(dd);
|
||||
zero = DD_ZERO(dd);
|
||||
|
|
@ -334,21 +362,21 @@ addMMRecur(
|
|||
}
|
||||
|
||||
if (cuddIsConstant(A) && cuddIsConstant(B)) {
|
||||
/* Compute the scaling factor. It is 2^k, where k is the
|
||||
** number of summation variables below the current variable.
|
||||
** Indeed, these constants represent blocks of 2^k identical
|
||||
** constant values in both A and B.
|
||||
*/
|
||||
value = cuddV(A) * cuddV(B);
|
||||
for (i = 0; i < dd->size; i++) {
|
||||
if (vars[i]) {
|
||||
if (dd->perm[i] > topP) {
|
||||
value *= (CUDD_VALUE_TYPE) 2;
|
||||
/* Compute the scaling factor. It is 2^k, where k is the
|
||||
** number of summation variables below the current variable.
|
||||
** Indeed, these constants represent blocks of 2^k identical
|
||||
** constant values in both A and B.
|
||||
*/
|
||||
value = cuddV(A) * cuddV(B);
|
||||
for (i = 0; i < dd->size; i++) {
|
||||
if (vars[i]) {
|
||||
if (dd->perm[i] > topP) {
|
||||
value *= (CUDD_VALUE_TYPE) 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res = cuddUniqueConst(dd, value);
|
||||
return(res);
|
||||
res = cuddUniqueConst(dd, value);
|
||||
return(res);
|
||||
}
|
||||
|
||||
/* Standardize to increase cache efficiency. Clearly, A*B != B*A
|
||||
|
|
@ -357,67 +385,67 @@ addMMRecur(
|
|||
** which one is passed as first argument.
|
||||
*/
|
||||
if (A > B) {
|
||||
DdNode *tmp = A;
|
||||
A = B;
|
||||
B = tmp;
|
||||
DdNode *tmp = A;
|
||||
A = B;
|
||||
B = tmp;
|
||||
}
|
||||
|
||||
topA = cuddI(dd,A->index); topB = cuddI(dd,B->index);
|
||||
topV = ddMin(topA,topB);
|
||||
|
||||
cacheOp = (DdNode *(*)(DdManager *, DdNode *, DdNode *)) addMMRecur;
|
||||
cacheOp = (DD_CTFP) addMMRecur;
|
||||
res = cuddCacheLookup2(dd,cacheOp,A,B);
|
||||
if (res != NULL) {
|
||||
/* If the result is 0, there is no need to normalize.
|
||||
** Otherwise we count the number of z variables between
|
||||
** the current depth and the top of the ADDs. These are
|
||||
** the missing variables that determine the size of the
|
||||
** constant blocks.
|
||||
*/
|
||||
if (res == zero) return(res);
|
||||
scale = 1.0;
|
||||
for (i = 0; i < dd->size; i++) {
|
||||
if (vars[i]) {
|
||||
if (dd->perm[i] > topP && (unsigned) dd->perm[i] < topV) {
|
||||
scale *= 2;
|
||||
/* If the result is 0, there is no need to normalize.
|
||||
** Otherwise we count the number of z variables between
|
||||
** the current depth and the top of the ADDs. These are
|
||||
** the missing variables that determine the size of the
|
||||
** constant blocks.
|
||||
*/
|
||||
if (res == zero) return(res);
|
||||
scale = 1.0;
|
||||
for (i = 0; i < dd->size; i++) {
|
||||
if (vars[i]) {
|
||||
if (dd->perm[i] > topP && (unsigned) dd->perm[i] < topV) {
|
||||
scale *= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (scale > 1.0) {
|
||||
cuddRef(res);
|
||||
add_scale = cuddUniqueConst(dd,(CUDD_VALUE_TYPE)scale);
|
||||
if (add_scale == NULL) {
|
||||
Cudd_RecursiveDeref(dd, res);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(add_scale);
|
||||
scaled = cuddAddApplyRecur(dd,Cudd_addTimes,res,add_scale);
|
||||
if (scaled == NULL) {
|
||||
Cudd_RecursiveDeref(dd, add_scale);
|
||||
Cudd_RecursiveDeref(dd, res);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(scaled);
|
||||
Cudd_RecursiveDeref(dd, add_scale);
|
||||
Cudd_RecursiveDeref(dd, res);
|
||||
res = scaled;
|
||||
cuddDeref(res);
|
||||
}
|
||||
}
|
||||
if (scale > 1.0) {
|
||||
cuddRef(res);
|
||||
add_scale = cuddUniqueConst(dd,(CUDD_VALUE_TYPE)scale);
|
||||
if (add_scale == NULL) {
|
||||
Cudd_RecursiveDeref(dd, res);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(add_scale);
|
||||
scaled = cuddAddApplyRecur(dd,Cudd_addTimes,res,add_scale);
|
||||
if (scaled == NULL) {
|
||||
Cudd_RecursiveDeref(dd, add_scale);
|
||||
Cudd_RecursiveDeref(dd, res);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(scaled);
|
||||
Cudd_RecursiveDeref(dd, add_scale);
|
||||
Cudd_RecursiveDeref(dd, res);
|
||||
res = scaled;
|
||||
cuddDeref(res);
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
/* compute the cofactors */
|
||||
if (topV == topA) {
|
||||
At = cuddT(A);
|
||||
Ae = cuddE(A);
|
||||
At = cuddT(A);
|
||||
Ae = cuddE(A);
|
||||
} else {
|
||||
At = Ae = A;
|
||||
At = Ae = A;
|
||||
}
|
||||
if (topV == topB) {
|
||||
Bt = cuddT(B);
|
||||
Be = cuddE(B);
|
||||
Bt = cuddT(B);
|
||||
Be = cuddE(B);
|
||||
} else {
|
||||
Bt = Be = B;
|
||||
Bt = Be = B;
|
||||
}
|
||||
|
||||
t = addMMRecur(dd, At, Bt, (int)topV, vars);
|
||||
|
|
@ -425,39 +453,39 @@ addMMRecur(
|
|||
cuddRef(t);
|
||||
e = addMMRecur(dd, Ae, Be, (int)topV, vars);
|
||||
if (e == NULL) {
|
||||
Cudd_RecursiveDeref(dd, t);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(dd, t);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(e);
|
||||
|
||||
index = dd->invperm[topV];
|
||||
if (vars[index] == 0) {
|
||||
/* We have split on either the rows of A or the columns
|
||||
** of B. We just need to connect the two subresults,
|
||||
** which correspond to two submatrices of the result.
|
||||
*/
|
||||
res = (t == e) ? t : cuddUniqueInter(dd,index,t,e);
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDeref(dd, t);
|
||||
Cudd_RecursiveDeref(dd, e);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
cuddDeref(t);
|
||||
cuddDeref(e);
|
||||
/* We have split on either the rows of A or the columns
|
||||
** of B. We just need to connect the two subresults,
|
||||
** which correspond to two submatrices of the result.
|
||||
*/
|
||||
res = (t == e) ? t : cuddUniqueInter(dd,index,t,e);
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDeref(dd, t);
|
||||
Cudd_RecursiveDeref(dd, e);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
cuddDeref(t);
|
||||
cuddDeref(e);
|
||||
} else {
|
||||
/* we have simultaneously split on the columns of A and
|
||||
** the rows of B. The two subresults must be added.
|
||||
*/
|
||||
res = cuddAddApplyRecur(dd,Cudd_addPlus,t,e);
|
||||
if (res == NULL) {
|
||||
/* we have simultaneously split on the columns of A and
|
||||
** the rows of B. The two subresults must be added.
|
||||
*/
|
||||
res = cuddAddApplyRecur(dd,Cudd_addPlus,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);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDeref(dd, t);
|
||||
Cudd_RecursiveDeref(dd, e);
|
||||
}
|
||||
|
||||
cuddCacheInsert2(dd,cacheOp,A,B,res);
|
||||
|
|
@ -469,33 +497,33 @@ addMMRecur(
|
|||
** scaling the result.
|
||||
*/
|
||||
if (res != zero) {
|
||||
scale = 1.0;
|
||||
for (i = 0; i < dd->size; i++) {
|
||||
if (vars[i]) {
|
||||
if (dd->perm[i] > topP && (unsigned) dd->perm[i] < topV) {
|
||||
scale *= 2;
|
||||
scale = 1.0;
|
||||
for (i = 0; i < dd->size; i++) {
|
||||
if (vars[i]) {
|
||||
if (dd->perm[i] > topP && (unsigned) dd->perm[i] < topV) {
|
||||
scale *= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (scale > 1.0) {
|
||||
add_scale = cuddUniqueConst(dd,(CUDD_VALUE_TYPE)scale);
|
||||
if (add_scale == NULL) {
|
||||
Cudd_RecursiveDeref(dd, res);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(add_scale);
|
||||
scaled = cuddAddApplyRecur(dd,Cudd_addTimes,res,add_scale);
|
||||
if (scaled == NULL) {
|
||||
Cudd_RecursiveDeref(dd, res);
|
||||
Cudd_RecursiveDeref(dd, add_scale);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(scaled);
|
||||
Cudd_RecursiveDeref(dd, add_scale);
|
||||
Cudd_RecursiveDeref(dd, res);
|
||||
res = scaled;
|
||||
}
|
||||
}
|
||||
if (scale > 1.0) {
|
||||
add_scale = cuddUniqueConst(dd,(CUDD_VALUE_TYPE)scale);
|
||||
if (add_scale == NULL) {
|
||||
Cudd_RecursiveDeref(dd, res);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(add_scale);
|
||||
scaled = cuddAddApplyRecur(dd,Cudd_addTimes,res,add_scale);
|
||||
if (scaled == NULL) {
|
||||
Cudd_RecursiveDeref(dd, res);
|
||||
Cudd_RecursiveDeref(dd, add_scale);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(scaled);
|
||||
Cudd_RecursiveDeref(dd, add_scale);
|
||||
Cudd_RecursiveDeref(dd, res);
|
||||
res = scaled;
|
||||
}
|
||||
}
|
||||
cuddDeref(res);
|
||||
return(res);
|
||||
|
||||
|
|
@ -526,25 +554,25 @@ addTriangleRecur(
|
|||
|
||||
statLine(dd);
|
||||
if (f == DD_PLUS_INFINITY(dd) || g == DD_PLUS_INFINITY(dd)) {
|
||||
return(DD_PLUS_INFINITY(dd));
|
||||
return(DD_PLUS_INFINITY(dd));
|
||||
}
|
||||
|
||||
if (cuddIsConstant(f) && cuddIsConstant(g)) {
|
||||
value = cuddV(f) + cuddV(g);
|
||||
res = cuddUniqueConst(dd, value);
|
||||
return(res);
|
||||
value = cuddV(f) + cuddV(g);
|
||||
res = cuddUniqueConst(dd, value);
|
||||
return(res);
|
||||
}
|
||||
if (f < g) {
|
||||
DdNode *tmp = f;
|
||||
f = g;
|
||||
g = tmp;
|
||||
DdNode *tmp = f;
|
||||
f = g;
|
||||
g = tmp;
|
||||
}
|
||||
|
||||
if (f->ref != 1 || g->ref != 1) {
|
||||
res = cuddCacheLookup(dd, DD_ADD_TRIANGLE_TAG, f, g, cube);
|
||||
if (res != NULL) {
|
||||
return(res);
|
||||
}
|
||||
res = cuddCacheLookup(dd, DD_ADD_TRIANGLE_TAG, f, g, cube);
|
||||
if (res != NULL) {
|
||||
return(res);
|
||||
}
|
||||
}
|
||||
|
||||
topf = cuddI(dd,f->index); topg = cuddI(dd,g->index);
|
||||
|
|
@ -558,36 +586,36 @@ addTriangleRecur(
|
|||
cuddRef(t);
|
||||
e = addTriangleRecur(dd, fvn, gvn, vars, cube);
|
||||
if (e == NULL) {
|
||||
Cudd_RecursiveDeref(dd, t);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(dd, t);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(e);
|
||||
|
||||
index = dd->invperm[top];
|
||||
if (vars[index] < 0) {
|
||||
res = (t == e) ? t : cuddUniqueInter(dd,index,t,e);
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDeref(dd, t);
|
||||
Cudd_RecursiveDeref(dd, e);
|
||||
return(NULL);
|
||||
}
|
||||
cuddDeref(t);
|
||||
cuddDeref(e);
|
||||
res = (t == e) ? t : cuddUniqueInter(dd,index,t,e);
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDeref(dd, t);
|
||||
Cudd_RecursiveDeref(dd, e);
|
||||
return(NULL);
|
||||
}
|
||||
cuddDeref(t);
|
||||
cuddDeref(e);
|
||||
} else {
|
||||
res = cuddAddApplyRecur(dd,Cudd_addMinimum,t,e);
|
||||
if (res == NULL) {
|
||||
res = cuddAddApplyRecur(dd,Cudd_addMinimum,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);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDeref(dd, t);
|
||||
Cudd_RecursiveDeref(dd, e);
|
||||
cuddDeref(res);
|
||||
cuddDeref(res);
|
||||
}
|
||||
|
||||
if (f->ref != 1 || g->ref != 1) {
|
||||
cuddCacheInsert(dd, DD_ADD_TRIANGLE_TAG, f, g, cube, res);
|
||||
cuddCacheInsert(dd, DD_ADD_TRIANGLE_TAG, f, g, cube, res);
|
||||
}
|
||||
|
||||
return(res);
|
||||
|
|
@ -623,23 +651,23 @@ cuddAddOuterSumRecur(
|
|||
if (r == DD_PLUS_INFINITY(dd) || c == DD_PLUS_INFINITY(dd)) return(M);
|
||||
|
||||
if (cuddIsConstant(c) && cuddIsConstant(r)) {
|
||||
R = cuddUniqueConst(dd,Cudd_V(c)+Cudd_V(r));
|
||||
cuddRef(R);
|
||||
if (cuddIsConstant(M)) {
|
||||
if (cuddV(R) <= cuddV(M)) {
|
||||
cuddDeref(R);
|
||||
return(R);
|
||||
R = cuddUniqueConst(dd,Cudd_V(c)+Cudd_V(r));
|
||||
cuddRef(R);
|
||||
if (cuddIsConstant(M)) {
|
||||
if (cuddV(R) <= cuddV(M)) {
|
||||
cuddDeref(R);
|
||||
return(R);
|
||||
} else {
|
||||
Cudd_RecursiveDeref(dd,R);
|
||||
return(M);
|
||||
}
|
||||
} else {
|
||||
Cudd_RecursiveDeref(dd,R);
|
||||
return(M);
|
||||
P = Cudd_addApply(dd,Cudd_addMinimum,R,M);
|
||||
cuddRef(P);
|
||||
Cudd_RecursiveDeref(dd,R);
|
||||
cuddDeref(P);
|
||||
return(P);
|
||||
}
|
||||
} else {
|
||||
P = Cudd_addApply(dd,Cudd_addMinimum,R,M);
|
||||
cuddRef(P);
|
||||
Cudd_RecursiveDeref(dd,R);
|
||||
cuddDeref(P);
|
||||
return(P);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the cache. */
|
||||
|
|
@ -661,16 +689,16 @@ cuddAddOuterSumRecur(
|
|||
cuddRef(Rt);
|
||||
Re = cuddAddOuterSumRecur(dd,Me,re,ce);
|
||||
if (Re == NULL) {
|
||||
Cudd_RecursiveDeref(dd, Rt);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(dd, Rt);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(Re);
|
||||
index = dd->invperm[v];
|
||||
R = (Rt == Re) ? Rt : cuddUniqueInter(dd,index,Rt,Re);
|
||||
if (R == NULL) {
|
||||
Cudd_RecursiveDeref(dd, Rt);
|
||||
Cudd_RecursiveDeref(dd, Re);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(dd, Rt);
|
||||
Cudd_RecursiveDeref(dd, Re);
|
||||
return(NULL);
|
||||
}
|
||||
cuddDeref(Rt);
|
||||
cuddDeref(Re);
|
||||
|
|
@ -681,5 +709,7 @@ cuddAddOuterSumRecur(
|
|||
return(R);
|
||||
|
||||
} /* end of cuddAddOuterSumRecur */
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -7,19 +7,46 @@
|
|||
Synopsis [Functions to read in a matrix]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_addRead()
|
||||
<li> Cudd_bddRead()
|
||||
</ul>]
|
||||
<ul>
|
||||
<li> Cudd_addRead()
|
||||
<li> Cudd_bddRead()
|
||||
</ul>]
|
||||
|
||||
SeeAlso [cudd_addHarwell.c]
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [ This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -30,6 +57,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -50,7 +78,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddRead.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddRead.c,v 1.6 2004/08/13 18:04:50 fabio Exp $";
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -145,85 +173,85 @@ Cudd_addRead(
|
|||
|
||||
err = fscanf(fp, "%d %d", &u, &v);
|
||||
if (err == EOF) {
|
||||
return(0);
|
||||
return(0);
|
||||
} else if (err != 2) {
|
||||
return(0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
*m = u;
|
||||
/* Compute the number of x variables. */
|
||||
lx = *x; lxn = *xn;
|
||||
u--; /* row and column numbers start from 0 */
|
||||
u--; /* row and column numbers start from 0 */
|
||||
for (lnx=0; u > 0; lnx++) {
|
||||
u >>= 1;
|
||||
u >>= 1;
|
||||
}
|
||||
/* Here we rely on the fact that ABC_REALLOC of a null pointer is
|
||||
** translates to an ABC_ALLOC.
|
||||
/* Here we rely on the fact that REALLOC of a null pointer is
|
||||
** translates to an ALLOC.
|
||||
*/
|
||||
if (lnx > *nx) {
|
||||
*x = lx = ABC_REALLOC(DdNode *, *x, lnx);
|
||||
if (lx == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
*xn = lxn = ABC_REALLOC(DdNode *, *xn, lnx);
|
||||
if (lxn == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
*x = lx = ABC_REALLOC(DdNode *, *x, lnx);
|
||||
if (lx == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
*xn = lxn = ABC_REALLOC(DdNode *, *xn, lnx);
|
||||
if (lxn == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
*n = v;
|
||||
/* Compute the number of y variables. */
|
||||
ly = *y; lyn = *yn_;
|
||||
v--; /* row and column numbers start from 0 */
|
||||
v--; /* row and column numbers start from 0 */
|
||||
for (lny=0; v > 0; lny++) {
|
||||
v >>= 1;
|
||||
v >>= 1;
|
||||
}
|
||||
/* Here we rely on the fact that ABC_REALLOC of a null pointer is
|
||||
** translates to an ABC_ALLOC.
|
||||
/* Here we rely on the fact that REALLOC of a null pointer is
|
||||
** translates to an ALLOC.
|
||||
*/
|
||||
if (lny > *ny) {
|
||||
*y = ly = ABC_REALLOC(DdNode *, *y, lny);
|
||||
if (ly == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
*yn_ = lyn = ABC_REALLOC(DdNode *, *yn_, lny);
|
||||
if (lyn == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
*y = ly = ABC_REALLOC(DdNode *, *y, lny);
|
||||
if (ly == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
*yn_ = lyn = ABC_REALLOC(DdNode *, *yn_, lny);
|
||||
if (lyn == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create all new variables. */
|
||||
for (i = *nx, nv = bx + (*nx) * sx; i < lnx; i++, nv += sx) {
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
lx[i] = cuddUniqueInter(dd, nv, one, zero);
|
||||
} while (dd->reordered == 1);
|
||||
if (lx[i] == NULL) return(0);
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
lx[i] = cuddUniqueInter(dd, nv, one, zero);
|
||||
} while (dd->reordered == 1);
|
||||
if (lx[i] == NULL) return(0);
|
||||
cuddRef(lx[i]);
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
lxn[i] = cuddUniqueInter(dd, nv, zero, one);
|
||||
} while (dd->reordered == 1);
|
||||
if (lxn[i] == NULL) return(0);
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
lxn[i] = cuddUniqueInter(dd, nv, zero, one);
|
||||
} while (dd->reordered == 1);
|
||||
if (lxn[i] == NULL) return(0);
|
||||
cuddRef(lxn[i]);
|
||||
}
|
||||
for (i = *ny, nv = by + (*ny) * sy; i < lny; i++, nv += sy) {
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
ly[i] = cuddUniqueInter(dd, nv, one, zero);
|
||||
} while (dd->reordered == 1);
|
||||
if (ly[i] == NULL) return(0);
|
||||
cuddRef(ly[i]);
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
lyn[i] = cuddUniqueInter(dd, nv, zero, one);
|
||||
} while (dd->reordered == 1);
|
||||
if (lyn[i] == NULL) return(0);
|
||||
cuddRef(lyn[i]);
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
ly[i] = cuddUniqueInter(dd, nv, one, zero);
|
||||
} while (dd->reordered == 1);
|
||||
if (ly[i] == NULL) return(0);
|
||||
cuddRef(ly[i]);
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
lyn[i] = cuddUniqueInter(dd, nv, zero, one);
|
||||
} while (dd->reordered == 1);
|
||||
if (lyn[i] == NULL) return(0);
|
||||
cuddRef(lyn[i]);
|
||||
}
|
||||
*nx = lnx;
|
||||
*ny = lny;
|
||||
|
|
@ -232,69 +260,69 @@ Cudd_addRead(
|
|||
cuddRef(*E);
|
||||
|
||||
while (! feof(fp)) {
|
||||
err = fscanf(fp, "%d %d %lf", &u, &v, &val);
|
||||
if (err == EOF) {
|
||||
break;
|
||||
} else if (err != 3) {
|
||||
return(0);
|
||||
} else if (u >= *m || v >= *n || u < 0 || v < 0) {
|
||||
return(0);
|
||||
}
|
||||
err = fscanf(fp, "%d %d %lf", &u, &v, &val);
|
||||
if (err == EOF) {
|
||||
break;
|
||||
} else if (err != 3) {
|
||||
return(0);
|
||||
} else if (u >= *m || v >= *n || u < 0 || v < 0) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
minterm1 = one; cuddRef(minterm1);
|
||||
minterm1 = one; cuddRef(minterm1);
|
||||
|
||||
/* Build minterm1 corresponding to this arc */
|
||||
for (i = lnx - 1; i>=0; i--) {
|
||||
if (u & 1) {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lx[i]);
|
||||
} else {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lxn[i]);
|
||||
/* Build minterm1 corresponding to this arc */
|
||||
for (i = lnx - 1; i>=0; i--) {
|
||||
if (u & 1) {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lx[i]);
|
||||
} else {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lxn[i]);
|
||||
}
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
minterm1 = w;
|
||||
u >>= 1;
|
||||
}
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
return(0);
|
||||
for (i = lny - 1; i>=0; i--) {
|
||||
if (v & 1) {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, minterm1, ly[i]);
|
||||
} else {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lyn[i]);
|
||||
}
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
minterm1 = w;
|
||||
v >>= 1;
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
minterm1 = w;
|
||||
u >>= 1;
|
||||
}
|
||||
for (i = lny - 1; i>=0; i--) {
|
||||
if (v & 1) {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, minterm1, ly[i]);
|
||||
} else {
|
||||
w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lyn[i]);
|
||||
/* Create new constant node if necessary.
|
||||
** This call will never cause reordering.
|
||||
*/
|
||||
neW = cuddUniqueConst(dd, val);
|
||||
if (neW == NULL) {
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
return(0);
|
||||
}
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
minterm1 = w;
|
||||
v >>= 1;
|
||||
}
|
||||
/* Create new constant node if necessary.
|
||||
** This call will never cause reordering.
|
||||
*/
|
||||
neW = cuddUniqueConst(dd, val);
|
||||
if (neW == NULL) {
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(neW);
|
||||
|
||||
w = Cudd_addIte(dd, minterm1, neW, *E);
|
||||
if (w == NULL) {
|
||||
w = Cudd_addIte(dd, minterm1, neW, *E);
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
Cudd_RecursiveDeref(dd, neW);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
Cudd_RecursiveDeref(dd, neW);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
Cudd_RecursiveDeref(dd, neW);
|
||||
Cudd_RecursiveDeref(dd, *E);
|
||||
*E = w;
|
||||
Cudd_RecursiveDeref(dd, *E);
|
||||
*E = w;
|
||||
}
|
||||
return(1);
|
||||
|
||||
|
|
@ -365,57 +393,57 @@ Cudd_bddRead(
|
|||
|
||||
err = fscanf(fp, "%d %d", &u, &v);
|
||||
if (err == EOF) {
|
||||
return(0);
|
||||
return(0);
|
||||
} else if (err != 2) {
|
||||
return(0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
*m = u;
|
||||
/* Compute the number of x variables. */
|
||||
lx = *x;
|
||||
u--; /* row and column numbers start from 0 */
|
||||
u--; /* row and column numbers start from 0 */
|
||||
for (lnx=0; u > 0; lnx++) {
|
||||
u >>= 1;
|
||||
u >>= 1;
|
||||
}
|
||||
if (lnx > *nx) {
|
||||
*x = lx = ABC_REALLOC(DdNode *, *x, lnx);
|
||||
if (lx == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
*x = lx = ABC_REALLOC(DdNode *, *x, lnx);
|
||||
if (lx == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
*n = v;
|
||||
/* Compute the number of y variables. */
|
||||
ly = *y;
|
||||
v--; /* row and column numbers start from 0 */
|
||||
v--; /* row and column numbers start from 0 */
|
||||
for (lny=0; v > 0; lny++) {
|
||||
v >>= 1;
|
||||
v >>= 1;
|
||||
}
|
||||
if (lny > *ny) {
|
||||
*y = ly = ABC_REALLOC(DdNode *, *y, lny);
|
||||
if (ly == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
*y = ly = ABC_REALLOC(DdNode *, *y, lny);
|
||||
if (ly == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create all new variables. */
|
||||
for (i = *nx, nv = bx + (*nx) * sx; i < lnx; i++, nv += sx) {
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
lx[i] = cuddUniqueInter(dd, nv, one, zero);
|
||||
} while (dd->reordered == 1);
|
||||
if (lx[i] == NULL) return(0);
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
lx[i] = cuddUniqueInter(dd, nv, one, zero);
|
||||
} while (dd->reordered == 1);
|
||||
if (lx[i] == NULL) return(0);
|
||||
cuddRef(lx[i]);
|
||||
}
|
||||
for (i = *ny, nv = by + (*ny) * sy; i < lny; i++, nv += sy) {
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
ly[i] = cuddUniqueInter(dd, nv, one, zero);
|
||||
} while (dd->reordered == 1);
|
||||
if (ly[i] == NULL) return(0);
|
||||
cuddRef(ly[i]);
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
ly[i] = cuddUniqueInter(dd, nv, one, zero);
|
||||
} while (dd->reordered == 1);
|
||||
if (ly[i] == NULL) return(0);
|
||||
cuddRef(ly[i]);
|
||||
}
|
||||
*nx = lnx;
|
||||
*ny = lny;
|
||||
|
|
@ -424,59 +452,59 @@ Cudd_bddRead(
|
|||
cuddRef(*E);
|
||||
|
||||
while (! feof(fp)) {
|
||||
err = fscanf(fp, "%d %d", &u, &v);
|
||||
if (err == EOF) {
|
||||
break;
|
||||
} else if (err != 2) {
|
||||
return(0);
|
||||
} else if (u >= *m || v >= *n || u < 0 || v < 0) {
|
||||
return(0);
|
||||
}
|
||||
err = fscanf(fp, "%d %d", &u, &v);
|
||||
if (err == EOF) {
|
||||
break;
|
||||
} else if (err != 2) {
|
||||
return(0);
|
||||
} else if (u >= *m || v >= *n || u < 0 || v < 0) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
minterm1 = one; cuddRef(minterm1);
|
||||
minterm1 = one; cuddRef(minterm1);
|
||||
|
||||
/* Build minterm1 corresponding to this arc. */
|
||||
for (i = lnx - 1; i>=0; i--) {
|
||||
if (u & 1) {
|
||||
w = Cudd_bddAnd(dd, minterm1, lx[i]);
|
||||
} else {
|
||||
w = Cudd_bddAnd(dd, minterm1, Cudd_Not(lx[i]));
|
||||
/* Build minterm1 corresponding to this arc. */
|
||||
for (i = lnx - 1; i>=0; i--) {
|
||||
if (u & 1) {
|
||||
w = Cudd_bddAnd(dd, minterm1, lx[i]);
|
||||
} else {
|
||||
w = Cudd_bddAnd(dd, minterm1, Cudd_Not(lx[i]));
|
||||
}
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd,minterm1);
|
||||
minterm1 = w;
|
||||
u >>= 1;
|
||||
}
|
||||
for (i = lny - 1; i>=0; i--) {
|
||||
if (v & 1) {
|
||||
w = Cudd_bddAnd(dd, minterm1, ly[i]);
|
||||
} else {
|
||||
w = Cudd_bddAnd(dd, minterm1, Cudd_Not(ly[i]));
|
||||
}
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
minterm1 = w;
|
||||
v >>= 1;
|
||||
}
|
||||
|
||||
w = Cudd_bddAnd(dd, Cudd_Not(minterm1), Cudd_Not(*E));
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
return(0);
|
||||
}
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd,minterm1);
|
||||
minterm1 = w;
|
||||
u >>= 1;
|
||||
}
|
||||
for (i = lny - 1; i>=0; i--) {
|
||||
if (v & 1) {
|
||||
w = Cudd_bddAnd(dd, minterm1, ly[i]);
|
||||
} else {
|
||||
w = Cudd_bddAnd(dd, minterm1, Cudd_Not(ly[i]));
|
||||
}
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
return(0);
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
return(0);
|
||||
}
|
||||
w = Cudd_Not(w);
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
minterm1 = w;
|
||||
v >>= 1;
|
||||
}
|
||||
|
||||
w = Cudd_bddAnd(dd, Cudd_Not(minterm1), Cudd_Not(*E));
|
||||
if (w == NULL) {
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
return(0);
|
||||
}
|
||||
w = Cudd_Not(w);
|
||||
cuddRef(w);
|
||||
Cudd_RecursiveDeref(dd, minterm1);
|
||||
Cudd_RecursiveDeref(dd, *E);
|
||||
*E = w;
|
||||
Cudd_RecursiveDeref(dd, *E);
|
||||
*E = w;
|
||||
}
|
||||
return(1);
|
||||
|
||||
|
|
@ -491,5 +519,7 @@ Cudd_bddRead(
|
|||
/* Definition of static functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,43 +7,71 @@
|
|||
Synopsis [Functions that manipulate the reference counts.]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_Ref()
|
||||
<li> Cudd_RecursiveDeref()
|
||||
<li> Cudd_IterDerefBdd()
|
||||
<li> Cudd_DelayedDerefBdd()
|
||||
<li> Cudd_RecursiveDerefZdd()
|
||||
<li> Cudd_Deref()
|
||||
<li> Cudd_CheckZeroRef()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddReclaim()
|
||||
<li> cuddReclaimZdd()
|
||||
<li> cuddClearDeathRow()
|
||||
<li> cuddShrinkDeathRow()
|
||||
<li> cuddIsInDeathRow()
|
||||
<li> cuddTimesInDeathRow()
|
||||
</ul>
|
||||
]
|
||||
<ul>
|
||||
<li> Cudd_Ref()
|
||||
<li> Cudd_RecursiveDeref()
|
||||
<li> Cudd_IterDerefBdd()
|
||||
<li> Cudd_DelayedDerefBdd()
|
||||
<li> Cudd_RecursiveDerefZdd()
|
||||
<li> Cudd_Deref()
|
||||
<li> Cudd_CheckZeroRef()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddReclaim()
|
||||
<li> cuddReclaimZdd()
|
||||
<li> cuddClearDeathRow()
|
||||
<li> cuddShrinkDeathRow()
|
||||
<li> cuddIsInDeathRow()
|
||||
<li> cuddTimesInDeathRow()
|
||||
</ul>
|
||||
]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [ This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -64,7 +92,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddRef.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddRef.c,v 1.28 2004/08/13 18:04:50 fabio Exp $";
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -134,35 +162,35 @@ Cudd_RecursiveDeref(
|
|||
|
||||
unsigned int live = table->keys - table->dead;
|
||||
if (live > table->peakLiveNodes) {
|
||||
table->peakLiveNodes = live;
|
||||
table->peakLiveNodes = live;
|
||||
}
|
||||
|
||||
N = Cudd_Regular(n);
|
||||
|
||||
do {
|
||||
#ifdef DD_DEBUG
|
||||
assert(N->ref != 0);
|
||||
assert(N->ref != 0);
|
||||
#endif
|
||||
|
||||
if (N->ref == 1) {
|
||||
N->ref = 0;
|
||||
table->dead++;
|
||||
if (N->ref == 1) {
|
||||
N->ref = 0;
|
||||
table->dead++;
|
||||
#ifdef DD_STATS
|
||||
table->nodesDropped++;
|
||||
table->nodesDropped++;
|
||||
#endif
|
||||
if (cuddIsConstant(N)) {
|
||||
table->constants.dead++;
|
||||
N = stack[--SP];
|
||||
if (cuddIsConstant(N)) {
|
||||
table->constants.dead++;
|
||||
N = stack[--SP];
|
||||
} else {
|
||||
ord = table->perm[N->index];
|
||||
stack[SP++] = Cudd_Regular(cuddE(N));
|
||||
table->subtables[ord].dead++;
|
||||
N = cuddT(N);
|
||||
}
|
||||
} else {
|
||||
ord = table->perm[N->index];
|
||||
stack[SP++] = Cudd_Regular(cuddE(N));
|
||||
table->subtables[ord].dead++;
|
||||
N = cuddT(N);
|
||||
cuddSatDec(N->ref);
|
||||
N = stack[--SP];
|
||||
}
|
||||
} else {
|
||||
cuddSatDec(N->ref);
|
||||
N = stack[--SP];
|
||||
}
|
||||
} while (SP != 0);
|
||||
|
||||
} /* end of Cudd_RecursiveDeref */
|
||||
|
|
@ -197,30 +225,30 @@ Cudd_IterDerefBdd(
|
|||
|
||||
unsigned int live = table->keys - table->dead;
|
||||
if (live > table->peakLiveNodes) {
|
||||
table->peakLiveNodes = live;
|
||||
table->peakLiveNodes = live;
|
||||
}
|
||||
|
||||
N = Cudd_Regular(n);
|
||||
|
||||
do {
|
||||
#ifdef DD_DEBUG
|
||||
assert(N->ref != 0);
|
||||
assert(N->ref != 0);
|
||||
#endif
|
||||
|
||||
if (N->ref == 1) {
|
||||
N->ref = 0;
|
||||
table->dead++;
|
||||
if (N->ref == 1) {
|
||||
N->ref = 0;
|
||||
table->dead++;
|
||||
#ifdef DD_STATS
|
||||
table->nodesDropped++;
|
||||
table->nodesDropped++;
|
||||
#endif
|
||||
ord = table->perm[N->index];
|
||||
stack[SP++] = Cudd_Regular(cuddE(N));
|
||||
table->subtables[ord].dead++;
|
||||
N = cuddT(N);
|
||||
} else {
|
||||
cuddSatDec(N->ref);
|
||||
N = stack[--SP];
|
||||
}
|
||||
ord = table->perm[N->index];
|
||||
stack[SP++] = Cudd_Regular(cuddE(N));
|
||||
table->subtables[ord].dead++;
|
||||
N = cuddT(N);
|
||||
} else {
|
||||
cuddSatDec(N->ref);
|
||||
N = stack[--SP];
|
||||
}
|
||||
} while (SP != 0);
|
||||
|
||||
} /* end of Cudd_IterDerefBdd */
|
||||
|
|
@ -254,7 +282,7 @@ Cudd_DelayedDerefBdd(
|
|||
|
||||
unsigned int live = table->keys - table->dead;
|
||||
if (live > table->peakLiveNodes) {
|
||||
table->peakLiveNodes = live;
|
||||
table->peakLiveNodes = live;
|
||||
}
|
||||
|
||||
n = Cudd_Regular(n);
|
||||
|
|
@ -267,10 +295,10 @@ Cudd_DelayedDerefBdd(
|
|||
#else
|
||||
if (cuddIsConstant(n) || n->ref > 1) {
|
||||
#ifdef DD_DEBUG
|
||||
assert(n->ref != 1 && (!cuddIsConstant(n) || n == DD_ONE(table)));
|
||||
assert(n->ref != 1 && (!cuddIsConstant(n) || n == DD_ONE(table)));
|
||||
#endif
|
||||
cuddSatDec(n->ref);
|
||||
return;
|
||||
cuddSatDec(n->ref);
|
||||
return;
|
||||
}
|
||||
|
||||
N = table->deathRow[table->nextDead];
|
||||
|
|
@ -278,29 +306,29 @@ Cudd_DelayedDerefBdd(
|
|||
if (N != NULL) {
|
||||
#endif
|
||||
#ifdef DD_DEBUG
|
||||
assert(!Cudd_IsComplement(N));
|
||||
assert(!Cudd_IsComplement(N));
|
||||
#endif
|
||||
stack = table->stack;
|
||||
SP = 1;
|
||||
do {
|
||||
stack = table->stack;
|
||||
SP = 1;
|
||||
do {
|
||||
#ifdef DD_DEBUG
|
||||
assert(N->ref != 0);
|
||||
assert(N->ref != 0);
|
||||
#endif
|
||||
if (N->ref == 1) {
|
||||
N->ref = 0;
|
||||
table->dead++;
|
||||
if (N->ref == 1) {
|
||||
N->ref = 0;
|
||||
table->dead++;
|
||||
#ifdef DD_STATS
|
||||
table->nodesDropped++;
|
||||
table->nodesDropped++;
|
||||
#endif
|
||||
ord = table->perm[N->index];
|
||||
stack[SP++] = Cudd_Regular(cuddE(N));
|
||||
table->subtables[ord].dead++;
|
||||
N = cuddT(N);
|
||||
} else {
|
||||
cuddSatDec(N->ref);
|
||||
N = stack[--SP];
|
||||
}
|
||||
} while (SP != 0);
|
||||
ord = table->perm[N->index];
|
||||
stack[SP++] = Cudd_Regular(cuddE(N));
|
||||
table->subtables[ord].dead++;
|
||||
N = cuddT(N);
|
||||
} else {
|
||||
cuddSatDec(N->ref);
|
||||
N = stack[--SP];
|
||||
}
|
||||
} while (SP != 0);
|
||||
#ifndef DD_NO_DEATH_ROW
|
||||
}
|
||||
table->deathRow[table->nextDead] = n;
|
||||
|
|
@ -310,29 +338,29 @@ Cudd_DelayedDerefBdd(
|
|||
table->nextDead &= table->deadMask;
|
||||
#if 0
|
||||
if (table->nextDead == table->deathRowDepth) {
|
||||
if (table->deathRowDepth < table->looseUpTo / 2) {
|
||||
// extern void (*MMoutOfMemory)(long);
|
||||
void (*saveHandler)(long) = MMoutOfMemory;
|
||||
DdNodePtr *newRow;
|
||||
MMoutOfMemory = Cudd_OutOfMem;
|
||||
newRow = ABC_REALLOC(DdNodePtr,table->deathRow,2*table->deathRowDepth);
|
||||
MMoutOfMemory = saveHandler;
|
||||
if (newRow == NULL) {
|
||||
table->nextDead = 0;
|
||||
if (table->deathRowDepth < table->looseUpTo / 2) {
|
||||
extern void (*MMoutOfMemory)(long);
|
||||
void (*saveHandler)(long) = MMoutOfMemory;
|
||||
DdNodePtr *newRow;
|
||||
MMoutOfMemory = Cudd_OutOfMem;
|
||||
newRow = ABC_REALLOC(DdNodePtr,table->deathRow,2*table->deathRowDepth);
|
||||
MMoutOfMemory = saveHandler;
|
||||
if (newRow == NULL) {
|
||||
table->nextDead = 0;
|
||||
} else {
|
||||
int i;
|
||||
table->memused += table->deathRowDepth;
|
||||
i = table->deathRowDepth;
|
||||
table->deathRowDepth <<= 1;
|
||||
for (; i < table->deathRowDepth; i++) {
|
||||
newRow[i] = NULL;
|
||||
}
|
||||
table->deadMask = table->deathRowDepth - 1;
|
||||
table->deathRow = newRow;
|
||||
}
|
||||
} else {
|
||||
int i;
|
||||
table->memused += table->deathRowDepth;
|
||||
i = table->deathRowDepth;
|
||||
table->deathRowDepth <<= 1;
|
||||
for (; i < table->deathRowDepth; i++) {
|
||||
newRow[i] = NULL;
|
||||
table->nextDead = 0;
|
||||
}
|
||||
table->deadMask = table->deathRowDepth - 1;
|
||||
table->deathRow = newRow;
|
||||
}
|
||||
} else {
|
||||
table->nextDead = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -367,26 +395,26 @@ Cudd_RecursiveDerefZdd(
|
|||
|
||||
do {
|
||||
#ifdef DD_DEBUG
|
||||
assert(N->ref != 0);
|
||||
assert(N->ref != 0);
|
||||
#endif
|
||||
|
||||
cuddSatDec(N->ref);
|
||||
cuddSatDec(N->ref);
|
||||
|
||||
if (N->ref == 0) {
|
||||
table->deadZ++;
|
||||
if (N->ref == 0) {
|
||||
table->deadZ++;
|
||||
#ifdef DD_STATS
|
||||
table->nodesDropped++;
|
||||
table->nodesDropped++;
|
||||
#endif
|
||||
#ifdef DD_DEBUG
|
||||
assert(!cuddIsConstant(N));
|
||||
assert(!cuddIsConstant(N));
|
||||
#endif
|
||||
ord = table->permZ[N->index];
|
||||
stack[SP++] = cuddE(N);
|
||||
table->subtableZ[ord].dead++;
|
||||
N = cuddT(N);
|
||||
} else {
|
||||
N = stack[--SP];
|
||||
}
|
||||
ord = table->permZ[N->index];
|
||||
stack[SP++] = cuddE(N);
|
||||
table->subtableZ[ord].dead++;
|
||||
N = cuddT(N);
|
||||
} else {
|
||||
N = stack[--SP];
|
||||
}
|
||||
} while (SP != 0);
|
||||
|
||||
} /* end of Cudd_RecursiveDerefZdd */
|
||||
|
|
@ -440,7 +468,7 @@ Cudd_CheckZeroRef(
|
|||
{
|
||||
int size;
|
||||
int i, j;
|
||||
int remain; /* the expected number of remaining references to one */
|
||||
int remain; /* the expected number of remaining references to one */
|
||||
DdNodePtr *nodelist;
|
||||
DdNode *node;
|
||||
DdNode *sentinel = &(manager->sentinel);
|
||||
|
|
@ -455,53 +483,53 @@ Cudd_CheckZeroRef(
|
|||
/* First look at the BDD/ADD subtables. */
|
||||
remain = 1; /* reference from the manager */
|
||||
size = manager->size;
|
||||
remain += 2 * size; /* reference from the BDD projection functions */
|
||||
remain += 2 * size; /* reference from the BDD projection functions */
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
subtable = &(manager->subtables[i]);
|
||||
nodelist = subtable->nodelist;
|
||||
for (j = 0; (unsigned) j < subtable->slots; j++) {
|
||||
node = nodelist[j];
|
||||
while (node != sentinel) {
|
||||
if (node->ref != 0 && node->ref != DD_MAXREF) {
|
||||
index = (int) node->index;
|
||||
if (node != manager->vars[index]) {
|
||||
count++;
|
||||
} else {
|
||||
if (node->ref != 1) {
|
||||
count++;
|
||||
}
|
||||
subtable = &(manager->subtables[i]);
|
||||
nodelist = subtable->nodelist;
|
||||
for (j = 0; (unsigned) j < subtable->slots; j++) {
|
||||
node = nodelist[j];
|
||||
while (node != sentinel) {
|
||||
if (node->ref != 0 && node->ref != DD_MAXREF) {
|
||||
index = (int) node->index;
|
||||
if (node != manager->vars[index]) {
|
||||
count++;
|
||||
} else {
|
||||
if (node->ref != 1) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Then look at the ZDD subtables. */
|
||||
size = manager->sizeZ;
|
||||
if (size) /* references from ZDD universe */
|
||||
remain += 2;
|
||||
remain += 2;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
subtable = &(manager->subtableZ[i]);
|
||||
nodelist = subtable->nodelist;
|
||||
for (j = 0; (unsigned) j < subtable->slots; j++) {
|
||||
node = nodelist[j];
|
||||
while (node != NULL) {
|
||||
if (node->ref != 0 && node->ref != DD_MAXREF) {
|
||||
index = (int) node->index;
|
||||
if (node == manager->univ[manager->permZ[index]]) {
|
||||
if (node->ref > 2) {
|
||||
count++;
|
||||
}
|
||||
} else {
|
||||
count++;
|
||||
subtable = &(manager->subtableZ[i]);
|
||||
nodelist = subtable->nodelist;
|
||||
for (j = 0; (unsigned) j < subtable->slots; j++) {
|
||||
node = nodelist[j];
|
||||
while (node != NULL) {
|
||||
if (node->ref != 0 && node->ref != DD_MAXREF) {
|
||||
index = (int) node->index;
|
||||
if (node == manager->univ[manager->permZ[index]]) {
|
||||
if (node->ref > 2) {
|
||||
count++;
|
||||
}
|
||||
} else {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now examine the constant table. Plusinfinity, minusinfinity, and
|
||||
|
|
@ -511,25 +539,25 @@ Cudd_CheckZeroRef(
|
|||
*/
|
||||
nodelist = manager->constants.nodelist;
|
||||
for (j = 0; (unsigned) j < manager->constants.slots; j++) {
|
||||
node = nodelist[j];
|
||||
while (node != NULL) {
|
||||
if (node->ref != 0 && node->ref != DD_MAXREF) {
|
||||
if (node == manager->one) {
|
||||
if ((int) node->ref != remain) {
|
||||
count++;
|
||||
node = nodelist[j];
|
||||
while (node != NULL) {
|
||||
if (node->ref != 0 && node->ref != DD_MAXREF) {
|
||||
if (node == manager->one) {
|
||||
if ((int) node->ref != remain) {
|
||||
count++;
|
||||
}
|
||||
} else if (node == manager->zero ||
|
||||
node == manager->plusinfinity ||
|
||||
node == manager->minusinfinity) {
|
||||
if (node->ref != 1) {
|
||||
count++;
|
||||
}
|
||||
} else {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
} else if (node == manager->zero ||
|
||||
node == manager->plusinfinity ||
|
||||
node == manager->minusinfinity) {
|
||||
if (node->ref != 1) {
|
||||
count++;
|
||||
}
|
||||
} else {
|
||||
count++;
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
return(count);
|
||||
|
||||
|
|
@ -570,22 +598,22 @@ cuddReclaim(
|
|||
#endif
|
||||
|
||||
do {
|
||||
if (N->ref == 0) {
|
||||
N->ref = 1;
|
||||
table->dead--;
|
||||
if (cuddIsConstant(N)) {
|
||||
table->constants.dead--;
|
||||
N = stack[--SP];
|
||||
if (N->ref == 0) {
|
||||
N->ref = 1;
|
||||
table->dead--;
|
||||
if (cuddIsConstant(N)) {
|
||||
table->constants.dead--;
|
||||
N = stack[--SP];
|
||||
} else {
|
||||
ord = table->perm[N->index];
|
||||
stack[SP++] = Cudd_Regular(cuddE(N));
|
||||
table->subtables[ord].dead--;
|
||||
N = cuddT(N);
|
||||
}
|
||||
} else {
|
||||
ord = table->perm[N->index];
|
||||
stack[SP++] = Cudd_Regular(cuddE(N));
|
||||
table->subtables[ord].dead--;
|
||||
N = cuddT(N);
|
||||
cuddSatInc(N->ref);
|
||||
N = stack[--SP];
|
||||
}
|
||||
} else {
|
||||
cuddSatInc(N->ref);
|
||||
N = stack[--SP];
|
||||
}
|
||||
} while (SP != 0);
|
||||
|
||||
N = Cudd_Regular(n);
|
||||
|
|
@ -623,21 +651,21 @@ cuddReclaimZdd(
|
|||
#endif
|
||||
|
||||
do {
|
||||
cuddSatInc(N->ref);
|
||||
cuddSatInc(N->ref);
|
||||
|
||||
if (N->ref == 1) {
|
||||
table->deadZ--;
|
||||
table->reclaimed++;
|
||||
if (N->ref == 1) {
|
||||
table->deadZ--;
|
||||
table->reclaimed++;
|
||||
#ifdef DD_DEBUG
|
||||
assert(!cuddIsConstant(N));
|
||||
assert(!cuddIsConstant(N));
|
||||
#endif
|
||||
ord = table->permZ[N->index];
|
||||
stack[SP++] = cuddE(N);
|
||||
table->subtableZ[ord].dead--;
|
||||
N = cuddT(N);
|
||||
} else {
|
||||
N = stack[--SP];
|
||||
}
|
||||
ord = table->permZ[N->index];
|
||||
stack[SP++] = cuddE(N);
|
||||
table->subtableZ[ord].dead--;
|
||||
N = cuddT(N);
|
||||
} else {
|
||||
N = stack[--SP];
|
||||
}
|
||||
} while (SP != 0);
|
||||
|
||||
cuddSatDec(n->ref);
|
||||
|
|
@ -664,18 +692,18 @@ cuddShrinkDeathRow(
|
|||
int i;
|
||||
|
||||
if (table->deathRowDepth > 3) {
|
||||
for (i = table->deathRowDepth/4; i < table->deathRowDepth; i++) {
|
||||
if (table->deathRow[i] == NULL) break;
|
||||
Cudd_IterDerefBdd(table,table->deathRow[i]);
|
||||
table->deathRow[i] = NULL;
|
||||
}
|
||||
table->deathRowDepth /= 4;
|
||||
table->deadMask = table->deathRowDepth - 2;
|
||||
if ((unsigned) table->nextDead > table->deadMask) {
|
||||
table->nextDead = 0;
|
||||
}
|
||||
table->deathRow = ABC_REALLOC(DdNodePtr, table->deathRow,
|
||||
table->deathRowDepth);
|
||||
for (i = table->deathRowDepth/4; i < table->deathRowDepth; i++) {
|
||||
if (table->deathRow[i] == NULL) break;
|
||||
Cudd_IterDerefBdd(table,table->deathRow[i]);
|
||||
table->deathRow[i] = NULL;
|
||||
}
|
||||
table->deathRowDepth /= 4;
|
||||
table->deadMask = table->deathRowDepth - 1;
|
||||
if ((unsigned) table->nextDead > table->deadMask) {
|
||||
table->nextDead = 0;
|
||||
}
|
||||
table->deathRow = ABC_REALLOC(DdNodePtr, table->deathRow,
|
||||
table->deathRowDepth);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -702,13 +730,13 @@ cuddClearDeathRow(
|
|||
int i;
|
||||
|
||||
for (i = 0; i < table->deathRowDepth; i++) {
|
||||
if (table->deathRow[i] == NULL) break;
|
||||
Cudd_IterDerefBdd(table,table->deathRow[i]);
|
||||
table->deathRow[i] = NULL;
|
||||
if (table->deathRow[i] == NULL) break;
|
||||
Cudd_IterDerefBdd(table,table->deathRow[i]);
|
||||
table->deathRow[i] = NULL;
|
||||
}
|
||||
#ifdef DD_DEBUG
|
||||
for (; i < table->deathRowDepth; i++) {
|
||||
assert(table->deathRow[i] == NULL);
|
||||
assert(table->deathRow[i] == NULL);
|
||||
}
|
||||
#endif
|
||||
table->nextDead = 0;
|
||||
|
|
@ -739,9 +767,9 @@ cuddIsInDeathRow(
|
|||
int i;
|
||||
|
||||
for (i = 0; i < dd->deathRowDepth; i++) {
|
||||
if (f == dd->deathRow[i]) {
|
||||
return(i);
|
||||
}
|
||||
if (f == dd->deathRow[i]) {
|
||||
return(i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -771,7 +799,7 @@ cuddTimesInDeathRow(
|
|||
int i;
|
||||
|
||||
for (i = 0; i < dd->deathRowDepth; i++) {
|
||||
count += f == dd->deathRow[i];
|
||||
count += f == dd->deathRow[i];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -782,5 +810,7 @@ cuddTimesInDeathRow(
|
|||
/*---------------------------------------------------------------------------*/
|
||||
/* Definition of static functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -4,24 +4,51 @@
|
|||
|
||||
PackageName [cudd]
|
||||
|
||||
Synopsis [Computation of signatures]
|
||||
Synopsis [Computation of signatures.]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_CofMinterm();
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> ddCofMintermAux()
|
||||
</ul>
|
||||
]
|
||||
<ul>
|
||||
<li> Cudd_CofMinterm();
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> ddCofMintermAux()
|
||||
</ul>
|
||||
]
|
||||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -32,6 +59,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -52,13 +80,13 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddSign.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddSign.c,v 1.22 2009/02/20 02:14:58 fabio Exp $";
|
||||
#endif
|
||||
|
||||
static int size;
|
||||
|
||||
#ifdef DD_STATS
|
||||
static int num_calls; /* should equal 2n-1 (n is the # of nodes) */
|
||||
static int num_calls; /* should equal 2n-1 (n is the # of nodes) */
|
||||
static int table_mem;
|
||||
#endif
|
||||
|
||||
|
|
@ -74,7 +102,7 @@ static int table_mem;
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static double * ddCofMintermAux ARGS((DdManager *dd, DdNode *node, st_table *table));
|
||||
static double * ddCofMintermAux (DdManager *dd, DdNode *node, st_table *table);
|
||||
|
||||
/**AutomaticEnd***************************************************************/
|
||||
|
||||
|
|
@ -90,7 +118,7 @@ static double * ddCofMintermAux ARGS((DdManager *dd, DdNode *node, st_table *tab
|
|||
|
||||
Description [Computes the fraction of minterms in the on-set of all
|
||||
the positive cofactors of DD. Returns the pointer to an array of
|
||||
doubles if successful; NULL otherwise. The array hs as many
|
||||
doubles if successful; NULL otherwise. The array has as many
|
||||
positions as there are BDD variables in the manager plus one. The
|
||||
last position of the array contains the fraction of the minterms in
|
||||
the ON-set of the function represented by the BDD or ADD. The other
|
||||
|
|
@ -105,9 +133,9 @@ Cudd_CofMinterm(
|
|||
DdNode * node)
|
||||
{
|
||||
st_table *table;
|
||||
double *values;
|
||||
double *result = NULL;
|
||||
int i, firstLevel;
|
||||
double *values;
|
||||
double *result = NULL;
|
||||
int i, firstLevel;
|
||||
|
||||
#ifdef DD_STATS
|
||||
long startTime;
|
||||
|
|
@ -118,52 +146,52 @@ Cudd_CofMinterm(
|
|||
|
||||
table = st_init_table(st_ptrcmp, st_ptrhash);
|
||||
if (table == NULL) {
|
||||
(void) fprintf(dd->err,
|
||||
"out-of-memory, couldn't measure DD cofactors.\n");
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
(void) fprintf(dd->err,
|
||||
"out-of-memory, couldn't measure DD cofactors.\n");
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
}
|
||||
size = dd->size;
|
||||
values = ddCofMintermAux(dd, node, table);
|
||||
if (values != NULL) {
|
||||
result = ABC_ALLOC(double,size + 1);
|
||||
if (result != NULL) {
|
||||
result = ABC_ALLOC(double,size + 1);
|
||||
if (result != NULL) {
|
||||
#ifdef DD_STATS
|
||||
table_mem += (size + 1) * sizeof(double);
|
||||
table_mem += (size + 1) * sizeof(double);
|
||||
#endif
|
||||
if (Cudd_IsConstant(node))
|
||||
firstLevel = 1;
|
||||
else
|
||||
firstLevel = cuddI(dd,Cudd_Regular(node)->index);
|
||||
for (i = 0; i < size; i++) {
|
||||
if (i >= cuddI(dd,Cudd_Regular(node)->index)) {
|
||||
result[dd->invperm[i]] = values[i - firstLevel];
|
||||
if (Cudd_IsConstant(node))
|
||||
firstLevel = 1;
|
||||
else
|
||||
firstLevel = cuddI(dd,Cudd_Regular(node)->index);
|
||||
for (i = 0; i < size; i++) {
|
||||
if (i >= cuddI(dd,Cudd_Regular(node)->index)) {
|
||||
result[dd->invperm[i]] = values[i - firstLevel];
|
||||
} else {
|
||||
result[dd->invperm[i]] = values[size - firstLevel];
|
||||
}
|
||||
}
|
||||
result[size] = values[size - firstLevel];
|
||||
} else {
|
||||
result[dd->invperm[i]] = values[size - firstLevel];
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
}
|
||||
}
|
||||
result[size] = values[size - firstLevel];
|
||||
} else {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DD_STATS
|
||||
table_mem += table->num_bins * sizeof(st_table_entry *);
|
||||
#endif
|
||||
if (Cudd_Regular(node)->ref == 1) ABC_FREE(values);
|
||||
st_foreach(table, (ST_PFSR)cuddStCountfree, NULL);
|
||||
st_foreach(table, cuddStCountfree, NULL);
|
||||
st_free_table(table);
|
||||
#ifdef DD_STATS
|
||||
(void) fprintf(dd->out,"Number of calls: %d\tTable memory: %d bytes\n",
|
||||
num_calls, table_mem);
|
||||
num_calls, table_mem);
|
||||
(void) fprintf(dd->out,"Time to compute measures: %s\n",
|
||||
util_print_time(util_cpu_time() - startTime));
|
||||
util_print_time(util_cpu_time() - startTime));
|
||||
#endif
|
||||
if (result == NULL) {
|
||||
(void) fprintf(dd->out,
|
||||
"out-of-memory, couldn't measure DD cofactors.\n");
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
(void) fprintf(dd->out,
|
||||
"out-of-memory, couldn't measure DD cofactors.\n");
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
}
|
||||
return(result);
|
||||
|
||||
|
|
@ -206,92 +234,93 @@ ddCofMintermAux(
|
|||
DdNode * node,
|
||||
st_table * table)
|
||||
{
|
||||
DdNode *N; /* regular version of node */
|
||||
DdNode *Nv, *Nnv;
|
||||
double *values;
|
||||
double *valuesT, *valuesE;
|
||||
int i;
|
||||
int localSize, localSizeT, localSizeE;
|
||||
double vT, vE;
|
||||
DdNode *N; /* regular version of node */
|
||||
DdNode *Nv, *Nnv;
|
||||
double *values;
|
||||
double *valuesT, *valuesE;
|
||||
int i;
|
||||
int localSize, localSizeT, localSizeE;
|
||||
double vT, vE;
|
||||
|
||||
statLine(dd);
|
||||
#ifdef DD_STATS
|
||||
num_calls++;
|
||||
#endif
|
||||
|
||||
if (st_lookup(table, (char *) node, (char **) &values)) {
|
||||
return(values);
|
||||
if (st_lookup(table, (const char *)node, (char **)&values)) {
|
||||
return(values);
|
||||
}
|
||||
|
||||
N = Cudd_Regular(node);
|
||||
if (cuddIsConstant(N)) {
|
||||
localSize = 1;
|
||||
localSize = 1;
|
||||
} else {
|
||||
localSize = size - cuddI(dd,N->index) + 1;
|
||||
localSize = size - cuddI(dd,N->index) + 1;
|
||||
}
|
||||
values = ABC_ALLOC(double, localSize);
|
||||
if (values == NULL) {
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
dd->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (cuddIsConstant(N)) {
|
||||
if (node == DD_ZERO(dd) || node == Cudd_Not(DD_ONE(dd))) {
|
||||
values[0] = 0.0;
|
||||
} else {
|
||||
values[0] = 1.0;
|
||||
}
|
||||
} else {
|
||||
Nv = Cudd_NotCond(cuddT(N),N!=node);
|
||||
Nnv = Cudd_NotCond(cuddE(N),N!=node);
|
||||
|
||||
valuesT = ddCofMintermAux(dd, Nv, table);
|
||||
if (valuesT == NULL) return(NULL);
|
||||
valuesE = ddCofMintermAux(dd, Nnv, table);
|
||||
if (valuesE == NULL) return(NULL);
|
||||
|
||||
if (Cudd_IsConstant(Nv)) {
|
||||
localSizeT = 1;
|
||||
} else {
|
||||
localSizeT = size - cuddI(dd,Cudd_Regular(Nv)->index) + 1;
|
||||
}
|
||||
if (Cudd_IsConstant(Nnv)) {
|
||||
localSizeE = 1;
|
||||
} else {
|
||||
localSizeE = size - cuddI(dd,Cudd_Regular(Nnv)->index) + 1;
|
||||
}
|
||||
values[0] = valuesT[localSizeT - 1];
|
||||
for (i = 1; i < localSize; i++) {
|
||||
if (i >= cuddI(dd,Cudd_Regular(Nv)->index) - cuddI(dd,N->index)) {
|
||||
vT = valuesT[i - cuddI(dd,Cudd_Regular(Nv)->index) +
|
||||
cuddI(dd,N->index)];
|
||||
if (node == DD_ZERO(dd) || node == Cudd_Not(DD_ONE(dd))) {
|
||||
values[0] = 0.0;
|
||||
} else {
|
||||
vT = valuesT[localSizeT - 1];
|
||||
values[0] = 1.0;
|
||||
}
|
||||
if (i >= cuddI(dd,Cudd_Regular(Nnv)->index) - cuddI(dd,N->index)) {
|
||||
vE = valuesE[i - cuddI(dd,Cudd_Regular(Nnv)->index) +
|
||||
cuddI(dd,N->index)];
|
||||
} else {
|
||||
Nv = Cudd_NotCond(cuddT(N),N!=node);
|
||||
Nnv = Cudd_NotCond(cuddE(N),N!=node);
|
||||
|
||||
valuesT = ddCofMintermAux(dd, Nv, table);
|
||||
if (valuesT == NULL) return(NULL);
|
||||
valuesE = ddCofMintermAux(dd, Nnv, table);
|
||||
if (valuesE == NULL) return(NULL);
|
||||
|
||||
if (Cudd_IsConstant(Nv)) {
|
||||
localSizeT = 1;
|
||||
} else {
|
||||
vE = valuesE[localSizeE - 1];
|
||||
localSizeT = size - cuddI(dd,Cudd_Regular(Nv)->index) + 1;
|
||||
}
|
||||
values[i] = (vT + vE) / 2.0;
|
||||
}
|
||||
if (Cudd_Regular(Nv)->ref == 1) ABC_FREE(valuesT);
|
||||
if (Cudd_Regular(Nnv)->ref == 1) ABC_FREE(valuesE);
|
||||
if (Cudd_IsConstant(Nnv)) {
|
||||
localSizeE = 1;
|
||||
} else {
|
||||
localSizeE = size - cuddI(dd,Cudd_Regular(Nnv)->index) + 1;
|
||||
}
|
||||
values[0] = valuesT[localSizeT - 1];
|
||||
for (i = 1; i < localSize; i++) {
|
||||
if (i >= cuddI(dd,Cudd_Regular(Nv)->index) - cuddI(dd,N->index)) {
|
||||
vT = valuesT[i - cuddI(dd,Cudd_Regular(Nv)->index) +
|
||||
cuddI(dd,N->index)];
|
||||
} else {
|
||||
vT = valuesT[localSizeT - 1];
|
||||
}
|
||||
if (i >= cuddI(dd,Cudd_Regular(Nnv)->index) - cuddI(dd,N->index)) {
|
||||
vE = valuesE[i - cuddI(dd,Cudd_Regular(Nnv)->index) +
|
||||
cuddI(dd,N->index)];
|
||||
} else {
|
||||
vE = valuesE[localSizeE - 1];
|
||||
}
|
||||
values[i] = (vT + vE) / 2.0;
|
||||
}
|
||||
if (Cudd_Regular(Nv)->ref == 1) ABC_FREE(valuesT);
|
||||
if (Cudd_Regular(Nnv)->ref == 1) ABC_FREE(valuesE);
|
||||
}
|
||||
|
||||
if (N->ref > 1) {
|
||||
if (st_add_direct(table, (char *) node, (char *) values) == ST_OUT_OF_MEM) {
|
||||
ABC_FREE(values);
|
||||
return(NULL);
|
||||
}
|
||||
if (st_add_direct(table, (char *) node, (char *) values) == ST_OUT_OF_MEM) {
|
||||
ABC_FREE(values);
|
||||
return(NULL);
|
||||
}
|
||||
#ifdef DD_STATS
|
||||
table_mem += localSize * sizeof(double) + sizeof(st_table_entry);
|
||||
table_mem += localSize * sizeof(double) + sizeof(st_table_entry);
|
||||
#endif
|
||||
}
|
||||
return(values);
|
||||
|
||||
} /* end of ddCofMintermAux */
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -7,24 +7,51 @@
|
|||
Synopsis [Boolean equation solver and related functions.]
|
||||
|
||||
Description [External functions included in this modoule:
|
||||
<ul>
|
||||
<li> Cudd_SolveEqn()
|
||||
<li> Cudd_VerifySol()
|
||||
</ul>
|
||||
Internal functions included in this module:
|
||||
<ul>
|
||||
<li> cuddSolveEqnRecur()
|
||||
<li> cuddVerifySol()
|
||||
</ul> ]
|
||||
<ul>
|
||||
<li> Cudd_SolveEqn()
|
||||
<li> Cudd_VerifySol()
|
||||
</ul>
|
||||
Internal functions included in this module:
|
||||
<ul>
|
||||
<li> cuddSolveEqnRecur()
|
||||
<li> cuddVerifySol()
|
||||
</ul> ]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
Author [Balakrishna Kumthekar]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -34,6 +61,7 @@
|
|||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -54,7 +82,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddSolve.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddSolve.c,v 1.12 2004/08/13 18:04:51 fabio Exp $";
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -108,15 +136,15 @@ Cudd_SolveEqn(
|
|||
|
||||
*yIndex = temp = ABC_ALLOC(int, n);
|
||||
if (temp == NULL) {
|
||||
bdd->errorCode = CUDD_MEMORY_OUT;
|
||||
(void) fprintf(bdd->out,
|
||||
"Cudd_SolveEqn: Out of memory for yIndex\n");
|
||||
return(NULL);
|
||||
bdd->errorCode = CUDD_MEMORY_OUT;
|
||||
(void) fprintf(bdd->out,
|
||||
"Cudd_SolveEqn: Out of memory for yIndex\n");
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
do {
|
||||
bdd->reordered = 0;
|
||||
res = cuddSolveEqnRecur(bdd, F, Y, G, n, temp, 0);
|
||||
bdd->reordered = 0;
|
||||
res = cuddSolveEqnRecur(bdd, F, Y, G, n, temp, 0);
|
||||
} while (bdd->reordered == 1);
|
||||
|
||||
return(res);
|
||||
|
|
@ -148,8 +176,8 @@ Cudd_VerifySol(
|
|||
DdNode *res;
|
||||
|
||||
do {
|
||||
bdd->reordered = 0;
|
||||
res = cuddVerifySol(bdd, F, G, yIndex, n);
|
||||
bdd->reordered = 0;
|
||||
res = cuddVerifySol(bdd, F, G, yIndex, n);
|
||||
} while (bdd->reordered == 1);
|
||||
|
||||
ABC_FREE(yIndex);
|
||||
|
|
@ -199,7 +227,7 @@ cuddSolveEqnRecur(
|
|||
|
||||
/* Base condition. */
|
||||
if (Y == one) {
|
||||
return F;
|
||||
return F;
|
||||
}
|
||||
|
||||
/* Cofactor of Y. */
|
||||
|
|
@ -209,61 +237,61 @@ cuddSolveEqnRecur(
|
|||
/* Universal abstraction of F with respect to the top variable index. */
|
||||
Fm1 = cuddBddExistAbstractRecur(bdd, Cudd_Not(F), variables[yIndex[i]]);
|
||||
if (Fm1) {
|
||||
Fm1 = Cudd_Not(Fm1);
|
||||
cuddRef(Fm1);
|
||||
Fm1 = Cudd_Not(Fm1);
|
||||
cuddRef(Fm1);
|
||||
} else {
|
||||
return(NULL);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
Fn = cuddSolveEqnRecur(bdd, Fm1, nextY, G, n, yIndex, i+1);
|
||||
if (Fn) {
|
||||
cuddRef(Fn);
|
||||
cuddRef(Fn);
|
||||
} else {
|
||||
Cudd_RecursiveDeref(bdd, Fm1);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(bdd, Fm1);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
Fv = cuddCofactorRecur(bdd, F, variables[yIndex[i]]);
|
||||
if (Fv) {
|
||||
cuddRef(Fv);
|
||||
cuddRef(Fv);
|
||||
} else {
|
||||
Cudd_RecursiveDeref(bdd, Fm1);
|
||||
Cudd_RecursiveDeref(bdd, Fn);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(bdd, Fm1);
|
||||
Cudd_RecursiveDeref(bdd, Fn);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
Fvbar = cuddCofactorRecur(bdd, F, Cudd_Not(variables[yIndex[i]]));
|
||||
if (Fvbar) {
|
||||
cuddRef(Fvbar);
|
||||
cuddRef(Fvbar);
|
||||
} else {
|
||||
Cudd_RecursiveDeref(bdd, Fm1);
|
||||
Cudd_RecursiveDeref(bdd, Fn);
|
||||
Cudd_RecursiveDeref(bdd, Fv);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(bdd, Fm1);
|
||||
Cudd_RecursiveDeref(bdd, Fn);
|
||||
Cudd_RecursiveDeref(bdd, Fv);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* Build i-th component of the solution. */
|
||||
w = cuddBddIteRecur(bdd, variables[yIndex[i]], Cudd_Not(Fv), Fvbar);
|
||||
if (w) {
|
||||
cuddRef(w);
|
||||
cuddRef(w);
|
||||
} else {
|
||||
Cudd_RecursiveDeref(bdd, Fm1);
|
||||
Cudd_RecursiveDeref(bdd, Fn);
|
||||
Cudd_RecursiveDeref(bdd, Fv);
|
||||
Cudd_RecursiveDeref(bdd, Fvbar);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(bdd, Fm1);
|
||||
Cudd_RecursiveDeref(bdd, Fn);
|
||||
Cudd_RecursiveDeref(bdd, Fv);
|
||||
Cudd_RecursiveDeref(bdd, Fvbar);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
T = cuddBddRestrictRecur(bdd, w, Cudd_Not(Fm1));
|
||||
if(T) {
|
||||
cuddRef(T);
|
||||
cuddRef(T);
|
||||
} else {
|
||||
Cudd_RecursiveDeref(bdd, Fm1);
|
||||
Cudd_RecursiveDeref(bdd, Fn);
|
||||
Cudd_RecursiveDeref(bdd, Fv);
|
||||
Cudd_RecursiveDeref(bdd, Fvbar);
|
||||
Cudd_RecursiveDeref(bdd, w);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(bdd, Fm1);
|
||||
Cudd_RecursiveDeref(bdd, Fn);
|
||||
Cudd_RecursiveDeref(bdd, Fv);
|
||||
Cudd_RecursiveDeref(bdd, Fvbar);
|
||||
Cudd_RecursiveDeref(bdd, w);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
Cudd_RecursiveDeref(bdd,Fm1);
|
||||
|
|
@ -273,16 +301,16 @@ cuddSolveEqnRecur(
|
|||
|
||||
/* Substitute components of solution already found into solution. */
|
||||
for (j = n-1; j > i; j--) {
|
||||
w = cuddBddComposeRecur(bdd,T, G[j], variables[yIndex[j]]);
|
||||
if(w) {
|
||||
cuddRef(w);
|
||||
} else {
|
||||
Cudd_RecursiveDeref(bdd, Fn);
|
||||
Cudd_RecursiveDeref(bdd, T);
|
||||
return(NULL);
|
||||
}
|
||||
Cudd_RecursiveDeref(bdd,T);
|
||||
T = w;
|
||||
w = cuddBddComposeRecur(bdd,T, G[j], variables[yIndex[j]]);
|
||||
if(w) {
|
||||
cuddRef(w);
|
||||
} else {
|
||||
Cudd_RecursiveDeref(bdd, Fn);
|
||||
Cudd_RecursiveDeref(bdd, T);
|
||||
return(NULL);
|
||||
}
|
||||
Cudd_RecursiveDeref(bdd,T);
|
||||
T = w;
|
||||
}
|
||||
G[i] = T;
|
||||
|
||||
|
|
@ -319,14 +347,14 @@ cuddVerifySol(
|
|||
R = F;
|
||||
cuddRef(R);
|
||||
for(j = n - 1; j >= 0; j--) {
|
||||
w = Cudd_bddCompose(bdd, R, G[j], yIndex[j]);
|
||||
if (w) {
|
||||
cuddRef(w);
|
||||
} else {
|
||||
return(NULL);
|
||||
}
|
||||
Cudd_RecursiveDeref(bdd,R);
|
||||
R = w;
|
||||
w = Cudd_bddCompose(bdd, R, G[j], yIndex[j]);
|
||||
if (w) {
|
||||
cuddRef(w);
|
||||
} else {
|
||||
return(NULL);
|
||||
}
|
||||
Cudd_RecursiveDeref(bdd,R);
|
||||
R = w;
|
||||
}
|
||||
|
||||
cuddDeref(R);
|
||||
|
|
@ -340,5 +368,7 @@ cuddVerifySol(
|
|||
/* Definition of static functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,28 +7,55 @@
|
|||
Synopsis [Returns a subset of minterms from a boolean function.]
|
||||
|
||||
Description [External functions included in this modoule:
|
||||
<ul>
|
||||
<li> Cudd_SplitSet()
|
||||
</ul>
|
||||
Internal functions included in this module:
|
||||
<ul>
|
||||
<li> cuddSplitSetRecur()
|
||||
</u>
|
||||
<ul>
|
||||
<li> Cudd_SplitSet()
|
||||
</ul>
|
||||
Internal functions included in this module:
|
||||
<ul>
|
||||
<li> cuddSplitSetRecur()
|
||||
</u>
|
||||
Static functions included in this module:
|
||||
<ul>
|
||||
<li> selectMintermsFromUniverse()
|
||||
<li> mintermsFromUniverse()
|
||||
<li> bddAnnotateMintermCount()
|
||||
</ul> ]
|
||||
<ul>
|
||||
<li> selectMintermsFromUniverse()
|
||||
<li> mintermsFromUniverse()
|
||||
<li> bddAnnotateMintermCount()
|
||||
</ul> ]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
Author [Balakrishna Kumthekar]
|
||||
|
||||
Copyright [This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
|
@ -38,6 +65,7 @@
|
|||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -68,9 +96,9 @@ ABC_NAMESPACE_IMPL_START
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static DdNode * selectMintermsFromUniverse ARGS((DdManager *manager, int *varSeen, double n));
|
||||
static DdNode * mintermsFromUniverse ARGS((DdManager *manager, DdNode **vars, int numVars, double n, int index));
|
||||
static double bddAnnotateMintermCount ARGS((DdManager *manager, DdNode *node, double max, st_table *table));
|
||||
static DdNode * selectMintermsFromUniverse (DdManager *manager, int *varSeen, double n);
|
||||
static DdNode * mintermsFromUniverse (DdManager *manager, DdNode **vars, int numVars, double n, int index);
|
||||
static double bddAnnotateMintermCount (DdManager *manager, DdNode *node, double max, st_table *table);
|
||||
|
||||
/**AutomaticEnd***************************************************************/
|
||||
|
||||
|
|
@ -117,69 +145,71 @@ Cudd_SplitSet(
|
|||
|
||||
/* Trivial cases. */
|
||||
if (m == 0.0) {
|
||||
return(zero);
|
||||
return(zero);
|
||||
}
|
||||
if (S == zero) {
|
||||
return(NULL);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
max = pow(2.0,(double)n);
|
||||
if (m > max)
|
||||
return(NULL);
|
||||
return(NULL);
|
||||
|
||||
do {
|
||||
manager->reordered = 0;
|
||||
/* varSeen is used to mark the variables that are encountered
|
||||
** while traversing the BDD S.
|
||||
*/
|
||||
varSeen = ABC_ALLOC(int, size);
|
||||
if (varSeen == NULL) {
|
||||
manager->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
}
|
||||
for (i = 0; i < size; i++) {
|
||||
varSeen[i] = -1;
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
index = (xVars[i])->index;
|
||||
varSeen[manager->invperm[index]] = 0;
|
||||
}
|
||||
|
||||
if (S == one) {
|
||||
if (m == max)
|
||||
return(S);
|
||||
result = selectMintermsFromUniverse(manager,varSeen,m);
|
||||
if (result)
|
||||
cuddRef(result);
|
||||
ABC_FREE(varSeen);
|
||||
} else {
|
||||
mtable = st_init_table(st_ptrcmp, st_ptrhash);;
|
||||
if (mtable == NULL) {
|
||||
(void) fprintf(manager->out,
|
||||
"Cudd_SplitSet: out-of-memory.\n");
|
||||
ABC_FREE(varSeen);
|
||||
manager->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
}
|
||||
/* The nodes of BDD S are annotated by the number of minterms
|
||||
** in their onset. The node and the number of minterms in its
|
||||
** onset are stored in mtable.
|
||||
manager->reordered = 0;
|
||||
/* varSeen is used to mark the variables that are encountered
|
||||
** while traversing the BDD S.
|
||||
*/
|
||||
num = bddAnnotateMintermCount(manager,S,max,mtable);
|
||||
if (m == num) {
|
||||
st_foreach(mtable,(ST_PFSR)cuddStCountfree,NIL(char));
|
||||
st_free_table(mtable);
|
||||
ABC_FREE(varSeen);
|
||||
return(S);
|
||||
varSeen = ABC_ALLOC(int, size);
|
||||
if (varSeen == NULL) {
|
||||
manager->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
}
|
||||
for (i = 0; i < size; i++) {
|
||||
varSeen[i] = -1;
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
index = (xVars[i])->index;
|
||||
varSeen[manager->invperm[index]] = 0;
|
||||
}
|
||||
|
||||
if (S == one) {
|
||||
if (m == max) {
|
||||
ABC_FREE(varSeen);
|
||||
return(S);
|
||||
}
|
||||
result = selectMintermsFromUniverse(manager,varSeen,m);
|
||||
if (result)
|
||||
cuddRef(result);
|
||||
ABC_FREE(varSeen);
|
||||
} else {
|
||||
mtable = st_init_table(st_ptrcmp,st_ptrhash);
|
||||
if (mtable == NULL) {
|
||||
(void) fprintf(manager->out,
|
||||
"Cudd_SplitSet: out-of-memory.\n");
|
||||
ABC_FREE(varSeen);
|
||||
manager->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
}
|
||||
/* The nodes of BDD S are annotated by the number of minterms
|
||||
** in their onset. The node and the number of minterms in its
|
||||
** onset are stored in mtable.
|
||||
*/
|
||||
num = bddAnnotateMintermCount(manager,S,max,mtable);
|
||||
if (m == num) {
|
||||
st_foreach(mtable,cuddStCountfree,NIL(char));
|
||||
st_free_table(mtable);
|
||||
ABC_FREE(varSeen);
|
||||
return(S);
|
||||
}
|
||||
|
||||
result = cuddSplitSetRecur(manager,mtable,varSeen,S,m,max,0);
|
||||
if (result)
|
||||
cuddRef(result);
|
||||
st_foreach(mtable,cuddStCountfree,NULL);
|
||||
st_free_table(mtable);
|
||||
ABC_FREE(varSeen);
|
||||
}
|
||||
|
||||
result = cuddSplitSetRecur(manager,mtable,varSeen,S,m,max,0);
|
||||
if (result)
|
||||
cuddRef(result);
|
||||
st_foreach(mtable,(ST_PFSR)cuddStCountfree,NULL);
|
||||
st_free_table(mtable);
|
||||
ABC_FREE(varSeen);
|
||||
}
|
||||
} while (manager->reordered == 1);
|
||||
|
||||
cuddDeref(result);
|
||||
|
|
@ -238,8 +268,8 @@ cuddSplitSetRecur(
|
|||
** constant 0.
|
||||
*/
|
||||
if (Cudd_IsConstant(p)) {
|
||||
q = selectMintermsFromUniverse(manager,varSeen,n);
|
||||
return(q);
|
||||
q = selectMintermsFromUniverse(manager,varSeen,n);
|
||||
return(q);
|
||||
}
|
||||
|
||||
N = Cudd_Regular(p);
|
||||
|
|
@ -251,47 +281,47 @@ cuddSplitSetRecur(
|
|||
Nv = cuddT(N);
|
||||
Nnv = cuddE(N);
|
||||
if (Cudd_IsComplement(p)) {
|
||||
Nv = Cudd_Not(Nv);
|
||||
Nnv = Cudd_Not(Nnv);
|
||||
Nv = Cudd_Not(Nv);
|
||||
Nnv = Cudd_Not(Nnv);
|
||||
}
|
||||
|
||||
/* If both the children of 'p' are constants, extract n minterms from a
|
||||
** constant node.
|
||||
*/
|
||||
if (Cudd_IsConstant(Nv) && Cudd_IsConstant(Nnv)) {
|
||||
q = selectMintermsFromUniverse(manager,varSeen,n);
|
||||
if (q == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(q);
|
||||
r = cuddBddAndRecur(manager,p,q);
|
||||
if (r == NULL) {
|
||||
q = selectMintermsFromUniverse(manager,varSeen,n);
|
||||
if (q == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(q);
|
||||
r = cuddBddAndRecur(manager,p,q);
|
||||
if (r == NULL) {
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(r);
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(r);
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
cuddDeref(r);
|
||||
return(r);
|
||||
cuddDeref(r);
|
||||
return(r);
|
||||
}
|
||||
|
||||
/* Lookup the # of minterms in the onset of the node from the table. */
|
||||
if (!Cudd_IsConstant(Nv)) {
|
||||
st_lookup(mtable,(char *)Nv, (char **)&dummy);
|
||||
numT = *dummy/(2*(1<<index));
|
||||
if (!st_lookup(mtable, (const char *)Nv, (char **)&dummy)) return(NULL);
|
||||
numT = *dummy/(2*(1<<index));
|
||||
} else if (Nv == one) {
|
||||
numT = max/(2*(1<<index));
|
||||
numT = max/(2*(1<<index));
|
||||
} else {
|
||||
numT = 0;
|
||||
numT = 0;
|
||||
}
|
||||
|
||||
if (!Cudd_IsConstant(Nnv)) {
|
||||
st_lookup(mtable,(char *)Nnv, (char **)&dummy);
|
||||
numE = *dummy/(2*(1<<index));
|
||||
if (!st_lookup(mtable, (const char *)Nnv, (char **)&dummy)) return(NULL);
|
||||
numE = *dummy/(2*(1<<index));
|
||||
} else if (Nnv == one) {
|
||||
numE = max/(2*(1<<index));
|
||||
numE = max/(2*(1<<index));
|
||||
} else {
|
||||
numE = 0;
|
||||
numE = 0;
|
||||
}
|
||||
|
||||
v = cuddUniqueInter(manager,variable,one,zero);
|
||||
|
|
@ -299,72 +329,72 @@ cuddSplitSetRecur(
|
|||
|
||||
/* If perfect match. */
|
||||
if (numT == n) {
|
||||
q = cuddBddAndRecur(manager,v,Nv);
|
||||
if (q == NULL) {
|
||||
q = cuddBddAndRecur(manager,v,Nv);
|
||||
if (q == NULL) {
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(q);
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(q);
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
cuddDeref(q);
|
||||
return(q);
|
||||
cuddDeref(q);
|
||||
return(q);
|
||||
}
|
||||
if (numE == n) {
|
||||
q = cuddBddAndRecur(manager,Cudd_Not(v),Nnv);
|
||||
if (q == NULL) {
|
||||
q = cuddBddAndRecur(manager,Cudd_Not(v),Nnv);
|
||||
if (q == NULL) {
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(q);
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(q);
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
cuddDeref(q);
|
||||
return(q);
|
||||
cuddDeref(q);
|
||||
return(q);
|
||||
}
|
||||
/* If n is greater than numT, extract the difference from the ELSE child
|
||||
** and retain the function represented by the THEN branch.
|
||||
*/
|
||||
if (numT < n) {
|
||||
q = cuddSplitSetRecur(manager,mtable,varSeen,
|
||||
Nnv,(n-numT),max,index+1);
|
||||
if (q == NULL) {
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(q);
|
||||
r = cuddBddIteRecur(manager,v,Nv,q);
|
||||
if (r == NULL) {
|
||||
q = cuddSplitSetRecur(manager,mtable,varSeen,
|
||||
Nnv,(n-numT),max,index+1);
|
||||
if (q == NULL) {
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(q);
|
||||
r = cuddBddIteRecur(manager,v,Nv,q);
|
||||
if (r == NULL) {
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(r);
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(r);
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
cuddDeref(r);
|
||||
return(r);
|
||||
cuddDeref(r);
|
||||
return(r);
|
||||
}
|
||||
/* If n is greater than numE, extract the difference from the THEN child
|
||||
** and retain the function represented by the ELSE branch.
|
||||
*/
|
||||
if (numE < n) {
|
||||
q = cuddSplitSetRecur(manager,mtable,varSeen,
|
||||
Nv, (n-numE),max,index+1);
|
||||
if (q == NULL) {
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(q);
|
||||
r = cuddBddIteRecur(manager,v,q,Nnv);
|
||||
if (r == NULL) {
|
||||
q = cuddSplitSetRecur(manager,mtable,varSeen,
|
||||
Nv, (n-numE),max,index+1);
|
||||
if (q == NULL) {
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(q);
|
||||
r = cuddBddIteRecur(manager,v,q,Nnv);
|
||||
if (r == NULL) {
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(r);
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(r);
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
cuddDeref(r);
|
||||
return(r);
|
||||
cuddDeref(r);
|
||||
return(r);
|
||||
}
|
||||
|
||||
/* None of the above cases; (n < numT and n < numE) and either of
|
||||
|
|
@ -372,41 +402,41 @@ cuddSplitSetRecur(
|
|||
** required minterms the constant branch.
|
||||
*/
|
||||
if (Cudd_IsConstant(Nv) && !Cudd_IsConstant(Nnv)) {
|
||||
q = selectMintermsFromUniverse(manager,varSeen,n);
|
||||
if (q == NULL) {
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(q);
|
||||
result = cuddBddAndRecur(manager,v,q);
|
||||
if (result == NULL) {
|
||||
q = selectMintermsFromUniverse(manager,varSeen,n);
|
||||
if (q == NULL) {
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(q);
|
||||
result = cuddBddAndRecur(manager,v,q);
|
||||
if (result == NULL) {
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(result);
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(result);
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
cuddDeref(result);
|
||||
return(result);
|
||||
cuddDeref(result);
|
||||
return(result);
|
||||
} else if (!Cudd_IsConstant(Nv) && Cudd_IsConstant(Nnv)) {
|
||||
q = selectMintermsFromUniverse(manager,varSeen,n);
|
||||
if (q == NULL) {
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(q);
|
||||
result = cuddBddAndRecur(manager,Cudd_Not(v),q);
|
||||
if (result == NULL) {
|
||||
q = selectMintermsFromUniverse(manager,varSeen,n);
|
||||
if (q == NULL) {
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(q);
|
||||
result = cuddBddAndRecur(manager,Cudd_Not(v),q);
|
||||
if (result == NULL) {
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(result);
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(result);
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
cuddDeref(result);
|
||||
return(result);
|
||||
cuddDeref(result);
|
||||
return(result);
|
||||
}
|
||||
|
||||
/* Both Nv and Nnv are not constants. So choose the one which
|
||||
|
|
@ -414,29 +444,29 @@ cuddSplitSetRecur(
|
|||
*/
|
||||
positive = 0;
|
||||
if (numT < numE) {
|
||||
q = cuddSplitSetRecur(manager,mtable,varSeen,
|
||||
Nv,n,max,index+1);
|
||||
positive = 1;
|
||||
q = cuddSplitSetRecur(manager,mtable,varSeen,
|
||||
Nv,n,max,index+1);
|
||||
positive = 1;
|
||||
} else {
|
||||
q = cuddSplitSetRecur(manager,mtable,varSeen,
|
||||
Nnv,n,max,index+1);
|
||||
q = cuddSplitSetRecur(manager,mtable,varSeen,
|
||||
Nnv,n,max,index+1);
|
||||
}
|
||||
|
||||
if (q == NULL) {
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(q);
|
||||
|
||||
if (positive) {
|
||||
result = cuddBddAndRecur(manager,v,q);
|
||||
result = cuddBddAndRecur(manager,v,q);
|
||||
} else {
|
||||
result = cuddBddAndRecur(manager,Cudd_Not(v),q);
|
||||
result = cuddBddAndRecur(manager,Cudd_Not(v),q);
|
||||
}
|
||||
if (result == NULL) {
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
Cudd_RecursiveDeref(manager,v);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(result);
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
|
|
@ -485,22 +515,22 @@ selectMintermsFromUniverse(
|
|||
** cuddSplitSetRecur.
|
||||
*/
|
||||
for (i = size-1; i >= 0; i--) {
|
||||
if(varSeen[i] == 0)
|
||||
numVars++;
|
||||
if(varSeen[i] == 0)
|
||||
numVars++;
|
||||
}
|
||||
vars = ABC_ALLOC(DdNode *, numVars);
|
||||
if (!vars) {
|
||||
manager->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
manager->errorCode = CUDD_MEMORY_OUT;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
j = 0;
|
||||
for (i = size-1; i >= 0; i--) {
|
||||
if(varSeen[i] == 0) {
|
||||
vars[j] = cuddUniqueInter(manager,manager->perm[i],one,zero);
|
||||
cuddRef(vars[j]);
|
||||
j++;
|
||||
}
|
||||
if(varSeen[i] == 0) {
|
||||
vars[j] = cuddUniqueInter(manager,manager->perm[i],one,zero);
|
||||
cuddRef(vars[j]);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute a function which has n minterms and depends on at most
|
||||
|
|
@ -508,10 +538,10 @@ selectMintermsFromUniverse(
|
|||
*/
|
||||
result = mintermsFromUniverse(manager,vars,numVars,n, 0);
|
||||
if (result)
|
||||
cuddRef(result);
|
||||
cuddRef(result);
|
||||
|
||||
for (i = 0; i < numVars; i++)
|
||||
Cudd_RecursiveDeref(manager,vars[i]);
|
||||
Cudd_RecursiveDeref(manager,vars[i]);
|
||||
ABC_FREE(vars);
|
||||
|
||||
return(result);
|
||||
|
|
@ -548,37 +578,37 @@ mintermsFromUniverse(
|
|||
max2 = max / 2.0;
|
||||
|
||||
if (n == max)
|
||||
return(one);
|
||||
return(one);
|
||||
if (n == 0.0)
|
||||
return(zero);
|
||||
return(zero);
|
||||
/* if n == 2^(numVars-1), return a single variable */
|
||||
if (n == max2)
|
||||
return vars[index];
|
||||
return vars[index];
|
||||
else if (n > max2) {
|
||||
/* When n > 2^(numVars-1), a single variable vars[index]
|
||||
** contains 2^(numVars-1) minterms. The rest are extracted
|
||||
** from a constant with 1 less variable.
|
||||
*/
|
||||
q = mintermsFromUniverse(manager,vars,numVars-1,(n-max2),index+1);
|
||||
if (q == NULL)
|
||||
return(NULL);
|
||||
cuddRef(q);
|
||||
result = cuddBddIteRecur(manager,vars[index],one,q);
|
||||
/* When n > 2^(numVars-1), a single variable vars[index]
|
||||
** contains 2^(numVars-1) minterms. The rest are extracted
|
||||
** from a constant with 1 less variable.
|
||||
*/
|
||||
q = mintermsFromUniverse(manager,vars,numVars-1,(n-max2),index+1);
|
||||
if (q == NULL)
|
||||
return(NULL);
|
||||
cuddRef(q);
|
||||
result = cuddBddIteRecur(manager,vars[index],one,q);
|
||||
} else {
|
||||
/* When n < 2^(numVars-1), a literal of variable vars[index]
|
||||
** is selected. The required n minterms are extracted from a
|
||||
** constant with 1 less variable.
|
||||
*/
|
||||
q = mintermsFromUniverse(manager,vars,numVars-1,n,index+1);
|
||||
if (q == NULL)
|
||||
return(NULL);
|
||||
cuddRef(q);
|
||||
result = cuddBddAndRecur(manager,vars[index],q);
|
||||
/* When n < 2^(numVars-1), a literal of variable vars[index]
|
||||
** is selected. The required n minterms are extracted from a
|
||||
** constant with 1 less variable.
|
||||
*/
|
||||
q = mintermsFromUniverse(manager,vars,numVars-1,n,index+1);
|
||||
if (q == NULL)
|
||||
return(NULL);
|
||||
cuddRef(q);
|
||||
result = cuddBddAndRecur(manager,vars[index],q);
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(result);
|
||||
Cudd_RecursiveDeref(manager,q);
|
||||
|
|
@ -616,47 +646,49 @@ bddAnnotateMintermCount(
|
|||
statLine(manager);
|
||||
N = Cudd_Regular(node);
|
||||
if (cuddIsConstant(N)) {
|
||||
if (node == DD_ONE(manager)) {
|
||||
return(max);
|
||||
} else {
|
||||
return(0.0);
|
||||
}
|
||||
if (node == DD_ONE(manager)) {
|
||||
return(max);
|
||||
} else {
|
||||
return(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
if (st_lookup(table,(char *)node,(char **)&dummy)) {
|
||||
return(*dummy);
|
||||
}
|
||||
if (st_lookup(table, (const char *)node, (char **)&dummy)) {
|
||||
return(*dummy);
|
||||
}
|
||||
|
||||
Nv = cuddT(N);
|
||||
Nnv = cuddE(N);
|
||||
if (N != node) {
|
||||
Nv = Cudd_Not(Nv);
|
||||
Nnv = Cudd_Not(Nnv);
|
||||
Nv = Cudd_Not(Nv);
|
||||
Nnv = Cudd_Not(Nnv);
|
||||
}
|
||||
|
||||
/* Recur on the two branches. */
|
||||
min_v = bddAnnotateMintermCount(manager,Nv,max,table) / 2.0;
|
||||
if (min_v == (double)CUDD_OUT_OF_MEM)
|
||||
return ((double)CUDD_OUT_OF_MEM);
|
||||
return ((double)CUDD_OUT_OF_MEM);
|
||||
min_nv = bddAnnotateMintermCount(manager,Nnv,max,table) / 2.0;
|
||||
if (min_nv == (double)CUDD_OUT_OF_MEM)
|
||||
return ((double)CUDD_OUT_OF_MEM);
|
||||
return ((double)CUDD_OUT_OF_MEM);
|
||||
min_N = min_v + min_nv;
|
||||
|
||||
pmin = ABC_ALLOC(double,1);
|
||||
if (pmin == NULL) {
|
||||
manager->errorCode = CUDD_MEMORY_OUT;
|
||||
return((double)CUDD_OUT_OF_MEM);
|
||||
manager->errorCode = CUDD_MEMORY_OUT;
|
||||
return((double)CUDD_OUT_OF_MEM);
|
||||
}
|
||||
*pmin = min_N;
|
||||
|
||||
if (st_insert(table,(char *)node, (char *)pmin) == ST_OUT_OF_MEM) {
|
||||
ABC_FREE(pmin);
|
||||
return((double)CUDD_OUT_OF_MEM);
|
||||
ABC_FREE(pmin);
|
||||
return((double)CUDD_OUT_OF_MEM);
|
||||
}
|
||||
|
||||
return(min_N);
|
||||
|
||||
} /* end of bddAnnotateMintermCount */
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -7,39 +7,67 @@
|
|||
Synopsis [Procedures to count the number of minterms of a ZDD.]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_zddCount();
|
||||
<li> Cudd_zddCountDouble();
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddZddCountStep();
|
||||
<li> cuddZddCountDoubleStep();
|
||||
<li> st_zdd_count_dbl_free()
|
||||
<li> st_zdd_countfree()
|
||||
</ul>
|
||||
]
|
||||
<ul>
|
||||
<li> Cudd_zddCount();
|
||||
<li> Cudd_zddCountDouble();
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddZddCountStep();
|
||||
<li> cuddZddCountDoubleStep();
|
||||
<li> st_zdd_count_dbl_free()
|
||||
<li> st_zdd_countfree()
|
||||
</ul>
|
||||
]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
Author [Hyong-Kyoon Shin, In-Ho Moon]
|
||||
|
||||
Copyright [ This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -60,13 +88,16 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddZddCount.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddZddCount.c,v 1.14 2004/08/13 18:04:53 fabio Exp $";
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Macro declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**AutomaticStart*************************************************************/
|
||||
|
||||
|
|
@ -74,13 +105,16 @@ static char rcsid[] DD_UNUSED = "$Id: cuddZddCount.c,v 1.1.1.1 2003/02/24 22:23:
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static int cuddZddCountStep ARGS((DdNode *P, st_table *table, DdNode *base, DdNode *empty));
|
||||
static double cuddZddCountDoubleStep ARGS((DdNode *P, st_table *table, DdNode *base, DdNode *empty));
|
||||
static enum st_retval st_zdd_countfree ARGS((char *key, char *value, char *arg));
|
||||
static enum st_retval st_zdd_count_dbl_free ARGS((char *key, char *value, char *arg));
|
||||
static int cuddZddCountStep (DdNode *P, st_table *table, DdNode *base, DdNode *empty);
|
||||
static double cuddZddCountDoubleStep (DdNode *P, st_table *table, DdNode *base, DdNode *empty);
|
||||
static enum st_retval st_zdd_countfree (char *key, char *value, char *arg);
|
||||
static enum st_retval st_zdd_count_dbl_free (char *key, char *value, char *arg);
|
||||
|
||||
/**AutomaticEnd***************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Definition of exported functions */
|
||||
|
|
@ -105,8 +139,8 @@ Cudd_zddCount(
|
|||
DdNode * P)
|
||||
{
|
||||
st_table *table;
|
||||
int res;
|
||||
DdNode *base, *empty;
|
||||
int res;
|
||||
DdNode *base, *empty;
|
||||
|
||||
base = DD_ONE(zdd);
|
||||
empty = DD_ZERO(zdd);
|
||||
|
|
@ -114,9 +148,9 @@ Cudd_zddCount(
|
|||
if (table == NULL) return(CUDD_OUT_OF_MEM);
|
||||
res = cuddZddCountStep(P, table, base, empty);
|
||||
if (res == CUDD_OUT_OF_MEM) {
|
||||
zdd->errorCode = CUDD_MEMORY_OUT;
|
||||
zdd->errorCode = CUDD_MEMORY_OUT;
|
||||
}
|
||||
st_foreach(table, (ST_PFSR)st_zdd_countfree, NIL(char));
|
||||
st_foreach(table, st_zdd_countfree, NIL(char));
|
||||
st_free_table(table);
|
||||
|
||||
return(res);
|
||||
|
|
@ -144,8 +178,8 @@ Cudd_zddCountDouble(
|
|||
DdNode * P)
|
||||
{
|
||||
st_table *table;
|
||||
double res;
|
||||
DdNode *base, *empty;
|
||||
double res;
|
||||
DdNode *base, *empty;
|
||||
|
||||
base = DD_ONE(zdd);
|
||||
empty = DD_ZERO(zdd);
|
||||
|
|
@ -153,9 +187,9 @@ Cudd_zddCountDouble(
|
|||
if (table == NULL) return((double)CUDD_OUT_OF_MEM);
|
||||
res = cuddZddCountDoubleStep(P, table, base, empty);
|
||||
if (res == (double)CUDD_OUT_OF_MEM) {
|
||||
zdd->errorCode = CUDD_MEMORY_OUT;
|
||||
zdd->errorCode = CUDD_MEMORY_OUT;
|
||||
}
|
||||
st_foreach(table, (ST_PFSR)st_zdd_count_dbl_free, NIL(char));
|
||||
st_foreach(table, st_zdd_count_dbl_free, NIL(char));
|
||||
st_free_table(table);
|
||||
|
||||
return(res);
|
||||
|
|
@ -191,31 +225,31 @@ cuddZddCountStep(
|
|||
DdNode * base,
|
||||
DdNode * empty)
|
||||
{
|
||||
int res;
|
||||
int *dummy;
|
||||
int res;
|
||||
int *dummy;
|
||||
|
||||
if (P == empty)
|
||||
return(0);
|
||||
return(0);
|
||||
if (P == base)
|
||||
return(1);
|
||||
return(1);
|
||||
|
||||
/* Check cache. */
|
||||
if (st_lookup(table, (char *)P, (char **)(&dummy))) {
|
||||
res = *dummy;
|
||||
return(res);
|
||||
if (st_lookup(table, (const char *)P, (char **)&dummy)) {
|
||||
res = *dummy;
|
||||
return(res);
|
||||
}
|
||||
|
||||
res = cuddZddCountStep(cuddE(P), table, base, empty) +
|
||||
cuddZddCountStep(cuddT(P), table, base, empty);
|
||||
cuddZddCountStep(cuddT(P), table, base, empty);
|
||||
|
||||
dummy = ABC_ALLOC(int, 1);
|
||||
if (dummy == NULL) {
|
||||
return(CUDD_OUT_OF_MEM);
|
||||
return(CUDD_OUT_OF_MEM);
|
||||
}
|
||||
*dummy = res;
|
||||
if (st_insert(table, (char *)P, (char *)dummy) == ST_OUT_OF_MEM) {
|
||||
ABC_FREE(dummy);
|
||||
return(CUDD_OUT_OF_MEM);
|
||||
ABC_FREE(dummy);
|
||||
return(CUDD_OUT_OF_MEM);
|
||||
}
|
||||
|
||||
return(res);
|
||||
|
|
@ -241,31 +275,31 @@ cuddZddCountDoubleStep(
|
|||
DdNode * base,
|
||||
DdNode * empty)
|
||||
{
|
||||
double res;
|
||||
double *dummy;
|
||||
double res;
|
||||
double *dummy;
|
||||
|
||||
if (P == empty)
|
||||
return((double)0.0);
|
||||
return((double)0.0);
|
||||
if (P == base)
|
||||
return((double)1.0);
|
||||
return((double)1.0);
|
||||
|
||||
/* Check cache */
|
||||
if (st_lookup(table, (char *)P, (char **)(&dummy))) {
|
||||
res = *dummy;
|
||||
return(res);
|
||||
if (st_lookup(table, (const char *)P, (char **)&dummy)) {
|
||||
res = *dummy;
|
||||
return(res);
|
||||
}
|
||||
|
||||
res = cuddZddCountDoubleStep(cuddE(P), table, base, empty) +
|
||||
cuddZddCountDoubleStep(cuddT(P), table, base, empty);
|
||||
cuddZddCountDoubleStep(cuddT(P), table, base, empty);
|
||||
|
||||
dummy = ABC_ALLOC(double, 1);
|
||||
if (dummy == NULL) {
|
||||
return((double)CUDD_OUT_OF_MEM);
|
||||
return((double)CUDD_OUT_OF_MEM);
|
||||
}
|
||||
*dummy = res;
|
||||
if (st_insert(table, (char *)P, (char *)dummy) == ST_OUT_OF_MEM) {
|
||||
ABC_FREE(dummy);
|
||||
return((double)CUDD_OUT_OF_MEM);
|
||||
ABC_FREE(dummy);
|
||||
return((double)CUDD_OUT_OF_MEM);
|
||||
}
|
||||
|
||||
return(res);
|
||||
|
|
@ -291,7 +325,7 @@ st_zdd_countfree(
|
|||
char * value,
|
||||
char * arg)
|
||||
{
|
||||
int *d;
|
||||
int *d;
|
||||
|
||||
d = (int *)value;
|
||||
ABC_FREE(d);
|
||||
|
|
@ -318,12 +352,14 @@ st_zdd_count_dbl_free(
|
|||
char * value,
|
||||
char * arg)
|
||||
{
|
||||
double *d;
|
||||
double *d;
|
||||
|
||||
d = (double *)value;
|
||||
ABC_FREE(d);
|
||||
return(ST_CONTINUE);
|
||||
|
||||
} /* end of st_zdd_count_dbl_free */
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -4,41 +4,69 @@
|
|||
|
||||
PackageName [cudd]
|
||||
|
||||
Synopsis [.]
|
||||
Synopsis [Miscellaneous utility functions for ZDDs.]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_zddDagSize()
|
||||
<li> Cudd_zddCountMinterm()
|
||||
<li> Cudd_zddPrintSubtable()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddZddDagInt()
|
||||
</ul>
|
||||
]
|
||||
<ul>
|
||||
<li> Cudd_zddDagSize()
|
||||
<li> Cudd_zddCountMinterm()
|
||||
<li> Cudd_zddPrintSubtable()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> cuddZddDagInt()
|
||||
</ul>
|
||||
]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
Author [Hyong-Kyoon Shin, In-Ho Moon]
|
||||
|
||||
Copyright [ This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include <math.h>
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
#include <math.h>
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -59,7 +87,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddZddMisc.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddZddMisc.c,v 1.16 2009/02/20 02:14:58 fabio Exp $";
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -73,7 +101,7 @@ static char rcsid[] DD_UNUSED = "$Id: cuddZddMisc.c,v 1.1.1.1 2003/02/24 22:23:5
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static int cuddZddDagInt ARGS((DdNode *n, st_table *tab));
|
||||
static int cuddZddDagInt (DdNode *n, st_table *tab);
|
||||
|
||||
/**AutomaticEnd***************************************************************/
|
||||
|
||||
|
|
@ -100,7 +128,7 @@ Cudd_zddDagSize(
|
|||
DdNode * p_node)
|
||||
{
|
||||
|
||||
int i;
|
||||
int i;
|
||||
st_table *table;
|
||||
|
||||
table = st_init_table(st_ptrcmp, st_ptrhash);
|
||||
|
|
@ -132,7 +160,7 @@ Cudd_zddCountMinterm(
|
|||
DdNode * node,
|
||||
int path)
|
||||
{
|
||||
double dc_var, minterms;
|
||||
double dc_var, minterms;
|
||||
|
||||
dc_var = (double)((double)(zdd->sizeZ) - (double)path);
|
||||
minterms = Cudd_zddCountDouble(zdd, node) / pow(2.0, dc_var);
|
||||
|
|
@ -156,61 +184,61 @@ void
|
|||
Cudd_zddPrintSubtable(
|
||||
DdManager * table)
|
||||
{
|
||||
int i, j;
|
||||
DdNode *z1, *z1_next, *base;
|
||||
DdSubtable *ZSubTable;
|
||||
int i, j;
|
||||
DdNode *z1, *z1_next, *base;
|
||||
DdSubtable *ZSubTable;
|
||||
|
||||
base = table->one;
|
||||
for (i = table->sizeZ - 1; i >= 0; i--) {
|
||||
ZSubTable = &(table->subtableZ[i]);
|
||||
printf("subtable[%d]:\n", i);
|
||||
for (j = ZSubTable->slots - 1; j >= 0; j--) {
|
||||
z1 = ZSubTable->nodelist[j];
|
||||
while (z1 != NIL(DdNode)) {
|
||||
(void) fprintf(table->out,
|
||||
ZSubTable = &(table->subtableZ[i]);
|
||||
printf("subtable[%d]:\n", i);
|
||||
for (j = ZSubTable->slots - 1; j >= 0; j--) {
|
||||
z1 = ZSubTable->nodelist[j];
|
||||
while (z1 != NIL(DdNode)) {
|
||||
(void) fprintf(table->out,
|
||||
#if SIZEOF_VOID_P == 8
|
||||
"ID = 0x%lx\tindex = %d\tr = %d\t",
|
||||
(unsigned long) z1 / (unsigned long) sizeof(DdNode),
|
||||
z1->index, z1->ref);
|
||||
"ID = 0x%lx\tindex = %u\tr = %u\t",
|
||||
(ptruint) z1 / (ptruint) sizeof(DdNode),
|
||||
z1->index, z1->ref);
|
||||
#else
|
||||
"ID = 0x%x\tindex = %d\tr = %d\t",
|
||||
(unsigned) z1 / (unsigned) sizeof(DdNode),
|
||||
z1->index, z1->ref);
|
||||
"ID = 0x%x\tindex = %hu\tr = %hu\t",
|
||||
(ptruint) z1 / (ptruint) sizeof(DdNode),
|
||||
z1->index, z1->ref);
|
||||
#endif
|
||||
z1_next = cuddT(z1);
|
||||
if (Cudd_IsConstant(z1_next)) {
|
||||
(void) fprintf(table->out, "T = %d\t\t",
|
||||
(z1_next == base));
|
||||
}
|
||||
else {
|
||||
z1_next = cuddT(z1);
|
||||
if (Cudd_IsConstant(z1_next)) {
|
||||
(void) fprintf(table->out, "T = %d\t\t",
|
||||
(z1_next == base));
|
||||
}
|
||||
else {
|
||||
#if SIZEOF_VOID_P == 8
|
||||
(void) fprintf(table->out, "T = 0x%lx\t",
|
||||
(unsigned long) z1_next / (unsigned long) sizeof(DdNode));
|
||||
(void) fprintf(table->out, "T = 0x%lx\t",
|
||||
(ptruint) z1_next / (ptruint) sizeof(DdNode));
|
||||
#else
|
||||
(void) fprintf(table->out, "T = 0x%x\t",
|
||||
(unsigned) z1_next / (unsigned) sizeof(DdNode));
|
||||
(void) fprintf(table->out, "T = 0x%x\t",
|
||||
(ptruint) z1_next / (ptruint) sizeof(DdNode));
|
||||
#endif
|
||||
}
|
||||
z1_next = cuddE(z1);
|
||||
if (Cudd_IsConstant(z1_next)) {
|
||||
(void) fprintf(table->out, "E = %d\n",
|
||||
(z1_next == base));
|
||||
}
|
||||
else {
|
||||
}
|
||||
z1_next = cuddE(z1);
|
||||
if (Cudd_IsConstant(z1_next)) {
|
||||
(void) fprintf(table->out, "E = %d\n",
|
||||
(z1_next == base));
|
||||
}
|
||||
else {
|
||||
#if SIZEOF_VOID_P == 8
|
||||
(void) fprintf(table->out, "E = 0x%lx\n",
|
||||
(unsigned long) z1_next / (unsigned long) sizeof(DdNode));
|
||||
(void) fprintf(table->out, "E = 0x%lx\n",
|
||||
(ptruint) z1_next / (ptruint) sizeof(DdNode));
|
||||
#else
|
||||
(void) fprintf(table->out, "E = 0x%x\n",
|
||||
(unsigned) z1_next / (unsigned) sizeof(DdNode));
|
||||
(void) fprintf(table->out, "E = 0x%x\n",
|
||||
(ptruint) z1_next / (ptruint) sizeof(DdNode));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
z1_next = z1->next;
|
||||
z1 = z1_next;
|
||||
z1_next = z1->next;
|
||||
z1 = z1_next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
putchar('\n');
|
||||
|
||||
} /* Cudd_zddPrintSubtable */
|
||||
|
|
@ -239,19 +267,20 @@ cuddZddDagInt(
|
|||
st_table * tab)
|
||||
{
|
||||
if (n == NIL(DdNode))
|
||||
return(0);
|
||||
return(0);
|
||||
|
||||
if (st_is_member(tab, (char *)n) == 1)
|
||||
return(0);
|
||||
return(0);
|
||||
|
||||
if (Cudd_IsConstant(n))
|
||||
return(0);
|
||||
return(0);
|
||||
|
||||
(void)st_insert(tab, (char *)n, NIL(char));
|
||||
return(1 + cuddZddDagInt(cuddT(n), tab) +
|
||||
cuddZddDagInt(cuddE(n), tab));
|
||||
cuddZddDagInt(cuddE(n), tab));
|
||||
|
||||
} /* cuddZddDagInt */
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -7,37 +7,65 @@
|
|||
Synopsis [Functions that translate BDDs to ZDDs.]
|
||||
|
||||
Description [External procedures included in this module:
|
||||
<ul>
|
||||
<li> Cudd_zddPortFromBdd()
|
||||
<li> Cudd_zddPortToBdd()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> zddPortFromBddStep()
|
||||
<li> zddPortToBddStep()
|
||||
</ul>
|
||||
]
|
||||
<ul>
|
||||
<li> Cudd_zddPortFromBdd()
|
||||
<li> Cudd_zddPortToBdd()
|
||||
</ul>
|
||||
Internal procedures included in this module:
|
||||
<ul>
|
||||
</ul>
|
||||
Static procedures included in this module:
|
||||
<ul>
|
||||
<li> zddPortFromBddStep()
|
||||
<li> zddPortToBddStep()
|
||||
</ul>
|
||||
]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
Author [Hyong-kyoon Shin, In-Ho Moon]
|
||||
|
||||
Copyright [ This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
#include "util_hack.h"
|
||||
#include "cuddInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -58,7 +86,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddZddPort.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: cuddZddPort.c,v 1.13 2004/08/13 18:04:53 fabio Exp $";
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
@ -72,8 +100,8 @@ static char rcsid[] DD_UNUSED = "$Id: cuddZddPort.c,v 1.1.1.1 2003/02/24 22:23:5
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static DdNode * zddPortFromBddStep ARGS((DdManager *dd, DdNode *B, int expected));
|
||||
static DdNode * zddPortToBddStep ARGS((DdManager *dd, DdNode *f, int depth));
|
||||
static DdNode * zddPortFromBddStep (DdManager *dd, DdNode *B, int expected);
|
||||
static DdNode * zddPortToBddStep (DdManager *dd, DdNode *f, int depth);
|
||||
|
||||
/**AutomaticEnd***************************************************************/
|
||||
|
||||
|
|
@ -107,8 +135,8 @@ Cudd_zddPortFromBdd(
|
|||
DdNode *res;
|
||||
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = zddPortFromBddStep(dd,B,0);
|
||||
dd->reordered = 0;
|
||||
res = zddPortFromBddStep(dd,B,0);
|
||||
} while (dd->reordered == 1);
|
||||
|
||||
return(res);
|
||||
|
|
@ -136,8 +164,8 @@ Cudd_zddPortToBdd(
|
|||
DdNode *res;
|
||||
|
||||
do {
|
||||
dd->reordered = 0;
|
||||
res = zddPortToBddStep(dd,f,0);
|
||||
dd->reordered = 0;
|
||||
res = zddPortToBddStep(dd,f,0);
|
||||
} while (dd->reordered == 1);
|
||||
|
||||
return(res);
|
||||
|
|
@ -171,20 +199,20 @@ zddPortFromBddStep(
|
|||
DdNode * B,
|
||||
int expected)
|
||||
{
|
||||
DdNode *res, *prevZdd, *t, *e;
|
||||
DdNode *Breg, *Bt, *Be;
|
||||
int id, level;
|
||||
DdNode *res, *prevZdd, *t, *e;
|
||||
DdNode *Breg, *Bt, *Be;
|
||||
int id, level;
|
||||
|
||||
statLine(dd);
|
||||
/* Terminal cases. */
|
||||
if (B == Cudd_Not(DD_ONE(dd)))
|
||||
return(DD_ZERO(dd));
|
||||
return(DD_ZERO(dd));
|
||||
if (B == DD_ONE(dd)) {
|
||||
if (expected >= dd->sizeZ) {
|
||||
return(DD_ONE(dd));
|
||||
} else {
|
||||
return(dd->univ[expected]);
|
||||
}
|
||||
if (expected >= dd->sizeZ) {
|
||||
return(DD_ONE(dd));
|
||||
} else {
|
||||
return(dd->univ[expected]);
|
||||
}
|
||||
}
|
||||
|
||||
Breg = Cudd_Regular(B);
|
||||
|
|
@ -192,33 +220,33 @@ zddPortFromBddStep(
|
|||
/* Computed table look-up. */
|
||||
res = cuddCacheLookup1Zdd(dd,Cudd_zddPortFromBdd,B);
|
||||
if (res != NULL) {
|
||||
level = cuddI(dd,Breg->index);
|
||||
/* Adding DC vars. */
|
||||
if (expected < level) {
|
||||
/* Add suppressed variables. */
|
||||
cuddRef(res);
|
||||
for (level--; level >= expected; level--) {
|
||||
prevZdd = res;
|
||||
id = dd->invperm[level];
|
||||
res = cuddZddGetNode(dd, id, prevZdd, prevZdd);
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDerefZdd(dd, prevZdd);
|
||||
return(NULL);
|
||||
level = cuddI(dd,Breg->index);
|
||||
/* Adding DC vars. */
|
||||
if (expected < level) {
|
||||
/* Add suppressed variables. */
|
||||
cuddRef(res);
|
||||
for (level--; level >= expected; level--) {
|
||||
prevZdd = res;
|
||||
id = dd->invperm[level];
|
||||
res = cuddZddGetNode(dd, id, prevZdd, prevZdd);
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDerefZdd(dd, prevZdd);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDerefZdd(dd, prevZdd);
|
||||
}
|
||||
cuddDeref(res);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDerefZdd(dd, prevZdd);
|
||||
}
|
||||
cuddDeref(res);
|
||||
}
|
||||
return(res);
|
||||
} /* end of cache look-up */
|
||||
return(res);
|
||||
} /* end of cache look-up */
|
||||
|
||||
if (Cudd_IsComplement(B)) {
|
||||
Bt = Cudd_Not(cuddT(Breg));
|
||||
Be = Cudd_Not(cuddE(Breg));
|
||||
Bt = Cudd_Not(cuddT(Breg));
|
||||
Be = Cudd_Not(cuddE(Breg));
|
||||
} else {
|
||||
Bt = cuddT(Breg);
|
||||
Be = cuddE(Breg);
|
||||
Bt = cuddT(Breg);
|
||||
Be = cuddE(Breg);
|
||||
}
|
||||
|
||||
id = Breg->index;
|
||||
|
|
@ -228,15 +256,15 @@ zddPortFromBddStep(
|
|||
cuddRef(t);
|
||||
e = zddPortFromBddStep(dd, Be, level+1);
|
||||
if (e == NULL) {
|
||||
Cudd_RecursiveDerefZdd(dd, t);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDerefZdd(dd, t);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(e);
|
||||
res = cuddZddGetNode(dd, id, t, e);
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDerefZdd(dd, t);
|
||||
Cudd_RecursiveDerefZdd(dd, e);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDerefZdd(dd, t);
|
||||
Cudd_RecursiveDerefZdd(dd, e);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDerefZdd(dd, t);
|
||||
|
|
@ -245,15 +273,15 @@ zddPortFromBddStep(
|
|||
cuddCacheInsert1(dd,Cudd_zddPortFromBdd,B,res);
|
||||
|
||||
for (level--; level >= expected; level--) {
|
||||
prevZdd = res;
|
||||
id = dd->invperm[level];
|
||||
res = cuddZddGetNode(dd, id, prevZdd, prevZdd);
|
||||
if (res == NULL) {
|
||||
prevZdd = res;
|
||||
id = dd->invperm[level];
|
||||
res = cuddZddGetNode(dd, id, prevZdd, prevZdd);
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDerefZdd(dd, prevZdd);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDerefZdd(dd, prevZdd);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDerefZdd(dd, prevZdd);
|
||||
}
|
||||
|
||||
cuddDeref(res);
|
||||
|
|
@ -297,51 +325,51 @@ zddPortToBddStep(
|
|||
cuddRef(var);
|
||||
|
||||
if (level > (unsigned) depth) {
|
||||
E = zddPortToBddStep(dd,f,depth+1);
|
||||
if (E == NULL) {
|
||||
Cudd_RecursiveDeref(dd,var);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(E);
|
||||
res = cuddBddIteRecur(dd,var,Cudd_Not(one),E);
|
||||
if (res == NULL) {
|
||||
E = zddPortToBddStep(dd,f,depth+1);
|
||||
if (E == NULL) {
|
||||
Cudd_RecursiveDeref(dd,var);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(E);
|
||||
res = cuddBddIteRecur(dd,var,Cudd_Not(one),E);
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDeref(dd,var);
|
||||
Cudd_RecursiveDeref(dd,E);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDeref(dd,var);
|
||||
Cudd_RecursiveDeref(dd,E);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDeref(dd,var);
|
||||
Cudd_RecursiveDeref(dd,E);
|
||||
cuddDeref(res);
|
||||
return(res);
|
||||
cuddDeref(res);
|
||||
return(res);
|
||||
}
|
||||
|
||||
res = cuddCacheLookup1(dd,Cudd_zddPortToBdd,f);
|
||||
if (res != NULL) {
|
||||
Cudd_RecursiveDeref(dd,var);
|
||||
return(res);
|
||||
Cudd_RecursiveDeref(dd,var);
|
||||
return(res);
|
||||
}
|
||||
|
||||
T = zddPortToBddStep(dd,cuddT(f),depth+1);
|
||||
if (T == NULL) {
|
||||
Cudd_RecursiveDeref(dd,var);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(dd,var);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(T);
|
||||
E = zddPortToBddStep(dd,cuddE(f),depth+1);
|
||||
if (E == NULL) {
|
||||
Cudd_RecursiveDeref(dd,var);
|
||||
Cudd_RecursiveDeref(dd,T);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(dd,var);
|
||||
Cudd_RecursiveDeref(dd,T);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(E);
|
||||
|
||||
res = cuddBddIteRecur(dd,var,T,E);
|
||||
if (res == NULL) {
|
||||
Cudd_RecursiveDeref(dd,var);
|
||||
Cudd_RecursiveDeref(dd,T);
|
||||
Cudd_RecursiveDeref(dd,E);
|
||||
return(NULL);
|
||||
Cudd_RecursiveDeref(dd,var);
|
||||
Cudd_RecursiveDeref(dd,T);
|
||||
Cudd_RecursiveDeref(dd,E);
|
||||
return(NULL);
|
||||
}
|
||||
cuddRef(res);
|
||||
Cudd_RecursiveDeref(dd,var);
|
||||
|
|
@ -355,5 +383,7 @@ zddPortToBddStep(
|
|||
|
||||
} /* end of zddPortToBddStep */
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,377 @@
|
|||
# TestCudd Version #1.0, Release date 3/17/01
|
||||
# ./testcudd -p 2 r7x8.1.mat
|
||||
:name: r7x8.1.mat: 7 rows 9 columns
|
||||
:1: M: 63 nodes 5 leaves 52 minterms
|
||||
000000-- 1
|
||||
000001-0 1
|
||||
000001-1 4
|
||||
000010-0 4
|
||||
000010-1 3
|
||||
000011-0 2
|
||||
000011-1 4
|
||||
000100-- 3
|
||||
000101-0 3
|
||||
000110-0 1
|
||||
000110-1 2
|
||||
000111-0 4
|
||||
001000-- 1
|
||||
001001-0 4
|
||||
001010-0 2
|
||||
001010-1 1
|
||||
001011-1 4
|
||||
001100-0 2
|
||||
001100-1 3
|
||||
001101-0 3
|
||||
001110-0 4
|
||||
001110-1 1
|
||||
0100-0-0 3
|
||||
011000-0 3
|
||||
011010-0 1
|
||||
100000-0 2
|
||||
100000-1 3
|
||||
100001-0 2
|
||||
100001-1 4
|
||||
100010-- 3
|
||||
100011-- 4
|
||||
100100-- 1
|
||||
100101-0 2
|
||||
100110-0 1
|
||||
100110-1 3
|
||||
100111-0 3
|
||||
101000-1 1
|
||||
101001-0 1
|
||||
101001-1 4
|
||||
101100-0 2
|
||||
101100-1 4
|
||||
101101-0 4
|
||||
110000-0 2
|
||||
110010-0 4
|
||||
111000-0 2
|
||||
|
||||
:2: time to read the matrix = 0.00 sec
|
||||
:3: C: 22 nodes 1 leaves 52 minterms
|
||||
0000---- 1
|
||||
0001-0-- 1
|
||||
0001-1-0 1
|
||||
001000-- 1
|
||||
001001-0 1
|
||||
001010-- 1
|
||||
001011-1 1
|
||||
001100-- 1
|
||||
001101-0 1
|
||||
001110-- 1
|
||||
01-0-0-0 1
|
||||
1000---- 1
|
||||
1001-0-- 1
|
||||
1001-1-0 1
|
||||
101000-1 1
|
||||
101001-- 1
|
||||
101100-- 1
|
||||
101101-0 1
|
||||
1100-0-0 1
|
||||
111000-0 1
|
||||
|
||||
Testing iterator on cubes:
|
||||
000000-- 1
|
||||
000001-0 1
|
||||
000001-1 4
|
||||
000010-0 4
|
||||
000010-1 3
|
||||
000011-0 2
|
||||
000011-1 4
|
||||
000100-- 3
|
||||
000101-0 3
|
||||
000110-0 1
|
||||
000110-1 2
|
||||
000111-0 4
|
||||
001000-- 1
|
||||
001001-0 4
|
||||
001010-0 2
|
||||
001010-1 1
|
||||
001011-1 4
|
||||
001100-0 2
|
||||
001100-1 3
|
||||
001101-0 3
|
||||
001110-0 4
|
||||
001110-1 1
|
||||
0100-0-0 3
|
||||
011000-0 3
|
||||
011010-0 1
|
||||
100000-0 2
|
||||
100000-1 3
|
||||
100001-0 2
|
||||
100001-1 4
|
||||
100010-- 3
|
||||
100011-- 4
|
||||
100100-- 1
|
||||
100101-0 2
|
||||
100110-0 1
|
||||
100110-1 3
|
||||
100111-0 3
|
||||
101000-1 1
|
||||
101001-0 1
|
||||
101001-1 4
|
||||
101100-0 2
|
||||
101100-1 4
|
||||
101101-0 4
|
||||
110000-0 2
|
||||
110010-0 4
|
||||
111000-0 2
|
||||
|
||||
Testing prime expansion of cubes:
|
||||
-000---- 1
|
||||
-00--0-- 1
|
||||
0--0-0-0 1
|
||||
--00-0-0 1
|
||||
-0-100-- 1
|
||||
10-001-- 1
|
||||
-00----0 1
|
||||
00---0-- 1
|
||||
-1-000-0 1
|
||||
-0--01-0 1
|
||||
-0--00-1 1
|
||||
00-01--1 1
|
||||
|
||||
Testing iterator on primes (CNF):
|
||||
-0-0---- 1
|
||||
-0---0-- 1
|
||||
0-0-0--- 1
|
||||
-0-----0 1
|
||||
---0-0-0 1
|
||||
0101-1-1 1
|
||||
--0-00-1 1
|
||||
1-0-10-0 1
|
||||
|
||||
Cache used slots = 58.06% (expected 58.92%)
|
||||
xor1: 14 nodes 1 leaves 28 minterms
|
||||
000--1-1 1
|
||||
001-11-1 1
|
||||
01---0-0 1
|
||||
100--1-1 1
|
||||
101-00-0 1
|
||||
101-01-1 1
|
||||
110--0-0 1
|
||||
111-00-0 1
|
||||
|
||||
Chosen minterm for Hamming distance test: : 9 nodes 1 leaves 1 minterms
|
||||
11110010 1
|
||||
|
||||
Minimum Hamming distance = 1
|
||||
ycube: 5 nodes 1 leaves 8 minterms
|
||||
-0-0-0-0 1
|
||||
|
||||
CP: 11 nodes 1 leaves 7 minterms
|
||||
00-0-0-0 1
|
||||
1000-0-0 1
|
||||
101000-1 1
|
||||
|
||||
:4: ineq: 10 nodes 1 leaves 42 minterms
|
||||
001000-- 1
|
||||
00101--- 1
|
||||
1000---- 1
|
||||
100100-- 1
|
||||
10011--- 1
|
||||
101----- 1
|
||||
111000-- 1
|
||||
11101--- 1
|
||||
|
||||
10------ 1
|
||||
-01----- 1
|
||||
1-1----- 1
|
||||
-0-0---- 1
|
||||
1--0---- 1
|
||||
-0--10-- 1
|
||||
--1010-- 1
|
||||
1---10-- 1
|
||||
|
||||
:4: ess: 1 nodes 1 leaves 128 minterms
|
||||
-------- 1
|
||||
|
||||
:5: shortP: 7 nodes 1 leaves 2 minterms
|
||||
000000-- 1
|
||||
|
||||
:5b: largest: 4 nodes 1 leaves 16 minterms
|
||||
01-1---- 1
|
||||
|
||||
The value of M along the chosen shortest path is 1
|
||||
:6: shortP: 5 nodes 1 leaves 8 minterms
|
||||
0000---- 1
|
||||
|
||||
Average distance: 4133.34
|
||||
Number of variables = 8 Number of slots = 2304
|
||||
Number of keys = 995 Number of min dead = 9216
|
||||
walsh1: 16 nodes 2 leaves 256 minterms
|
||||
-0--0--0--0- 1
|
||||
-0--0--0--10 1
|
||||
-0--0--0--11 -1
|
||||
-0--0--10-0- 1
|
||||
-0--0--10-10 1
|
||||
-0--0--10-11 -1
|
||||
-0--0--11-0- -1
|
||||
-0--0--11-10 -1
|
||||
-0--0--11-11 1
|
||||
-0--10-0--0- 1
|
||||
-0--10-0--10 1
|
||||
-0--10-0--11 -1
|
||||
-0--10-10-0- 1
|
||||
-0--10-10-10 1
|
||||
-0--10-10-11 -1
|
||||
-0--10-11-0- -1
|
||||
-0--10-11-10 -1
|
||||
-0--10-11-11 1
|
||||
-0--11-0--0- -1
|
||||
-0--11-0--10 -1
|
||||
-0--11-0--11 1
|
||||
-0--11-10-0- -1
|
||||
-0--11-10-10 -1
|
||||
-0--11-10-11 1
|
||||
-0--11-11-0- 1
|
||||
-0--11-11-10 1
|
||||
-0--11-11-11 -1
|
||||
-10-0--0--0- 1
|
||||
-10-0--0--10 1
|
||||
-10-0--0--11 -1
|
||||
-10-0--10-0- 1
|
||||
-10-0--10-10 1
|
||||
-10-0--10-11 -1
|
||||
-10-0--11-0- -1
|
||||
-10-0--11-10 -1
|
||||
-10-0--11-11 1
|
||||
-10-10-0--0- 1
|
||||
-10-10-0--10 1
|
||||
-10-10-0--11 -1
|
||||
-10-10-10-0- 1
|
||||
-10-10-10-10 1
|
||||
-10-10-10-11 -1
|
||||
-10-10-11-0- -1
|
||||
-10-10-11-10 -1
|
||||
-10-10-11-11 1
|
||||
-10-11-0--0- -1
|
||||
-10-11-0--10 -1
|
||||
-10-11-0--11 1
|
||||
-10-11-10-0- -1
|
||||
-10-11-10-10 -1
|
||||
-10-11-10-11 1
|
||||
-10-11-11-0- 1
|
||||
-10-11-11-10 1
|
||||
-10-11-11-11 -1
|
||||
-11-0--0--0- -1
|
||||
-11-0--0--10 -1
|
||||
-11-0--0--11 1
|
||||
-11-0--10-0- -1
|
||||
-11-0--10-10 -1
|
||||
-11-0--10-11 1
|
||||
-11-0--11-0- 1
|
||||
-11-0--11-10 1
|
||||
-11-0--11-11 -1
|
||||
-11-10-0--0- -1
|
||||
-11-10-0--10 -1
|
||||
-11-10-0--11 1
|
||||
-11-10-10-0- -1
|
||||
-11-10-10-10 -1
|
||||
-11-10-10-11 1
|
||||
-11-10-11-0- 1
|
||||
-11-10-11-10 1
|
||||
-11-10-11-11 -1
|
||||
-11-11-0--0- 1
|
||||
-11-11-0--10 1
|
||||
-11-11-0--11 -1
|
||||
-11-11-10-0- 1
|
||||
-11-11-10-10 1
|
||||
-11-11-10-11 -1
|
||||
-11-11-11-0- -1
|
||||
-11-11-11-10 -1
|
||||
-11-11-11-11 1
|
||||
|
||||
wtw: 14 nodes 2 leaves 16 minterms
|
||||
0-00-00-00-0 16
|
||||
0-00-00-01-1 16
|
||||
0-00-01-10-0 16
|
||||
0-00-01-11-1 16
|
||||
0-01-10-00-0 16
|
||||
0-01-10-01-1 16
|
||||
0-01-11-10-0 16
|
||||
0-01-11-11-1 16
|
||||
1-10-00-00-0 16
|
||||
1-10-00-01-1 16
|
||||
1-10-01-10-0 16
|
||||
1-10-01-11-1 16
|
||||
1-11-10-00-0 16
|
||||
1-11-10-01-1 16
|
||||
1-11-11-10-0 16
|
||||
1-11-11-11-1 16
|
||||
|
||||
Average length of non-empty lists = 1
|
||||
**** CUDD modifiable parameters ****
|
||||
Hard limit for cache size: 7645866
|
||||
Cache hit threshold for resizing: 30%
|
||||
Garbage collection enabled: yes
|
||||
Limit for fast unique table growth: 4587520
|
||||
Maximum number of variables sifted per reordering: 1000
|
||||
Maximum number of variable swaps per reordering: 2000000
|
||||
Maximum growth while sifting a variable: 1.2
|
||||
Dynamic reordering of BDDs enabled: no
|
||||
Default BDD reordering method: 4
|
||||
Dynamic reordering of ZDDs enabled: no
|
||||
Default ZDD reordering method: 4
|
||||
Realignment of ZDDs to BDDs enabled: no
|
||||
Realignment of BDDs to ZDDs enabled: no
|
||||
Dead nodes counted in triggering reordering: no
|
||||
Group checking criterion: 7
|
||||
Recombination threshold: 0
|
||||
Symmetry violation threshold: 0
|
||||
Arc violation threshold: 0
|
||||
GA population size: 0
|
||||
Number of crossovers for GA: 0
|
||||
Next reordering threshold: 4004
|
||||
**** CUDD non-modifiable parameters ****
|
||||
Memory in use: 4274484
|
||||
Peak number of nodes: 2044
|
||||
Peak number of live nodes: 119
|
||||
Number of BDD variables: 9
|
||||
Number of ZDD variables: 0
|
||||
Number of cache entries: 2048
|
||||
Number of cache look-ups: 2846
|
||||
Number of cache hits: 715
|
||||
Number of cache insertions: 2289
|
||||
Number of cache collisions: 937
|
||||
Number of cache deletions: 1348
|
||||
Cache used slots = 66.02% (expected 67.30%)
|
||||
Soft limit for cache size: 13312
|
||||
Number of buckets in unique table: 2560
|
||||
Used buckets in unique table: 0.51% (expected 0.51%)
|
||||
Number of BDD and ADD nodes: 13
|
||||
Number of ZDD nodes: 0
|
||||
Number of dead BDD and ADD nodes: 0
|
||||
Number of dead ZDD nodes: 0
|
||||
Total number of nodes allocated: 1091
|
||||
Total number of nodes reclaimed: 950
|
||||
Garbage collections so far: 1
|
||||
Time for garbage collection: 0.00 sec
|
||||
Reorderings so far: 0
|
||||
Time for reordering: 0.00 sec
|
||||
total time = 0.00 sec
|
||||
Runtime Statistics
|
||||
------------------
|
||||
Machine name: jobim.colorado.edu
|
||||
User time 0.0 seconds
|
||||
System time 0.0 seconds
|
||||
|
||||
Average resident text size = 0K
|
||||
Average resident data+stack size = 0K
|
||||
Maximum resident size = 0K
|
||||
|
||||
Virtual text size = 131644K
|
||||
Virtual data size = 151K
|
||||
data size initialized = 17K
|
||||
data size uninitialized = 0K
|
||||
data size sbrk = 134K
|
||||
Virtual memory limit = 358400K (4194304K)
|
||||
|
||||
Major page faults = 0
|
||||
Minor page faults = 1318
|
||||
Swaps = 0
|
||||
Input blocks = 0
|
||||
Output blocks = 0
|
||||
Context switch (voluntary) = 1
|
||||
Context switch (involuntary) = 1
|
||||
|
|
@ -16,19 +16,43 @@
|
|||
|
||||
Author [Fabio Somenzi]
|
||||
|
||||
Copyright [ This file was created at the University of Colorado at
|
||||
Boulder. The University of Colorado at Boulder makes no warranty
|
||||
about the suitability of this software for any purpose. It is
|
||||
presented on an AS IS basis.]
|
||||
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the University of Colorado nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.]
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "util_hack.h"
|
||||
#include "util.h"
|
||||
#include "cuddInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constant declarations */
|
||||
|
|
@ -41,10 +65,10 @@ ABC_NAMESPACE_IMPL_START
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] DD_UNUSED = "$Id: testcudd.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $";
|
||||
static char rcsid[] DD_UNUSED = "$Id: testcudd.c,v 1.20 2009/03/08 02:49:02 fabio Exp $";
|
||||
#endif
|
||||
|
||||
static char *onames[] = { "C", "M" }; /* names of functions to be dumped */
|
||||
static const char *onames[] = { "C", "M" }; /* names of functions to be dumped */
|
||||
|
||||
/**AutomaticStart*************************************************************/
|
||||
|
||||
|
|
@ -52,12 +76,12 @@ static char *onames[] = { "C", "M" }; /* names of functions to be dumped */
|
|||
/* Static function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static void usage ARGS((char * prog));
|
||||
static FILE *open_file ARGS((char *filename, char *mode));
|
||||
static int testIterators ARGS((DdManager *dd, DdNode *M, DdNode *C, int pr));
|
||||
static int testXor ARGS((DdManager *dd, DdNode *f, int pr, int nvars));
|
||||
static int testHamming ARGS((DdManager *dd, DdNode *f, int pr, int nvars));
|
||||
static int testWalsh ARGS((DdManager *dd, int N, int cmu, int approach, int pr));
|
||||
static void usage (char * prog);
|
||||
static FILE *open_file (char *filename, const char *mode);
|
||||
static int testIterators (DdManager *dd, DdNode *M, DdNode *C, int pr);
|
||||
static int testXor (DdManager *dd, DdNode *f, int pr, int nvars);
|
||||
static int testHamming (DdManager *dd, DdNode *f, int pr);
|
||||
static int testWalsh (DdManager *dd, int N, int cmu, int approach, int pr);
|
||||
|
||||
/**AutomaticEnd***************************************************************/
|
||||
|
||||
|
|
@ -77,17 +101,17 @@ int
|
|||
main(int argc, char **argv)
|
||||
{
|
||||
FILE *fp; /* pointer to input file */
|
||||
char *file = ""; /* input file name */
|
||||
char *file = (char *) ""; /* input file name */
|
||||
FILE *dfp = NULL; /* pointer to dump file */
|
||||
char *dfile; /* file for DD dump */
|
||||
DdNode *dfunc[2]; /* addresses of the functions to be dumped */
|
||||
DdManager *dd; /* pointer to DD manager */
|
||||
DdNode *one, *zero; /* fast access to constant functions */
|
||||
DdNode *one; /* fast access to constant function */
|
||||
DdNode *M;
|
||||
DdNode **x; /* pointers to variables */
|
||||
DdNode **y; /* pointers to variables */
|
||||
DdNode **xn; /* complements of row variables */
|
||||
DdNode **yn_; /* complements of column variables */
|
||||
DdNode **xn; /* complements of row variables */
|
||||
DdNode **yn_; /* complements of column variables */
|
||||
DdNode **xvars;
|
||||
DdNode **yvars;
|
||||
DdNode *C; /* result of converting from ADD to BDD */
|
||||
|
|
@ -149,7 +173,7 @@ main(int argc, char **argv)
|
|||
blifOrDot = 0; /* dot format */
|
||||
|
||||
/* Parse command line. */
|
||||
while ((c = util_getopt(argc, argv, "CDHMPS:a:bcd:g:hkmn:p:v:x:X:"))
|
||||
while ((c = util_getopt(argc, argv, (char *) "CDHMPS:a:bcd:g:hkmn:p:v:x:X:"))
|
||||
!= EOF) {
|
||||
switch(c) {
|
||||
case 'C':
|
||||
|
|
@ -216,7 +240,7 @@ main(int argc, char **argv)
|
|||
}
|
||||
|
||||
if (argc - util_optind == 0) {
|
||||
file = "-";
|
||||
file = (char *) "-";
|
||||
} else if (argc - util_optind == 1) {
|
||||
file = argv[util_optind];
|
||||
} else {
|
||||
|
|
@ -241,7 +265,6 @@ main(int argc, char **argv)
|
|||
/* Initialize manager and provide easy reference to terminals. */
|
||||
dd = Cudd_Init(nvars,0,nslots,cacheSize,maxMemory);
|
||||
one = DD_ONE(dd);
|
||||
zero = DD_ZERO(dd);
|
||||
dd->groupcheck = (Cudd_AggregationType) groupcheck;
|
||||
if (autodyn) Cudd_AutodynEnable(dd,CUDD_REORDER_SAME);
|
||||
|
||||
|
|
@ -335,7 +358,7 @@ main(int argc, char **argv)
|
|||
if (retval == 0) exit(2);
|
||||
|
||||
/* Test Hamming distance functions. */
|
||||
retval = testHamming(dd,C,pr,nx+ny);
|
||||
retval = testHamming(dd,C,pr);
|
||||
if (retval == 0) exit(2);
|
||||
|
||||
/* Test selection functions. */
|
||||
|
|
@ -356,6 +379,43 @@ main(int argc, char **argv)
|
|||
}
|
||||
Cudd_RecursiveDeref(dd, CPr);
|
||||
}
|
||||
|
||||
/* Test inequality generator. */
|
||||
{
|
||||
int Nmin = ddMin(nx,ny);
|
||||
int q;
|
||||
DdGen *gen;
|
||||
int *cube;
|
||||
DdNode *f = Cudd_Inequality(dd,Nmin,2,xvars,yvars);
|
||||
if (f == NULL) exit(2);
|
||||
Cudd_Ref(f);
|
||||
if (pr>0) {
|
||||
(void) printf(":4: ineq");
|
||||
Cudd_PrintDebug(dd,f,nx+ny,pr);
|
||||
if (pr>1) {
|
||||
Cudd_ForeachPrime(dd,Cudd_Not(f),Cudd_Not(f),gen,cube) {
|
||||
for (q = 0; q < dd->size; q++) {
|
||||
switch (cube[q]) {
|
||||
case 0:
|
||||
(void) printf("1");
|
||||
break;
|
||||
case 1:
|
||||
(void) printf("0");
|
||||
break;
|
||||
case 2:
|
||||
(void) printf("-");
|
||||
break;
|
||||
default:
|
||||
(void) printf("?");
|
||||
}
|
||||
}
|
||||
(void) printf(" 1\n");
|
||||
}
|
||||
(void) printf("\n");
|
||||
}
|
||||
}
|
||||
Cudd_IterDerefBdd(dd, f);
|
||||
}
|
||||
FREE(xvars); FREE(yvars);
|
||||
|
||||
Cudd_RecursiveDeref(dd, CP);
|
||||
|
|
@ -419,7 +479,7 @@ main(int argc, char **argv)
|
|||
}
|
||||
|
||||
/* Reorder if so requested. */
|
||||
if (approach != CUDD_REORDER_NONE) {
|
||||
if (approach != CUDD_REORDER_NONE) {
|
||||
#ifndef DD_STATS
|
||||
retval = Cudd_EnableReorderingReporting(dd);
|
||||
if (retval == 0) {
|
||||
|
|
@ -502,9 +562,10 @@ main(int argc, char **argv)
|
|||
dfunc[1] = M;
|
||||
if (blifOrDot == 1) {
|
||||
/* Only dump C because blif cannot handle ADDs */
|
||||
retval = Cudd_DumpBlif(dd,1,dfunc,NULL,onames,NULL,dfp);
|
||||
retval = Cudd_DumpBlif(dd,1,dfunc,NULL,(char **)onames,
|
||||
NULL,dfp,0);
|
||||
} else {
|
||||
retval = Cudd_DumpDot(dd,2,dfunc,NULL,onames,dfp);
|
||||
retval = Cudd_DumpDot(dd,2,dfunc,NULL,(char **)onames,dfp);
|
||||
}
|
||||
if (retval != 1) {
|
||||
(void) fprintf(stderr,"abnormal termination\n");
|
||||
|
|
@ -524,9 +585,9 @@ main(int argc, char **argv)
|
|||
}
|
||||
if (pr>0) {
|
||||
(void) printf("Number of variables = %6d\t",dd->size);
|
||||
(void) printf("Number of slots = %6d\n",dd->slots);
|
||||
(void) printf("Number of keys = %6d\t",dd->keys);
|
||||
(void) printf("Number of min dead = %6d\n",dd->minDead);
|
||||
(void) printf("Number of slots = %6u\n",dd->slots);
|
||||
(void) printf("Number of keys = %6u\t",dd->keys);
|
||||
(void) printf("Number of min dead = %6u\n",dd->minDead);
|
||||
}
|
||||
|
||||
} while (multiple && !feof(fp));
|
||||
|
|
@ -643,15 +704,15 @@ usage(char *prog)
|
|||
|
||||
******************************************************************************/
|
||||
static FILE *
|
||||
open_file(char *filename, char *mode)
|
||||
open_file(char *filename, const char *mode)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
if (strcmp(filename, "-") == 0) {
|
||||
return mode[0] == 'r' ? stdin : stdout;
|
||||
return mode[0] == 'r' ? stdin : stdout;
|
||||
} else if ((fp = fopen(filename, mode)) == NULL) {
|
||||
perror(filename);
|
||||
exit(1);
|
||||
perror(filename);
|
||||
exit(1);
|
||||
}
|
||||
return fp;
|
||||
|
||||
|
|
@ -798,34 +859,56 @@ testIterators(
|
|||
if (!Cudd_bddPrintCover(dd,C,C)) return(0);
|
||||
}
|
||||
|
||||
if (pr>1) {
|
||||
(void) printf("Testing iterator on primes (CNF):\n");
|
||||
Cudd_ForeachPrime(dd,Cudd_Not(C),Cudd_Not(C),gen,cube) {
|
||||
for (q = 0; q < dd->size; q++) {
|
||||
switch (cube[q]) {
|
||||
case 0:
|
||||
(void) printf("1");
|
||||
break;
|
||||
case 1:
|
||||
(void) printf("0");
|
||||
break;
|
||||
case 2:
|
||||
(void) printf("-");
|
||||
break;
|
||||
default:
|
||||
(void) printf("?");
|
||||
}
|
||||
}
|
||||
(void) printf(" 1\n");
|
||||
}
|
||||
(void) printf("\n");
|
||||
}
|
||||
|
||||
/* Test iterator on nodes. */
|
||||
if (pr>2) {
|
||||
DdGen *gen;
|
||||
DdNode *node;
|
||||
(void) printf("Testing iterator on nodes:\n");
|
||||
Cudd_ForeachNode(dd,M,gen,node) {
|
||||
if (Cudd_IsConstant(node)) {
|
||||
#if SIZEOF_VOID_P == 8
|
||||
(void) printf("ID = 0x%lx\tvalue = %-9g\n",
|
||||
(unsigned long) node /
|
||||
(unsigned long) sizeof(DdNode),
|
||||
(ptruint) node /
|
||||
(ptruint) sizeof(DdNode),
|
||||
Cudd_V(node));
|
||||
#else
|
||||
(void) printf("ID = 0x%x\tvalue = %-9g\n",
|
||||
(unsigned int) node /
|
||||
(unsigned int) sizeof(DdNode),
|
||||
(ptruint) node /
|
||||
(ptruint) sizeof(DdNode),
|
||||
Cudd_V(node));
|
||||
#endif
|
||||
} else {
|
||||
#if SIZEOF_VOID_P == 8
|
||||
(void) printf("ID = 0x%lx\tindex = %d\tr = %d\n",
|
||||
(unsigned long) node /
|
||||
(unsigned long) sizeof(DdNode),
|
||||
(void) printf("ID = 0x%lx\tindex = %u\tr = %u\n",
|
||||
(ptruint) node /
|
||||
(ptruint) sizeof(DdNode),
|
||||
node->index, node->ref);
|
||||
#else
|
||||
(void) printf("ID = 0x%x\tindex = %d\tr = %d\n",
|
||||
(unsigned int) node /
|
||||
(unsigned int) sizeof(DdNode),
|
||||
(void) printf("ID = 0x%x\tindex = %u\tr = %u\n",
|
||||
(ptruint) node /
|
||||
(ptruint) sizeof(DdNode),
|
||||
node->index, node->ref);
|
||||
#endif
|
||||
}
|
||||
|
|
@ -932,8 +1015,7 @@ static int
|
|||
testHamming(
|
||||
DdManager *dd,
|
||||
DdNode *f,
|
||||
int pr,
|
||||
int nvars)
|
||||
int pr)
|
||||
{
|
||||
DdNode **vars, *minBdd, *zero, *scan;
|
||||
int i;
|
||||
|
|
@ -989,5 +1071,3 @@ testHamming(
|
|||
return(1);
|
||||
|
||||
} /* end of testHamming */
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue