00001
00058 #include "util_hack.h"
00059 #include "cuddInt.h"
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 #ifndef lint
00079 static char rcsid[] DD_UNUSED = "$Id: cuddCompose.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
00080 #endif
00081
00082 #ifdef DD_DEBUG
00083 static int addPermuteRecurHits;
00084 static int bddPermuteRecurHits;
00085 static int bddVectorComposeHits;
00086 static int addVectorComposeHits;
00087
00088 static int addGeneralVectorComposeHits;
00089 #endif
00090
00091
00092
00093
00094
00095
00098
00099
00100
00101
00102 static DdNode * cuddAddPermuteRecur ARGS((DdManager *manager, DdHashTable *table, DdNode *node, int *permut));
00103 static DdNode * cuddBddPermuteRecur ARGS((DdManager *manager, DdHashTable *table, DdNode *node, int *permut));
00104 static DdNode * cuddBddVarMapRecur ARGS((DdManager *manager, DdNode *f));
00105 static DdNode * cuddAddVectorComposeRecur ARGS((DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest));
00106 static DdNode * cuddAddNonSimComposeRecur ARGS((DdManager *dd, DdNode *f, DdNode **vector, DdNode *key, DdNode *cube, int lastsub));
00107 static DdNode * cuddBddVectorComposeRecur ARGS((DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest));
00108 DD_INLINE static int ddIsIthAddVar ARGS((DdManager *dd, DdNode *f, unsigned int i));
00109
00110 static DdNode * cuddAddGeneralVectorComposeRecur ARGS((DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vectorOn, DdNode **vectorOff, int deepest));
00111 DD_INLINE static int ddIsIthAddVarPair ARGS((DdManager *dd, DdNode *f, DdNode *g, unsigned int i));
00112
00116
00117
00118
00119
00120
00135 DdNode *
00136 Cudd_bddCompose(
00137 DdManager * dd,
00138 DdNode * f,
00139 DdNode * g,
00140 int v)
00141 {
00142 DdNode *proj, *res;
00143
00144
00145 if (v < 0 || v > dd->size) return(NULL);
00146
00147 proj = dd->vars[v];
00148 do {
00149 dd->reordered = 0;
00150 res = cuddBddComposeRecur(dd,f,g,proj);
00151 } while (dd->reordered == 1);
00152 return(res);
00153
00154 }
00155
00156
00172 DdNode *
00173 Cudd_addCompose(
00174 DdManager * dd,
00175 DdNode * f,
00176 DdNode * g,
00177 int v)
00178 {
00179 DdNode *proj, *res;
00180
00181
00182 if (v < 0 || v > dd->size) return(NULL);
00183
00184 proj = dd->vars[v];
00185 do {
00186 dd->reordered = 0;
00187 res = cuddAddComposeRecur(dd,f,g,proj);
00188 } while (dd->reordered == 1);
00189 return(res);
00190
00191 }
00192
00193
00210 DdNode *
00211 Cudd_addPermute(
00212 DdManager * manager,
00213 DdNode * node,
00214 int * permut)
00215 {
00216 DdHashTable *table;
00217 DdNode *res;
00218
00219 do {
00220 manager->reordered = 0;
00221 table = cuddHashTableInit(manager,1,2);
00222 if (table == NULL) return(NULL);
00223
00224 res = cuddAddPermuteRecur(manager,table,node,permut);
00225 if (res != NULL) cuddRef(res);
00226
00227 cuddHashTableQuit(table);
00228 } while (manager->reordered == 1);
00229
00230 if (res != NULL) cuddDeref(res);
00231 return(res);
00232
00233 }
00234
00235
00251 DdNode *
00252 Cudd_addSwapVariables(
00253 DdManager * dd,
00254 DdNode * f,
00255 DdNode ** x,
00256 DdNode ** y,
00257 int n)
00258 {
00259 DdNode *swapped;
00260 int i, j, k;
00261 int *permut;
00262
00263 permut = ALLOC(int,dd->size);
00264 if (permut == NULL) {
00265 dd->errorCode = CUDD_MEMORY_OUT;
00266 return(NULL);
00267 }
00268 for (i = 0; i < dd->size; i++) permut[i] = i;
00269 for (i = 0; i < n; i++) {
00270 j = x[i]->index;
00271 k = y[i]->index;
00272 permut[j] = k;
00273 permut[k] = j;
00274 }
00275
00276 swapped = Cudd_addPermute(dd,f,permut);
00277 FREE(permut);
00278
00279 return(swapped);
00280
00281 }
00282
00283
00300 DdNode *
00301 Cudd_bddPermute(
00302 DdManager * manager,
00303 DdNode * node,
00304 int * permut)
00305 {
00306 DdHashTable *table;
00307 DdNode *res;
00308
00309 do {
00310 manager->reordered = 0;
00311 table = cuddHashTableInit(manager,1,2);
00312 if (table == NULL) return(NULL);
00313 res = cuddBddPermuteRecur(manager,table,node,permut);
00314 if (res != NULL) cuddRef(res);
00315
00316 cuddHashTableQuit(table);
00317
00318 } while (manager->reordered == 1);
00319
00320 if (res != NULL) cuddDeref(res);
00321 return(res);
00322
00323 }
00324
00325
00341 DdNode *
00342 Cudd_bddVarMap(
00343 DdManager * manager ,
00344 DdNode * f )
00345 {
00346 DdNode *res;
00347
00348 if (manager->map == NULL) return(NULL);
00349 do {
00350 manager->reordered = 0;
00351 res = cuddBddVarMapRecur(manager, f);
00352 } while (manager->reordered == 1);
00353
00354 return(res);
00355
00356 }
00357
00358
00384 int
00385 Cudd_SetVarMap (
00386 DdManager *manager ,
00387 DdNode **x ,
00388 DdNode **y ,
00389 int n )
00390 {
00391 int i;
00392
00393 if (manager->map != NULL) {
00394 cuddCacheFlush(manager);
00395 } else {
00396 manager->map = ALLOC(int,manager->maxSize);
00397 if (manager->map == NULL) {
00398 manager->errorCode = CUDD_MEMORY_OUT;
00399 return(0);
00400 }
00401 manager->memused += sizeof(int) * manager->maxSize;
00402 }
00403
00404 for (i = 0; i < manager->size; i++) {
00405 manager->map[i] = i;
00406 }
00407
00408 for (i = 0; i < n; i++) {
00409 manager->map[x[i]->index] = y[i]->index;
00410 manager->map[y[i]->index] = x[i]->index;
00411 }
00412 return(1);
00413
00414 }
00415
00416
00432 DdNode *
00433 Cudd_bddSwapVariables(
00434 DdManager * dd,
00435 DdNode * f,
00436 DdNode ** x,
00437 DdNode ** y,
00438 int n)
00439 {
00440 DdNode *swapped;
00441 int i, j, k;
00442 int *permut;
00443
00444 permut = ALLOC(int,dd->size);
00445 if (permut == NULL) {
00446 dd->errorCode = CUDD_MEMORY_OUT;
00447 return(NULL);
00448 }
00449 for (i = 0; i < dd->size; i++) permut[i] = i;
00450 for (i = 0; i < n; i++) {
00451 j = x[i]->index;
00452 k = y[i]->index;
00453 permut[j] = k;
00454 permut[k] = j;
00455 }
00456
00457 swapped = Cudd_bddPermute(dd,f,permut);
00458 FREE(permut);
00459
00460 return(swapped);
00461
00462 }
00463
00464
00480 DdNode *
00481 Cudd_bddAdjPermuteX(
00482 DdManager * dd,
00483 DdNode * B,
00484 DdNode ** x,
00485 int n)
00486 {
00487 DdNode *swapped;
00488 int i, j, k;
00489 int *permut;
00490
00491 permut = ALLOC(int,dd->size);
00492 if (permut == NULL) {
00493 dd->errorCode = CUDD_MEMORY_OUT;
00494 return(NULL);
00495 }
00496 for (i = 0; i < dd->size; i++) permut[i] = i;
00497 for (i = 0; i < n-2; i += 3) {
00498 j = x[i]->index;
00499 k = x[i+1]->index;
00500 permut[j] = k;
00501 permut[k] = j;
00502 }
00503
00504 swapped = Cudd_bddPermute(dd,B,permut);
00505 FREE(permut);
00506
00507 return(swapped);
00508
00509 }
00510
00511
00531 DdNode *
00532 Cudd_addVectorCompose(
00533 DdManager * dd,
00534 DdNode * f,
00535 DdNode ** vector)
00536 {
00537 DdHashTable *table;
00538 DdNode *res;
00539 int deepest;
00540 int i;
00541
00542 do {
00543 dd->reordered = 0;
00544
00545 table = cuddHashTableInit(dd,1,2);
00546 if (table == NULL) return(NULL);
00547
00548
00549 for (deepest = dd->size - 1; deepest >= 0; deepest--) {
00550 i = dd->invperm[deepest];
00551 if (!ddIsIthAddVar(dd,vector[i],i)) {
00552 break;
00553 }
00554 }
00555
00556
00557 res = cuddAddVectorComposeRecur(dd,table,f,vector,deepest);
00558 if (res != NULL) cuddRef(res);
00559
00560
00561 cuddHashTableQuit(table);
00562 } while (dd->reordered == 1);
00563
00564 if (res != NULL) cuddDeref(res);
00565 return(res);
00566
00567 }
00568
00569
00589 DdNode *
00590 Cudd_addGeneralVectorCompose(
00591 DdManager * dd,
00592 DdNode * f,
00593 DdNode ** vectorOn,
00594 DdNode ** vectorOff)
00595 {
00596 DdHashTable *table;
00597 DdNode *res;
00598 int deepest;
00599 int i;
00600
00601 do {
00602 dd->reordered = 0;
00603
00604 table = cuddHashTableInit(dd,1,2);
00605 if (table == NULL) return(NULL);
00606
00607
00608 for (deepest = dd->size - 1; deepest >= 0; deepest--) {
00609 i = dd->invperm[deepest];
00610 if (!ddIsIthAddVarPair(dd,vectorOn[i],vectorOff[i],i)) {
00611 break;
00612 }
00613 }
00614
00615
00616 res = cuddAddGeneralVectorComposeRecur(dd,table,f,vectorOn,
00617 vectorOff,deepest);
00618 if (res != NULL) cuddRef(res);
00619
00620
00621 cuddHashTableQuit(table);
00622 } while (dd->reordered == 1);
00623
00624 if (res != NULL) cuddDeref(res);
00625 return(res);
00626
00627 }
00628
00629
00650 DdNode *
00651 Cudd_addNonSimCompose(
00652 DdManager * dd,
00653 DdNode * f,
00654 DdNode ** vector)
00655 {
00656 DdNode *cube, *key, *var, *tmp, *piece;
00657 DdNode *res;
00658 int i, lastsub;
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670 key = DD_ONE(dd);
00671 cuddRef(key);
00672 cube = DD_ONE(dd);
00673 cuddRef(cube);
00674 for (i = (int) dd->size - 1; i >= 0; i--) {
00675 if (ddIsIthAddVar(dd,vector[i],(unsigned int)i)) {
00676 continue;
00677 }
00678 var = Cudd_addIthVar(dd,i);
00679 if (var == NULL) {
00680 Cudd_RecursiveDeref(dd,key);
00681 Cudd_RecursiveDeref(dd,cube);
00682 return(NULL);
00683 }
00684 cuddRef(var);
00685
00686 tmp = Cudd_addApply(dd,Cudd_addTimes,var,cube);
00687 if (tmp == NULL) {
00688 Cudd_RecursiveDeref(dd,key);
00689 Cudd_RecursiveDeref(dd,cube);
00690 Cudd_RecursiveDeref(dd,var);
00691 return(NULL);
00692 }
00693 cuddRef(tmp);
00694 Cudd_RecursiveDeref(dd,cube);
00695 cube = tmp;
00696
00697 piece = Cudd_addApply(dd,Cudd_addXnor,var,vector[i]);
00698 if (piece == NULL) {
00699 Cudd_RecursiveDeref(dd,key);
00700 Cudd_RecursiveDeref(dd,var);
00701 return(NULL);
00702 }
00703 cuddRef(piece);
00704 Cudd_RecursiveDeref(dd,var);
00705 tmp = Cudd_addApply(dd,Cudd_addTimes,key,piece);
00706 if (tmp == NULL) {
00707 Cudd_RecursiveDeref(dd,key);
00708 Cudd_RecursiveDeref(dd,piece);
00709 return(NULL);
00710 }
00711 cuddRef(tmp);
00712 Cudd_RecursiveDeref(dd,key);
00713 Cudd_RecursiveDeref(dd,piece);
00714 key = tmp;
00715 }
00716
00717
00718 do {
00719
00720 for (lastsub = dd->size - 1; lastsub >= 0; lastsub--) {
00721 if (!ddIsIthAddVar(dd,vector[lastsub],(unsigned int)lastsub)) {
00722 break;
00723 }
00724 }
00725
00726
00727 dd->reordered = 0;
00728 res = cuddAddNonSimComposeRecur(dd,f,vector,key,cube,lastsub+1);
00729 if (res != NULL) cuddRef(res);
00730
00731 } while (dd->reordered == 1);
00732
00733 Cudd_RecursiveDeref(dd,key);
00734 Cudd_RecursiveDeref(dd,cube);
00735 if (res != NULL) cuddDeref(res);
00736 return(res);
00737
00738 }
00739
00740
00759 DdNode *
00760 Cudd_bddVectorCompose(
00761 DdManager * dd,
00762 DdNode * f,
00763 DdNode ** vector)
00764 {
00765 DdHashTable *table;
00766 DdNode *res;
00767 int deepest;
00768 int i;
00769
00770 do {
00771 dd->reordered = 0;
00772
00773 table = cuddHashTableInit(dd,1,2);
00774 if (table == NULL) return(NULL);
00775
00776
00777 for (deepest = dd->size - 1; deepest >= 0; deepest--) {
00778 i = dd->invperm[deepest];
00779 if (vector[i] != dd->vars[i]) {
00780 break;
00781 }
00782 }
00783
00784
00785 res = cuddBddVectorComposeRecur(dd,table,f,vector, deepest);
00786 if (res != NULL) cuddRef(res);
00787
00788
00789 cuddHashTableQuit(table);
00790 } while (dd->reordered == 1);
00791
00792 if (res != NULL) cuddDeref(res);
00793 return(res);
00794
00795 }
00796
00797
00798
00799
00800
00801
00802
00818 DdNode *
00819 cuddBddComposeRecur(
00820 DdManager * dd,
00821 DdNode * f,
00822 DdNode * g,
00823 DdNode * proj)
00824 {
00825 DdNode *F, *G, *f1, *f0, *g1, *g0, *r, *t, *e;
00826 unsigned int v, topf, topg, topindex;
00827 int comple;
00828
00829 statLine(dd);
00830 v = dd->perm[proj->index];
00831 F = Cudd_Regular(f);
00832 topf = cuddI(dd,F->index);
00833
00834
00835 if (topf > v) return(f);
00836
00837
00838
00839
00840 comple = Cudd_IsComplement(f);
00841
00842
00843 r = cuddCacheLookup(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj);
00844 if (r != NULL) {
00845 return(Cudd_NotCond(r,comple));
00846 }
00847
00848 if (topf == v) {
00849
00850 f1 = cuddT(F);
00851 f0 = cuddE(F);
00852 r = cuddBddIteRecur(dd, g, f1, f0);
00853 if (r == NULL) return(NULL);
00854 } else {
00855
00856
00857
00858 G = Cudd_Regular(g);
00859 topg = cuddI(dd,G->index);
00860 if (topf > topg) {
00861 topindex = G->index;
00862 f1 = f0 = F;
00863 } else {
00864 topindex = F->index;
00865 f1 = cuddT(F);
00866 f0 = cuddE(F);
00867 }
00868 if (topg > topf) {
00869 g1 = g0 = g;
00870 } else {
00871 g1 = cuddT(G);
00872 g0 = cuddE(G);
00873 if (g != G) {
00874 g1 = Cudd_Not(g1);
00875 g0 = Cudd_Not(g0);
00876 }
00877 }
00878
00879 t = cuddBddComposeRecur(dd, f1, g1, proj);
00880 if (t == NULL) return(NULL);
00881 cuddRef(t);
00882 e = cuddBddComposeRecur(dd, f0, g0, proj);
00883 if (e == NULL) {
00884 Cudd_IterDerefBdd(dd, t);
00885 return(NULL);
00886 }
00887 cuddRef(e);
00888
00889 r = cuddBddIteRecur(dd, dd->vars[topindex], t, e);
00890 if (r == NULL) {
00891 Cudd_IterDerefBdd(dd, t);
00892 Cudd_IterDerefBdd(dd, e);
00893 return(NULL);
00894 }
00895 cuddRef(r);
00896 Cudd_IterDerefBdd(dd, t);
00897 Cudd_IterDerefBdd(dd, e);
00898 cuddDeref(r);
00899 }
00900
00901 cuddCacheInsert(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj,r);
00902
00903 return(Cudd_NotCond(r,comple));
00904
00905 }
00906
00907
00920 DdNode *
00921 cuddAddComposeRecur(
00922 DdManager * dd,
00923 DdNode * f,
00924 DdNode * g,
00925 DdNode * proj)
00926 {
00927 DdNode *f1, *f0, *g1, *g0, *r, *t, *e;
00928 unsigned int v, topf, topg, topindex;
00929
00930 statLine(dd);
00931 v = dd->perm[proj->index];
00932 topf = cuddI(dd,f->index);
00933
00934
00935 if (topf > v) return(f);
00936
00937
00938 r = cuddCacheLookup(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj);
00939 if (r != NULL) {
00940 return(r);
00941 }
00942
00943 if (topf == v) {
00944
00945 f1 = cuddT(f);
00946 f0 = cuddE(f);
00947 r = cuddAddIteRecur(dd, g, f1, f0);
00948 if (r == NULL) return(NULL);
00949 } else {
00950
00951
00952
00953 topg = cuddI(dd,g->index);
00954 if (topf > topg) {
00955 topindex = g->index;
00956 f1 = f0 = f;
00957 } else {
00958 topindex = f->index;
00959 f1 = cuddT(f);
00960 f0 = cuddE(f);
00961 }
00962 if (topg > topf) {
00963 g1 = g0 = g;
00964 } else {
00965 g1 = cuddT(g);
00966 g0 = cuddE(g);
00967 }
00968
00969 t = cuddAddComposeRecur(dd, f1, g1, proj);
00970 if (t == NULL) return(NULL);
00971 cuddRef(t);
00972 e = cuddAddComposeRecur(dd, f0, g0, proj);
00973 if (e == NULL) {
00974 Cudd_RecursiveDeref(dd, t);
00975 return(NULL);
00976 }
00977 cuddRef(e);
00978
00979 if (t == e) {
00980 r = t;
00981 } else {
00982 r = cuddUniqueInter(dd, (int) topindex, t, e);
00983 if (r == NULL) {
00984 Cudd_RecursiveDeref(dd, t);
00985 Cudd_RecursiveDeref(dd, e);
00986 return(NULL);
00987 }
00988 }
00989 cuddDeref(t);
00990 cuddDeref(e);
00991 }
00992
00993 cuddCacheInsert(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj,r);
00994
00995 return(r);
00996
00997 }
00998
00999
01000
01001
01002
01003
01004
01025 static DdNode *
01026 cuddAddPermuteRecur(
01027 DdManager * manager ,
01028 DdHashTable * table ,
01029 DdNode * node ,
01030 int * permut )
01031 {
01032 DdNode *T,*E;
01033 DdNode *res,*var;
01034 int index;
01035
01036 statLine(manager);
01037
01038 if (cuddIsConstant(node)) {
01039 return(node);
01040 }
01041
01042
01043 if (node->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) {
01044 #ifdef DD_DEBUG
01045 addPermuteRecurHits++;
01046 #endif
01047 return(res);
01048 }
01049
01050
01051 T = cuddAddPermuteRecur(manager,table,cuddT(node),permut);
01052 if (T == NULL) return(NULL);
01053 cuddRef(T);
01054 E = cuddAddPermuteRecur(manager,table,cuddE(node),permut);
01055 if (E == NULL) {
01056 Cudd_RecursiveDeref(manager, T);
01057 return(NULL);
01058 }
01059 cuddRef(E);
01060
01061
01062
01063
01064
01065 index = permut[node->index];
01066 var = cuddUniqueInter(manager,index,DD_ONE(manager),DD_ZERO(manager));
01067 if (var == NULL) return(NULL);
01068 cuddRef(var);
01069 res = cuddAddIteRecur(manager,var,T,E);
01070 if (res == NULL) {
01071 Cudd_RecursiveDeref(manager,var);
01072 Cudd_RecursiveDeref(manager, T);
01073 Cudd_RecursiveDeref(manager, E);
01074 return(NULL);
01075 }
01076 cuddRef(res);
01077 Cudd_RecursiveDeref(manager,var);
01078 Cudd_RecursiveDeref(manager, T);
01079 Cudd_RecursiveDeref(manager, E);
01080
01081
01082
01083
01084 if (node->ref != 1) {
01085 ptrint fanout = (ptrint) node->ref;
01086 cuddSatDec(fanout);
01087 if (!cuddHashTableInsert1(table,node,res,fanout)) {
01088 Cudd_RecursiveDeref(manager, res);
01089 return(NULL);
01090 }
01091 }
01092 cuddDeref(res);
01093 return(res);
01094
01095 }
01096
01097
01118 static DdNode *
01119 cuddBddPermuteRecur(
01120 DdManager * manager ,
01121 DdHashTable * table ,
01122 DdNode * node ,
01123 int * permut )
01124 {
01125 DdNode *N,*T,*E;
01126 DdNode *res;
01127 int index;
01128
01129 statLine(manager);
01130 N = Cudd_Regular(node);
01131
01132
01133 if (cuddIsConstant(N)) {
01134 return(node);
01135 }
01136
01137
01138 if (N->ref != 1 && (res = cuddHashTableLookup1(table,N)) != NULL) {
01139 #ifdef DD_DEBUG
01140 bddPermuteRecurHits++;
01141 #endif
01142 return(Cudd_NotCond(res,N != node));
01143 }
01144
01145
01146 T = cuddBddPermuteRecur(manager,table,cuddT(N),permut);
01147 if (T == NULL) return(NULL);
01148 cuddRef(T);
01149 E = cuddBddPermuteRecur(manager,table,cuddE(N),permut);
01150 if (E == NULL) {
01151 Cudd_IterDerefBdd(manager, T);
01152 return(NULL);
01153 }
01154 cuddRef(E);
01155
01156
01157
01158
01159
01160 index = permut[N->index];
01161 res = cuddBddIteRecur(manager,manager->vars[index],T,E);
01162 if (res == NULL) {
01163 Cudd_IterDerefBdd(manager, T);
01164 Cudd_IterDerefBdd(manager, E);
01165 return(NULL);
01166 }
01167 cuddRef(res);
01168 Cudd_IterDerefBdd(manager, T);
01169 Cudd_IterDerefBdd(manager, E);
01170
01171
01172
01173
01174 if (N->ref != 1) {
01175 ptrint fanout = (ptrint) N->ref;
01176 cuddSatDec(fanout);
01177 if (!cuddHashTableInsert1(table,N,res,fanout)) {
01178 Cudd_IterDerefBdd(manager, res);
01179 return(NULL);
01180 }
01181 }
01182 cuddDeref(res);
01183 return(Cudd_NotCond(res,N != node));
01184
01185 }
01186
01187
01200 static DdNode *
01201 cuddBddVarMapRecur(
01202 DdManager *manager ,
01203 DdNode *f )
01204 {
01205 DdNode *F, *T, *E;
01206 DdNode *res;
01207 int index;
01208
01209 statLine(manager);
01210 F = Cudd_Regular(f);
01211
01212
01213 if (cuddIsConstant(F)) {
01214 return(f);
01215 }
01216
01217
01218 if (F->ref != 1 &&
01219 (res = cuddCacheLookup1(manager,Cudd_bddVarMap,F)) != NULL) {
01220 return(Cudd_NotCond(res,F != f));
01221 }
01222
01223
01224 T = cuddBddVarMapRecur(manager,cuddT(F));
01225 if (T == NULL) return(NULL);
01226 cuddRef(T);
01227 E = cuddBddVarMapRecur(manager,cuddE(F));
01228 if (E == NULL) {
01229 Cudd_IterDerefBdd(manager, T);
01230 return(NULL);
01231 }
01232 cuddRef(E);
01233
01234
01235
01236
01237
01238 index = manager->map[F->index];
01239 res = cuddBddIteRecur(manager,manager->vars[index],T,E);
01240 if (res == NULL) {
01241 Cudd_IterDerefBdd(manager, T);
01242 Cudd_IterDerefBdd(manager, E);
01243 return(NULL);
01244 }
01245 cuddRef(res);
01246 Cudd_IterDerefBdd(manager, T);
01247 Cudd_IterDerefBdd(manager, E);
01248
01249
01250
01251
01252 if (F->ref != 1) {
01253 cuddCacheInsert1(manager,Cudd_bddVarMap,F,res);
01254 }
01255 cuddDeref(res);
01256 return(Cudd_NotCond(res,F != f));
01257
01258 }
01259
01260
01272 static DdNode *
01273 cuddAddVectorComposeRecur(
01274 DdManager * dd ,
01275 DdHashTable * table ,
01276 DdNode * f ,
01277 DdNode ** vector ,
01278 int deepest )
01279 {
01280 DdNode *T,*E;
01281 DdNode *res;
01282
01283 statLine(dd);
01284
01285 if (cuddI(dd,f->index) > deepest) {
01286 return(f);
01287 }
01288
01289 if ((res = cuddHashTableLookup1(table,f)) != NULL) {
01290 #ifdef DD_DEBUG
01291 addVectorComposeHits++;
01292 #endif
01293 return(res);
01294 }
01295
01296
01297 T = cuddAddVectorComposeRecur(dd,table,cuddT(f),vector,deepest);
01298 if (T == NULL) return(NULL);
01299 cuddRef(T);
01300 E = cuddAddVectorComposeRecur(dd,table,cuddE(f),vector,deepest);
01301 if (E == NULL) {
01302 Cudd_RecursiveDeref(dd, T);
01303 return(NULL);
01304 }
01305 cuddRef(E);
01306
01307
01308
01309
01310 res = cuddAddIteRecur(dd,vector[f->index],T,E);
01311 if (res == NULL) {
01312 Cudd_RecursiveDeref(dd, T);
01313 Cudd_RecursiveDeref(dd, E);
01314 return(NULL);
01315 }
01316 cuddRef(res);
01317 Cudd_RecursiveDeref(dd, T);
01318 Cudd_RecursiveDeref(dd, E);
01319
01320
01321
01322
01323 if (f->ref != 1) {
01324 ptrint fanout = (ptrint) f->ref;
01325 cuddSatDec(fanout);
01326 if (!cuddHashTableInsert1(table,f,res,fanout)) {
01327 Cudd_RecursiveDeref(dd, res);
01328 return(NULL);
01329 }
01330 }
01331 cuddDeref(res);
01332 return(res);
01333
01334 }
01335
01336
01348 static DdNode *
01349 cuddAddGeneralVectorComposeRecur(
01350 DdManager * dd ,
01351 DdHashTable * table ,
01352 DdNode * f ,
01353 DdNode ** vectorOn ,
01354 DdNode ** vectorOff ,
01355 int deepest )
01356 {
01357 DdNode *T,*E,*t,*e;
01358 DdNode *res;
01359
01360
01361 if (cuddI(dd,f->index) > deepest) {
01362 return(f);
01363 }
01364
01365 if ((res = cuddHashTableLookup1(table,f)) != NULL) {
01366 #ifdef DD_DEBUG
01367 addGeneralVectorComposeHits++;
01368 #endif
01369 return(res);
01370 }
01371
01372
01373 T = cuddAddGeneralVectorComposeRecur(dd,table,cuddT(f),
01374 vectorOn,vectorOff,deepest);
01375 if (T == NULL) return(NULL);
01376 cuddRef(T);
01377 E = cuddAddGeneralVectorComposeRecur(dd,table,cuddE(f),
01378 vectorOn,vectorOff,deepest);
01379 if (E == NULL) {
01380 Cudd_RecursiveDeref(dd, T);
01381 return(NULL);
01382 }
01383 cuddRef(E);
01384
01385
01386
01387
01388 t = cuddAddApplyRecur(dd,Cudd_addTimes,vectorOn[f->index],T);
01389 if (t == NULL) {
01390 Cudd_RecursiveDeref(dd,T);
01391 Cudd_RecursiveDeref(dd,E);
01392 return(NULL);
01393 }
01394 cuddRef(t);
01395 e = cuddAddApplyRecur(dd,Cudd_addTimes,vectorOff[f->index],E);
01396 if (e == NULL) {
01397 Cudd_RecursiveDeref(dd,T);
01398 Cudd_RecursiveDeref(dd,E);
01399 Cudd_RecursiveDeref(dd,t);
01400 return(NULL);
01401 }
01402 cuddRef(e);
01403 res = cuddAddApplyRecur(dd,Cudd_addPlus,t,e);
01404 if (res == NULL) {
01405 Cudd_RecursiveDeref(dd,T);
01406 Cudd_RecursiveDeref(dd,E);
01407 Cudd_RecursiveDeref(dd,t);
01408 Cudd_RecursiveDeref(dd,e);
01409 return(NULL);
01410 }
01411 cuddRef(res);
01412 Cudd_RecursiveDeref(dd,T);
01413 Cudd_RecursiveDeref(dd,E);
01414 Cudd_RecursiveDeref(dd,t);
01415 Cudd_RecursiveDeref(dd,e);
01416
01417
01418
01419
01420 if (f->ref != 1) {
01421 ptrint fanout = (ptrint) f->ref;
01422 cuddSatDec(fanout);
01423 if (!cuddHashTableInsert1(table,f,res,fanout)) {
01424 Cudd_RecursiveDeref(dd, res);
01425 return(NULL);
01426 }
01427 }
01428 cuddDeref(res);
01429 return(res);
01430
01431 }
01432
01433
01445 static DdNode *
01446 cuddAddNonSimComposeRecur(
01447 DdManager * dd,
01448 DdNode * f,
01449 DdNode ** vector,
01450 DdNode * key,
01451 DdNode * cube,
01452 int lastsub)
01453 {
01454 DdNode *f1, *f0, *key1, *key0, *cube1, *var;
01455 DdNode *T,*E;
01456 DdNode *r;
01457 unsigned int top, topf, topk, topc;
01458 unsigned int index;
01459 int i;
01460 DdNode **vect1;
01461 DdNode **vect0;
01462
01463 statLine(dd);
01464
01465 if (cube == DD_ONE(dd) || cuddIsConstant(f)) {
01466 return(f);
01467 }
01468
01469
01470 r = cuddCacheLookup(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube);
01471 if (r != NULL) {
01472 return(r);
01473 }
01474
01475
01476
01477
01478 topf = cuddI(dd,f->index);
01479 topk = cuddI(dd,key->index);
01480 top = ddMin(topf,topk);
01481 topc = cuddI(dd,cube->index);
01482 top = ddMin(top,topc);
01483 index = dd->invperm[top];
01484
01485
01486 if (topf == top) {
01487 f1 = cuddT(f);
01488 f0 = cuddE(f);
01489 } else {
01490 f1 = f0 = f;
01491 }
01492 if (topc == top) {
01493 cube1 = cuddT(cube);
01494
01495
01496
01497
01498 var = Cudd_addIthVar(dd, (int) index);
01499 if (var == NULL) {
01500 return(NULL);
01501 }
01502 cuddRef(var);
01503 key1 = cuddAddExistAbstractRecur(dd, key, var);
01504 if (key1 == NULL) {
01505 Cudd_RecursiveDeref(dd,var);
01506 return(NULL);
01507 }
01508 cuddRef(key1);
01509 Cudd_RecursiveDeref(dd,var);
01510 key0 = key1;
01511 } else {
01512 cube1 = cube;
01513 if (topk == top) {
01514 key1 = cuddT(key);
01515 key0 = cuddE(key);
01516 } else {
01517 key1 = key0 = key;
01518 }
01519 cuddRef(key1);
01520 }
01521
01522
01523 vect1 = ALLOC(DdNode *,lastsub);
01524 if (vect1 == NULL) {
01525 dd->errorCode = CUDD_MEMORY_OUT;
01526 Cudd_RecursiveDeref(dd,key1);
01527 return(NULL);
01528 }
01529 vect0 = ALLOC(DdNode *,lastsub);
01530 if (vect0 == NULL) {
01531 dd->errorCode = CUDD_MEMORY_OUT;
01532 Cudd_RecursiveDeref(dd,key1);
01533 FREE(vect1);
01534 return(NULL);
01535 }
01536
01537
01538
01539
01540 for (i = 0; i < lastsub; i++) {
01541 DdNode *gi = vector[i];
01542 if (gi == NULL) {
01543 vect1[i] = vect0[i] = NULL;
01544 } else if (gi->index == index) {
01545 vect1[i] = cuddT(gi);
01546 vect0[i] = cuddE(gi);
01547 } else {
01548 vect1[i] = vect0[i] = gi;
01549 }
01550 }
01551 vect1[index] = vect0[index] = NULL;
01552
01553
01554 T = cuddAddNonSimComposeRecur(dd,f1,vect1,key1,cube1,lastsub);
01555 FREE(vect1);
01556 if (T == NULL) {
01557 Cudd_RecursiveDeref(dd,key1);
01558 FREE(vect0);
01559 return(NULL);
01560 }
01561 cuddRef(T);
01562 E = cuddAddNonSimComposeRecur(dd,f0,vect0,key0,cube1,lastsub);
01563 FREE(vect0);
01564 if (E == NULL) {
01565 Cudd_RecursiveDeref(dd,key1);
01566 Cudd_RecursiveDeref(dd,T);
01567 return(NULL);
01568 }
01569 cuddRef(E);
01570 Cudd_RecursiveDeref(dd,key1);
01571
01572
01573
01574
01575 r = cuddAddIteRecur(dd,vector[index],T,E);
01576 if (r == NULL) {
01577 Cudd_RecursiveDeref(dd,T);
01578 Cudd_RecursiveDeref(dd,E);
01579 return(NULL);
01580 }
01581 cuddRef(r);
01582 Cudd_RecursiveDeref(dd,T);
01583 Cudd_RecursiveDeref(dd,E);
01584 cuddDeref(r);
01585
01586
01587 cuddCacheInsert(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube,r);
01588
01589 return(r);
01590
01591 }
01592
01593
01605 static DdNode *
01606 cuddBddVectorComposeRecur(
01607 DdManager * dd ,
01608 DdHashTable * table ,
01609 DdNode * f ,
01610 DdNode ** vector ,
01611 int deepest )
01612 {
01613 DdNode *F,*T,*E;
01614 DdNode *res;
01615
01616 statLine(dd);
01617 F = Cudd_Regular(f);
01618
01619
01620 if (cuddI(dd,F->index) > deepest) {
01621 return(f);
01622 }
01623
01624
01625 if ((res = cuddHashTableLookup1(table,F)) != NULL) {
01626 #ifdef DD_DEBUG
01627 bddVectorComposeHits++;
01628 #endif
01629 return(Cudd_NotCond(res,F != f));
01630 }
01631
01632
01633 T = cuddBddVectorComposeRecur(dd,table,cuddT(F),vector, deepest);
01634 if (T == NULL) return(NULL);
01635 cuddRef(T);
01636 E = cuddBddVectorComposeRecur(dd,table,cuddE(F),vector, deepest);
01637 if (E == NULL) {
01638 Cudd_IterDerefBdd(dd, T);
01639 return(NULL);
01640 }
01641 cuddRef(E);
01642
01643
01644
01645
01646 res = cuddBddIteRecur(dd,vector[F->index],T,E);
01647 if (res == NULL) {
01648 Cudd_IterDerefBdd(dd, T);
01649 Cudd_IterDerefBdd(dd, E);
01650 return(NULL);
01651 }
01652 cuddRef(res);
01653 Cudd_IterDerefBdd(dd, T);
01654 Cudd_IterDerefBdd(dd, E);
01655
01656
01657
01658
01659 if (F->ref != 1) {
01660 ptrint fanout = (ptrint) F->ref;
01661 cuddSatDec(fanout);
01662 if (!cuddHashTableInsert1(table,F,res,fanout)) {
01663 Cudd_IterDerefBdd(dd, res);
01664 return(NULL);
01665 }
01666 }
01667 cuddDeref(res);
01668 return(Cudd_NotCond(res,F != f));
01669
01670 }
01671
01672
01685 DD_INLINE
01686 static int
01687 ddIsIthAddVar(
01688 DdManager * dd,
01689 DdNode * f,
01690 unsigned int i)
01691 {
01692 return(f->index == i && cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd));
01693
01694 }
01695
01696
01710 DD_INLINE
01711 static int
01712 ddIsIthAddVarPair(
01713 DdManager * dd,
01714 DdNode * f,
01715 DdNode * g,
01716 unsigned int i)
01717 {
01718 return(f->index == i && g->index == i &&
01719 cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd) &&
01720 cuddT(g) == DD_ZERO(dd) && cuddE(g) == DD_ONE(dd));
01721
01722 }