cuddSign.c 11.3 KB
Newer Older
Alan Mishchenko committed
1 2 3 4 5 6
/**CFile***********************************************************************

  FileName    [cuddSign.c]

  PackageName [cudd]

7
  Synopsis    [Computation of signatures.]
Alan Mishchenko committed
8 9

  Description [External procedures included in this module:
10 11 12 13 14 15 16 17
                    <ul>
                    <li> Cudd_CofMinterm();
                    </ul>
                Static procedures included in this module:
                    <ul>
                    <li> ddCofMintermAux()
                    </ul>
                    ]
Alan Mishchenko committed
18 19 20

  Author      [Fabio Somenzi]

21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
  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.]
Alan Mishchenko committed
52 53 54

******************************************************************************/

55
#include "misc/util/util_hack.h"
Alan Mishchenko committed
56 57
#include "cuddInt.h"

58 59 60
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
61

62

Alan Mishchenko committed
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
/*---------------------------------------------------------------------------*/
/* Constant declarations                                                     */
/*---------------------------------------------------------------------------*/


/*---------------------------------------------------------------------------*/
/* Stucture declarations                                                     */
/*---------------------------------------------------------------------------*/


/*---------------------------------------------------------------------------*/
/* Type declarations                                                         */
/*---------------------------------------------------------------------------*/


/*---------------------------------------------------------------------------*/
/* Variable declarations                                                     */
/*---------------------------------------------------------------------------*/

#ifndef lint
83
static char rcsid[] DD_UNUSED = "$Id: cuddSign.c,v 1.22 2009/02/20 02:14:58 fabio Exp $";
Alan Mishchenko committed
84 85 86 87 88
#endif

static int    size;

#ifdef DD_STATS
89
static int num_calls;   /* should equal 2n-1 (n is the # of nodes) */
Alan Mishchenko committed
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
static int table_mem;
#endif


/*---------------------------------------------------------------------------*/
/* Macro declarations                                                        */
/*---------------------------------------------------------------------------*/


/**AutomaticStart*************************************************************/

/*---------------------------------------------------------------------------*/
/* Static function prototypes                                                */
/*---------------------------------------------------------------------------*/

105
static double * ddCofMintermAux (DdManager *dd, DdNode *node, st__table *table);
Alan Mishchenko committed
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120

/**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
121
  doubles if successful; NULL otherwise. The array has as many
Alan Mishchenko committed
122 123 124 125 126 127 128 129 130 131 132 133 134
  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)
{
135
    st__table    *table;
136 137 138
    double      *values;
    double      *result = NULL;
    int         i, firstLevel;
Alan Mishchenko committed
139 140 141 142 143

#ifdef DD_STATS
    long startTime;
    startTime = util_cpu_time();
    num_calls = 0;
144
    table_mem = sizeof( st__table);
Alan Mishchenko committed
145 146
#endif

147
    table = st__init_table( st__ptrcmp, st__ptrhash);
Alan Mishchenko committed
148
    if (table == NULL) {
149 150 151 152
        (void) fprintf(dd->err,
                       "out-of-memory, couldn't measure DD cofactors.\n");
        dd->errorCode = CUDD_MEMORY_OUT;
        return(NULL);
Alan Mishchenko committed
153 154 155 156
    }
    size = dd->size;
    values = ddCofMintermAux(dd, node, table);
    if (values != NULL) {
157 158
        result = ABC_ALLOC(double,size + 1);
        if (result != NULL) {
Alan Mishchenko committed
159
#ifdef DD_STATS
160
            table_mem += (size + 1) * sizeof(double);
Alan Mishchenko committed
161
#endif
162 163 164 165 166 167 168 169 170 171 172 173
            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];
Alan Mishchenko committed
174
        } else {
175
            dd->errorCode = CUDD_MEMORY_OUT;
Alan Mishchenko committed
176 177 178 179
        }
    }

#ifdef DD_STATS
180
    table_mem += table->num_bins * sizeof( st__table_entry *);
Alan Mishchenko committed
181
#endif
Alan Mishchenko committed
182
    if (Cudd_Regular(node)->ref == 1) ABC_FREE(values);
183 184
    st__foreach(table, cuddStCountfree, NULL);
    st__free_table(table);
Alan Mishchenko committed
185 186
#ifdef DD_STATS
    (void) fprintf(dd->out,"Number of calls: %d\tTable memory: %d bytes\n",
187
                  num_calls, table_mem);
Alan Mishchenko committed
188
    (void) fprintf(dd->out,"Time to compute measures: %s\n",
189
                  util_print_time(util_cpu_time() - startTime));
Alan Mishchenko committed
190 191
#endif
    if (result == NULL) {
192 193 194
        (void) fprintf(dd->out,
                       "out-of-memory, couldn't measure DD cofactors.\n");
        dd->errorCode = CUDD_MEMORY_OUT;
Alan Mishchenko committed
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
    }
    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,
235
  st__table * table)
Alan Mishchenko committed
236
{
237 238 239 240 241 242 243
    DdNode      *N;             /* regular version of node */
    DdNode      *Nv, *Nnv;
    double      *values;
    double      *valuesT, *valuesE;
    int         i;
    int         localSize, localSizeT, localSizeE;
    double      vT, vE;
Alan Mishchenko committed
244 245 246 247 248 249

    statLine(dd);
#ifdef DD_STATS
    num_calls++;
#endif

250
    if ( st__lookup(table, (const char *)node, (char **)&values)) {
251
        return(values);
Alan Mishchenko committed
252 253 254 255
    }

    N = Cudd_Regular(node);
    if (cuddIsConstant(N)) {
256
        localSize = 1;
Alan Mishchenko committed
257
    } else {
258
        localSize = size - cuddI(dd,N->index) + 1;
Alan Mishchenko committed
259
    }
Alan Mishchenko committed
260
    values = ABC_ALLOC(double, localSize);
Alan Mishchenko committed
261
    if (values == NULL) {
262 263
        dd->errorCode = CUDD_MEMORY_OUT;
        return(NULL);
Alan Mishchenko committed
264 265 266
    }

    if (cuddIsConstant(N)) {
267 268 269 270 271
        if (node == DD_ZERO(dd) || node == Cudd_Not(DD_ONE(dd))) {
            values[0] = 0.0;
        } else {
            values[0] = 1.0;
        }
Alan Mishchenko committed
272
    } else {
273 274
        Nv = Cudd_NotCond(cuddT(N),N!=node);
        Nnv = Cudd_NotCond(cuddE(N),N!=node);
Alan Mishchenko committed
275

276 277 278 279
        valuesT = ddCofMintermAux(dd, Nv, table);
        if (valuesT == NULL) return(NULL);
        valuesE = ddCofMintermAux(dd, Nnv, table);
        if (valuesE == NULL) return(NULL);
Alan Mishchenko committed
280

281 282
        if (Cudd_IsConstant(Nv)) {
            localSizeT = 1;
Alan Mishchenko committed
283
        } else {
284
            localSizeT = size - cuddI(dd,Cudd_Regular(Nv)->index) + 1;
Alan Mishchenko committed
285
        }
286 287
        if (Cudd_IsConstant(Nnv)) {
            localSizeE = 1;
Alan Mishchenko committed
288
        } else {
289
            localSizeE = size - cuddI(dd,Cudd_Regular(Nnv)->index) + 1;
Alan Mishchenko committed
290
        }
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
        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);
Alan Mishchenko committed
309 310 311
    }

    if (N->ref > 1) {
312
        if ( st__add_direct(table, (char *) node, (char *) values) == st__OUT_OF_MEM) {
313 314 315
            ABC_FREE(values);
            return(NULL);
        }
Alan Mishchenko committed
316
#ifdef DD_STATS
317
        table_mem += localSize * sizeof(double) + sizeof( st__table_entry);
Alan Mishchenko committed
318 319 320 321 322 323
#endif
    }
    return(values);

} /* end of ddCofMintermAux */

324

325 326
ABC_NAMESPACE_IMPL_END