00001 
00028 #include "util_hack.h"
00029 #include "cuddInt.h"
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 #ifndef lint
00052 static char rcsid[] DD_UNUSED = "$Id: cuddSign.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $";
00053 #endif
00054 
00055 static int    size;
00056 
00057 #ifdef DD_STATS
00058 static int num_calls;   
00059 static int table_mem;
00060 #endif
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00070 
00071 
00072 
00073 
00074 static double * ddCofMintermAux ARGS((DdManager *dd, DdNode *node, st_table *table));
00075 
00079 
00080 
00081 
00082 
00099 double *
00100 Cudd_CofMinterm(
00101   DdManager * dd,
00102   DdNode * node)
00103 {
00104     st_table    *table;
00105     double      *values;
00106     double      *result = NULL;
00107     int         i, firstLevel;
00108 
00109 #ifdef DD_STATS
00110     long startTime;
00111     startTime = util_cpu_time();
00112     num_calls = 0;
00113     table_mem = sizeof(st_table);
00114 #endif
00115 
00116     table = st_init_table(st_ptrcmp, st_ptrhash);
00117     if (table == NULL) {
00118         (void) fprintf(dd->err,
00119                        "out-of-memory, couldn't measure DD cofactors.\n");
00120         dd->errorCode = CUDD_MEMORY_OUT;
00121         return(NULL);
00122     }
00123     size = dd->size;
00124     values = ddCofMintermAux(dd, node, table);
00125     if (values != NULL) {
00126         result = ALLOC(double,size + 1);
00127         if (result != NULL) {
00128 #ifdef DD_STATS
00129             table_mem += (size + 1) * sizeof(double);
00130 #endif
00131             if (Cudd_IsConstant(node))
00132                 firstLevel = 1;
00133             else
00134                 firstLevel = cuddI(dd,Cudd_Regular(node)->index);
00135             for (i = 0; i < size; i++) {
00136                 if (i >= cuddI(dd,Cudd_Regular(node)->index)) {
00137                     result[dd->invperm[i]] = values[i - firstLevel];
00138                 } else {
00139                     result[dd->invperm[i]] = values[size - firstLevel];
00140                 }
00141             }
00142             result[size] = values[size - firstLevel];
00143         } else {
00144             dd->errorCode = CUDD_MEMORY_OUT;
00145         }
00146     }
00147 
00148 #ifdef DD_STATS
00149     table_mem += table->num_bins * sizeof(st_table_entry *);
00150 #endif
00151     if (Cudd_Regular(node)->ref == 1) FREE(values);
00152     st_foreach(table, cuddStCountfree, NULL);
00153     st_free_table(table);
00154 #ifdef DD_STATS
00155     (void) fprintf(dd->out,"Number of calls: %d\tTable memory: %d bytes\n",
00156                   num_calls, table_mem);
00157     (void) fprintf(dd->out,"Time to compute measures: %s\n",
00158                   util_print_time(util_cpu_time() - startTime));
00159 #endif
00160     if (result == NULL) {
00161         (void) fprintf(dd->out,
00162                        "out-of-memory, couldn't measure DD cofactors.\n");
00163         dd->errorCode = CUDD_MEMORY_OUT;
00164     }
00165     return(result);
00166 
00167 } 
00168 
00169 
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00200 static double *
00201 ddCofMintermAux(
00202   DdManager * dd,
00203   DdNode * node,
00204   st_table * table)
00205 {
00206     DdNode      *N;             
00207     DdNode      *Nv, *Nnv;
00208     double      *values;
00209     double      *valuesT, *valuesE;
00210     int         i;
00211     int         localSize, localSizeT, localSizeE;
00212     double      vT, vE;
00213 
00214     statLine(dd);
00215 #ifdef DD_STATS
00216     num_calls++;
00217 #endif
00218 
00219     if (st_lookup(table, (char *) node, (char **) &values)) {
00220         return(values);
00221     }
00222 
00223     N = Cudd_Regular(node);
00224     if (cuddIsConstant(N)) {
00225         localSize = 1;
00226     } else {
00227         localSize = size - cuddI(dd,N->index) + 1;
00228     }
00229     values = ALLOC(double, localSize);
00230     if (values == NULL) {
00231         dd->errorCode = CUDD_MEMORY_OUT;
00232         return(NULL);
00233     }
00234 
00235     if (cuddIsConstant(N)) {
00236         if (node == DD_ZERO(dd) || node == Cudd_Not(DD_ONE(dd))) {
00237             values[0] = 0.0;
00238         } else {
00239             values[0] = 1.0;
00240         }
00241     } else {
00242         Nv = Cudd_NotCond(cuddT(N),N!=node);
00243         Nnv = Cudd_NotCond(cuddE(N),N!=node);
00244 
00245         valuesT = ddCofMintermAux(dd, Nv, table);
00246         if (valuesT == NULL) return(NULL);
00247         valuesE = ddCofMintermAux(dd, Nnv, table);
00248         if (valuesE == NULL) return(NULL);
00249 
00250         if (Cudd_IsConstant(Nv)) {
00251             localSizeT = 1;
00252         } else {
00253             localSizeT = size - cuddI(dd,Cudd_Regular(Nv)->index) + 1;
00254         }
00255         if (Cudd_IsConstant(Nnv)) {
00256             localSizeE = 1;
00257         } else {
00258             localSizeE = size - cuddI(dd,Cudd_Regular(Nnv)->index) + 1;
00259         }
00260         values[0] = valuesT[localSizeT - 1];
00261         for (i = 1; i < localSize; i++) {
00262             if (i >= cuddI(dd,Cudd_Regular(Nv)->index) - cuddI(dd,N->index)) {
00263                 vT = valuesT[i - cuddI(dd,Cudd_Regular(Nv)->index) +
00264                             cuddI(dd,N->index)];
00265             } else {
00266                 vT = valuesT[localSizeT - 1];
00267             }
00268             if (i >= cuddI(dd,Cudd_Regular(Nnv)->index) - cuddI(dd,N->index)) {
00269                 vE = valuesE[i - cuddI(dd,Cudd_Regular(Nnv)->index) +
00270                             cuddI(dd,N->index)];
00271             } else {
00272                 vE = valuesE[localSizeE - 1];
00273             }
00274             values[i] = (vT + vE) / 2.0;
00275         }
00276         if (Cudd_Regular(Nv)->ref == 1) FREE(valuesT);
00277         if (Cudd_Regular(Nnv)->ref == 1) FREE(valuesE);
00278     }
00279 
00280     if (N->ref > 1) {
00281         if (st_add_direct(table, (char *) node, (char *) values) == ST_OUT_OF_MEM) {
00282             FREE(values);
00283             return(NULL);
00284         }
00285 #ifdef DD_STATS
00286         table_mem += localSize * sizeof(double) + sizeof(st_table_entry);
00287 #endif
00288     }
00289     return(values);
00290 
00291 } 
00292