00001
00064 #include "util.h"
00065 #include "cuddInt.h"
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 #ifndef lint
00087 static char rcsid[] DD_UNUSED = "$Id: cuddZddCount.c,v 1.14 2004/08/13 18:04:53 fabio Exp $";
00088 #endif
00089
00090
00091
00092
00093
00094 #ifdef __cplusplus
00095 extern "C" {
00096 #endif
00097
00100
00101
00102
00103
00104 static int cuddZddCountStep (DdNode *P, st_table *table, DdNode *base, DdNode *empty);
00105 static double cuddZddCountDoubleStep (DdNode *P, st_table *table, DdNode *base, DdNode *empty);
00106 static enum st_retval st_zdd_countfree (char *key, char *value, char *arg);
00107 static enum st_retval st_zdd_count_dbl_free (char *key, char *value, char *arg);
00108
00111 #ifdef __cplusplus
00112 }
00113 #endif
00114
00115
00116
00117
00118
00119
00132 int
00133 Cudd_zddCount(
00134 DdManager * zdd,
00135 DdNode * P)
00136 {
00137 st_table *table;
00138 int res;
00139 DdNode *base, *empty;
00140
00141 base = DD_ONE(zdd);
00142 empty = DD_ZERO(zdd);
00143 table = st_init_table(st_ptrcmp, st_ptrhash);
00144 if (table == NULL) return(CUDD_OUT_OF_MEM);
00145 res = cuddZddCountStep(P, table, base, empty);
00146 if (res == CUDD_OUT_OF_MEM) {
00147 zdd->errorCode = CUDD_MEMORY_OUT;
00148 }
00149 st_foreach(table, st_zdd_countfree, NIL(char));
00150 st_free_table(table);
00151
00152 return(res);
00153
00154 }
00155
00156
00171 double
00172 Cudd_zddCountDouble(
00173 DdManager * zdd,
00174 DdNode * P)
00175 {
00176 st_table *table;
00177 double res;
00178 DdNode *base, *empty;
00179
00180 base = DD_ONE(zdd);
00181 empty = DD_ZERO(zdd);
00182 table = st_init_table(st_ptrcmp, st_ptrhash);
00183 if (table == NULL) return((double)CUDD_OUT_OF_MEM);
00184 res = cuddZddCountDoubleStep(P, table, base, empty);
00185 if (res == (double)CUDD_OUT_OF_MEM) {
00186 zdd->errorCode = CUDD_MEMORY_OUT;
00187 }
00188 st_foreach(table, st_zdd_count_dbl_free, NIL(char));
00189 st_free_table(table);
00190
00191 return(res);
00192
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00217 static int
00218 cuddZddCountStep(
00219 DdNode * P,
00220 st_table * table,
00221 DdNode * base,
00222 DdNode * empty)
00223 {
00224 int res;
00225 int *dummy;
00226
00227 if (P == empty)
00228 return(0);
00229 if (P == base)
00230 return(1);
00231
00232
00233 if (st_lookup(table, P, &dummy)) {
00234 res = *dummy;
00235 return(res);
00236 }
00237
00238 res = cuddZddCountStep(cuddE(P), table, base, empty) +
00239 cuddZddCountStep(cuddT(P), table, base, empty);
00240
00241 dummy = ALLOC(int, 1);
00242 if (dummy == NULL) {
00243 return(CUDD_OUT_OF_MEM);
00244 }
00245 *dummy = res;
00246 if (st_insert(table, (char *)P, (char *)dummy) == ST_OUT_OF_MEM) {
00247 FREE(dummy);
00248 return(CUDD_OUT_OF_MEM);
00249 }
00250
00251 return(res);
00252
00253 }
00254
00255
00267 static double
00268 cuddZddCountDoubleStep(
00269 DdNode * P,
00270 st_table * table,
00271 DdNode * base,
00272 DdNode * empty)
00273 {
00274 double res;
00275 double *dummy;
00276
00277 if (P == empty)
00278 return((double)0.0);
00279 if (P == base)
00280 return((double)1.0);
00281
00282
00283 if (st_lookup(table, P, &dummy)) {
00284 res = *dummy;
00285 return(res);
00286 }
00287
00288 res = cuddZddCountDoubleStep(cuddE(P), table, base, empty) +
00289 cuddZddCountDoubleStep(cuddT(P), table, base, empty);
00290
00291 dummy = ALLOC(double, 1);
00292 if (dummy == NULL) {
00293 return((double)CUDD_OUT_OF_MEM);
00294 }
00295 *dummy = res;
00296 if (st_insert(table, (char *)P, (char *)dummy) == ST_OUT_OF_MEM) {
00297 FREE(dummy);
00298 return((double)CUDD_OUT_OF_MEM);
00299 }
00300
00301 return(res);
00302
00303 }
00304
00305
00318 static enum st_retval
00319 st_zdd_countfree(
00320 char * key,
00321 char * value,
00322 char * arg)
00323 {
00324 int *d;
00325
00326 d = (int *)value;
00327 FREE(d);
00328 return(ST_CONTINUE);
00329
00330 }
00331
00332
00345 static enum st_retval
00346 st_zdd_count_dbl_free(
00347 char * key,
00348 char * value,
00349 char * arg)
00350 {
00351 double *d;
00352
00353 d = (double *)value;
00354 FREE(d);
00355 return(ST_CONTINUE);
00356
00357 }