00001
00077 #include "util.h"
00078 #include "cuddInt.h"
00079
00080
00081
00082
00083
00084 #if SIZEOF_LONG == 8
00085 #define BPL 64
00086 #define LOGBPL 6
00087 #else
00088 #define BPL 32
00089 #define LOGBPL 5
00090 #endif
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 #ifndef lint
00107 static char rcsid[] DD_UNUSED = "$Id: cuddInteract.c,v 1.12 2004/08/13 18:04:49 fabio Exp $";
00108 #endif
00109
00110
00111
00112
00113
00114
00117
00118
00119
00120
00121 static void ddSuppInteract (DdNode *f, int *support);
00122 static void ddClearLocal (DdNode *f);
00123 static void ddUpdateInteract (DdManager *table, int *support);
00124 static void ddClearGlobal (DdManager *table);
00125
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00151 void
00152 cuddSetInteract(
00153 DdManager * table,
00154 int x,
00155 int y)
00156 {
00157 int posn, word, bit;
00158
00159 #ifdef DD_DEBUG
00160 assert(x < y);
00161 assert(y < table->size);
00162 assert(x >= 0);
00163 #endif
00164
00165 posn = ((((table->size << 1) - x - 3) * x) >> 1) + y - 1;
00166 word = posn >> LOGBPL;
00167 bit = posn & (BPL-1);
00168 table->interact[word] |= 1L << bit;
00169
00170 }
00171
00172
00186 int
00187 cuddTestInteract(
00188 DdManager * table,
00189 int x,
00190 int y)
00191 {
00192 int posn, word, bit, result;
00193
00194 if (x > y) {
00195 int tmp = x;
00196 x = y;
00197 y = tmp;
00198 }
00199 #ifdef DD_DEBUG
00200 assert(x < y);
00201 assert(y < table->size);
00202 assert(x >= 0);
00203 #endif
00204
00205 posn = ((((table->size << 1) - x - 3) * x) >> 1) + y - 1;
00206 word = posn >> LOGBPL;
00207 bit = posn & (BPL-1);
00208 result = (table->interact[word] >> bit) & 1L;
00209 return(result);
00210
00211 }
00212
00213
00232 int
00233 cuddInitInteract(
00234 DdManager * table)
00235 {
00236 int i,j,k;
00237 int words;
00238 long *interact;
00239 int *support;
00240 DdNode *f;
00241 DdNode *sentinel = &(table->sentinel);
00242 DdNodePtr *nodelist;
00243 int slots;
00244 int n = table->size;
00245
00246 words = ((n * (n-1)) >> (1 + LOGBPL)) + 1;
00247 table->interact = interact = ALLOC(long,words);
00248 if (interact == NULL) {
00249 table->errorCode = CUDD_MEMORY_OUT;
00250 return(0);
00251 }
00252 for (i = 0; i < words; i++) {
00253 interact[i] = 0;
00254 }
00255
00256 support = ALLOC(int,n);
00257 if (support == NULL) {
00258 table->errorCode = CUDD_MEMORY_OUT;
00259 FREE(interact);
00260 return(0);
00261 }
00262
00263 for (i = 0; i < n; i++) {
00264 nodelist = table->subtables[i].nodelist;
00265 slots = table->subtables[i].slots;
00266 for (j = 0; j < slots; j++) {
00267 f = nodelist[j];
00268 while (f != sentinel) {
00269
00270
00271
00272
00273
00274
00275 if (!Cudd_IsComplement(f->next)) {
00276 for (k = 0; k < n; k++) {
00277 support[k] = 0;
00278 }
00279 ddSuppInteract(f,support);
00280 ddClearLocal(f);
00281 ddUpdateInteract(table,support);
00282 }
00283 f = Cudd_Regular(f->next);
00284 }
00285 }
00286 }
00287 ddClearGlobal(table);
00288
00289 FREE(support);
00290 return(1);
00291
00292 }
00293
00294
00295
00296
00297
00298
00299
00312 static void
00313 ddSuppInteract(
00314 DdNode * f,
00315 int * support)
00316 {
00317 if (cuddIsConstant(f) || Cudd_IsComplement(cuddT(f))) {
00318 return;
00319 }
00320
00321 support[f->index] = 1;
00322 ddSuppInteract(cuddT(f),support);
00323 ddSuppInteract(Cudd_Regular(cuddE(f)),support);
00324
00325 cuddT(f) = Cudd_Complement(cuddT(f));
00326 f->next = Cudd_Complement(f->next);
00327 return;
00328
00329 }
00330
00331
00343 static void
00344 ddClearLocal(
00345 DdNode * f)
00346 {
00347 if (cuddIsConstant(f) || !Cudd_IsComplement(cuddT(f))) {
00348 return;
00349 }
00350
00351 cuddT(f) = Cudd_Regular(cuddT(f));
00352 ddClearLocal(cuddT(f));
00353 ddClearLocal(Cudd_Regular(cuddE(f)));
00354 return;
00355
00356 }
00357
00358
00372 static void
00373 ddUpdateInteract(
00374 DdManager * table,
00375 int * support)
00376 {
00377 int i,j;
00378 int n = table->size;
00379
00380 for (i = 0; i < n-1; i++) {
00381 if (support[i] == 1) {
00382 for (j = i+1; j < n; j++) {
00383 if (support[j] == 1) {
00384 cuddSetInteract(table,i,j);
00385 }
00386 }
00387 }
00388 }
00389
00390 }
00391
00392
00406 static void
00407 ddClearGlobal(
00408 DdManager * table)
00409 {
00410 int i,j;
00411 DdNode *f;
00412 DdNode *sentinel = &(table->sentinel);
00413 DdNodePtr *nodelist;
00414 int slots;
00415
00416 for (i = 0; i < table->size; i++) {
00417 nodelist = table->subtables[i].nodelist;
00418 slots = table->subtables[i].slots;
00419 for (j = 0; j < slots; j++) {
00420 f = nodelist[j];
00421 while (f != sentinel) {
00422 f->next = Cudd_Regular(f->next);
00423 f = f->next;
00424 }
00425 }
00426 }
00427
00428 }
00429