You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
318 lines
10 KiB
318 lines
10 KiB
/**CFile***********************************************************************
|
|
|
|
FileName [cuddSign.c]
|
|
|
|
PackageName [cudd]
|
|
|
|
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>
|
|
]
|
|
|
|
Author [Fabio Somenzi]
|
|
|
|
Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado
|
|
|
|
All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions
|
|
are met:
|
|
|
|
Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in the
|
|
documentation and/or other materials provided with the distribution.
|
|
|
|
Neither the name of the University of Colorado nor the names of its
|
|
contributors may be used to endorse or promote products derived from
|
|
this software without specific prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
POSSIBILITY OF SUCH DAMAGE.]
|
|
|
|
******************************************************************************/
|
|
|
|
#include "util.h"
|
|
#include "cuddInt.h"
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Constant declarations */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Stucture declarations */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Type declarations */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Variable declarations */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
#ifndef lint
|
|
static char rcsid[] DD_UNUSED = "$Id: cuddSign.c,v 1.24 2012/02/05 01:07:19 fabio Exp $";
|
|
#endif
|
|
|
|
static int size;
|
|
|
|
#ifdef DD_STATS
|
|
static int num_calls; /* should equal 2n-1 (n is the # of nodes) */
|
|
static int table_mem;
|
|
#endif
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Macro declarations */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
|
|
/**AutomaticStart*************************************************************/
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Static function prototypes */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
static double * ddCofMintermAux (DdManager *dd, DdNode *node, st_table *table);
|
|
|
|
/**AutomaticEnd***************************************************************/
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Definition of exported functions */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/**Function********************************************************************
|
|
|
|
Synopsis [Computes the fraction of minterms in the on-set of all the
|
|
positive cofactors of a BDD or ADD.]
|
|
|
|
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 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
|
|
positions of the array hold the variable signatures.]
|
|
|
|
SideEffects [None]
|
|
|
|
******************************************************************************/
|
|
double *
|
|
Cudd_CofMinterm(
|
|
DdManager * dd,
|
|
DdNode * node)
|
|
{
|
|
st_table *table;
|
|
double *values;
|
|
double *result = NULL;
|
|
int i, firstLevel;
|
|
|
|
#ifdef DD_STATS
|
|
unsigned long startTime;
|
|
startTime = util_cpu_time();
|
|
num_calls = 0;
|
|
table_mem = sizeof(st_table);
|
|
#endif
|
|
|
|
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);
|
|
}
|
|
size = dd->size;
|
|
values = ddCofMintermAux(dd, node, table);
|
|
if (values != NULL) {
|
|
result = ALLOC(double,size + 1);
|
|
if (result != NULL) {
|
|
#ifdef DD_STATS
|
|
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];
|
|
} else {
|
|
result[dd->invperm[i]] = values[size - firstLevel];
|
|
}
|
|
}
|
|
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) FREE(values);
|
|
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);
|
|
(void) fprintf(dd->out,"Time to compute measures: %s\n",
|
|
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;
|
|
}
|
|
return(result);
|
|
|
|
} /* end of Cudd_CofMinterm */
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Definition of internal functions */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Definition of static functions */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
|
|
/**Function********************************************************************
|
|
|
|
Synopsis [Recursive Step for Cudd_CofMinterm function.]
|
|
|
|
Description [Traverses the DD node and computes the fraction of
|
|
minterms in the on-set of all positive cofactors simultaneously.
|
|
It allocates an array with two more entries than there are
|
|
variables below the one labeling the node. One extra entry (the
|
|
first in the array) is for the variable labeling the node. The other
|
|
entry (the last one in the array) holds the fraction of minterms of
|
|
the function rooted at node. Each other entry holds the value for
|
|
one cofactor. The array is put in a symbol table, to avoid repeated
|
|
computation, and its address is returned by the procedure, for use
|
|
by the caller. Returns a pointer to the array of cofactor measures.]
|
|
|
|
SideEffects [None]
|
|
|
|
SeeAlso []
|
|
|
|
******************************************************************************/
|
|
static double *
|
|
ddCofMintermAux(
|
|
DdManager * dd,
|
|
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;
|
|
|
|
statLine(dd);
|
|
#ifdef DD_STATS
|
|
num_calls++;
|
|
#endif
|
|
|
|
if (st_lookup(table, node, &values)) {
|
|
return(values);
|
|
}
|
|
|
|
N = Cudd_Regular(node);
|
|
if (cuddIsConstant(N)) {
|
|
localSize = 1;
|
|
} else {
|
|
localSize = size - cuddI(dd,N->index) + 1;
|
|
}
|
|
values = ALLOC(double, localSize);
|
|
if (values == 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)];
|
|
} 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) FREE(valuesT);
|
|
if (Cudd_Regular(Nnv)->ref == 1) FREE(valuesE);
|
|
}
|
|
|
|
if (N->ref > 1) {
|
|
if (st_add_direct(table, (char *) node, (char *) values) == ST_OUT_OF_MEM) {
|
|
FREE(values);
|
|
return(NULL);
|
|
}
|
|
#ifdef DD_STATS
|
|
table_mem += localSize * sizeof(double) + sizeof(st_table_entry);
|
|
#endif
|
|
}
|
|
return(values);
|
|
|
|
} /* end of ddCofMintermAux */
|