SVF
cuddUtil.c
Go to the documentation of this file.
1 
113 #include "CUDD/util.h"
114 #include "CUDD/cuddInt.h"
115 
116 /*---------------------------------------------------------------------------*/
117 /* Constant declarations */
118 /*---------------------------------------------------------------------------*/
119 
120 /* Random generator constants. */
121 #define MODULUS1 2147483563
122 #define LEQA1 40014
123 #define LEQQ1 53668
124 #define LEQR1 12211
125 #define MODULUS2 2147483399
126 #define LEQA2 40692
127 #define LEQQ2 52774
128 #define LEQR2 3791
129 #define STAB_SIZE 64
130 #define STAB_DIV (1 + (MODULUS1 - 1) / STAB_SIZE)
131 
132 /*---------------------------------------------------------------------------*/
133 /* Stucture declarations */
134 /*---------------------------------------------------------------------------*/
135 
136 /*---------------------------------------------------------------------------*/
137 /* Type declarations */
138 /*---------------------------------------------------------------------------*/
139 
140 
141 /*---------------------------------------------------------------------------*/
142 /* Variable declarations */
143 /*---------------------------------------------------------------------------*/
144 
145 #ifndef lint
146 static char rcsid[] DD_UNUSED = "$Id: cuddUtil.c,v 1.83 2012/02/05 01:07:19 fabio Exp $";
147 #endif
148 
150 
151 static long cuddRand = 0;
152 static long cuddRand2;
153 static long shuffleSelect;
154 static long shuffleTable[STAB_SIZE];
155 
156 /*---------------------------------------------------------------------------*/
157 /* Macro declarations */
158 /*---------------------------------------------------------------------------*/
159 
160 #define bang(f) ((Cudd_IsComplement(f)) ? '!' : ' ')
161 
162 #ifdef __cplusplus
163 extern "C" {
164 #endif
165 
168 /*---------------------------------------------------------------------------*/
169 /* Static function prototypes */
170 /*---------------------------------------------------------------------------*/
171 
172 static int dp2 (DdManager *dd, DdNode *f, st_table *t);
173 static void ddPrintMintermAux (DdManager *dd, DdNode *node, int *list);
174 static int ddDagInt (DdNode *n);
175 static int cuddNodeArrayRecur (DdNode *f, DdNodePtr *table, int index);
176 static int cuddEstimateCofactor (DdManager *dd, st_table *table, DdNode * node, int i, int phase, DdNode ** ptr);
177 static DdNode * cuddUniqueLookup (DdManager * unique, int index, DdNode * T, DdNode * E);
178 static int cuddEstimateCofactorSimple (DdNode * node, int i);
179 static double ddCountMintermAux (DdNode *node, double max, DdHashTable *table);
180 static int ddEpdCountMintermAux (DdNode *node, EpDouble *max, EpDouble *epd, st_table *table);
181 static double ddCountPathAux (DdNode *node, st_table *table);
182 static double ddCountPathsToNonZero (DdNode * N, st_table * table);
183 static void ddSupportStep (DdNode *f, int *support);
184 static void ddClearFlag (DdNode *f);
185 static int ddLeavesInt (DdNode *n);
186 static int ddPickArbitraryMinterms (DdManager *dd, DdNode *node, int nvars, int nminterms, char **string);
187 static int ddPickRepresentativeCube (DdManager *dd, DdNode *node, double *weight, char *string);
188 static enum st_retval ddEpdFree (char * key, char * value, char * arg);
189 static void ddFindSupport(DdManager *dd, DdNode *f, int *SP);
190 static void ddClearVars(DdManager *dd, int SP);
191 static int indexCompare(const void *a, const void *b);
192 
195 #ifdef __cplusplus
196 }
197 #endif
198 
199 /*---------------------------------------------------------------------------*/
200 /* Definition of exported functions */
201 /*---------------------------------------------------------------------------*/
202 
203 
219 int
221  DdManager * manager,
222  DdNode * node)
223 {
224  int i, *list;
225 
226  background = manager->background;
227  zero = Cudd_Not(manager->one);
228  list = ALLOC(int,manager->size);
229  if (list == NULL) {
230  manager->errorCode = CUDD_MEMORY_OUT;
231  return(0);
232  }
233  for (i = 0; i < manager->size; i++) list[i] = 2;
234  ddPrintMintermAux(manager,node,list);
235  FREE(list);
236  return(1);
237 
238 } /* end of Cudd_PrintMinterm */
239 
240 
256 int
258  DdManager *dd,
259  DdNode *l,
260  DdNode *u)
261 {
262  int *array;
263  int q, result;
264  DdNode *lb;
265 #ifdef DD_DEBUG
266  DdNode *cover;
267 #endif
268 
269  array = ALLOC(int, Cudd_ReadSize(dd));
270  if (array == NULL) return(0);
271  lb = l;
272  cuddRef(lb);
273 #ifdef DD_DEBUG
274  cover = Cudd_ReadLogicZero(dd);
275  cuddRef(cover);
276 #endif
277  while (lb != Cudd_ReadLogicZero(dd)) {
278  DdNode *implicant, *prime, *tmp;
279  int length;
280  implicant = Cudd_LargestCube(dd,lb,&length);
281  if (implicant == NULL) {
282  Cudd_RecursiveDeref(dd,lb);
283  FREE(array);
284  return(0);
285  }
286  cuddRef(implicant);
287  prime = Cudd_bddMakePrime(dd,implicant,u);
288  if (prime == NULL) {
289  Cudd_RecursiveDeref(dd,lb);
290  Cudd_RecursiveDeref(dd,implicant);
291  FREE(array);
292  return(0);
293  }
294  cuddRef(prime);
295  Cudd_RecursiveDeref(dd,implicant);
296  tmp = Cudd_bddAnd(dd,lb,Cudd_Not(prime));
297  if (tmp == NULL) {
298  Cudd_RecursiveDeref(dd,lb);
299  Cudd_RecursiveDeref(dd,prime);
300  FREE(array);
301  return(0);
302  }
303  cuddRef(tmp);
304  Cudd_RecursiveDeref(dd,lb);
305  lb = tmp;
306  result = Cudd_BddToCubeArray(dd,prime,array);
307  if (result == 0) {
308  Cudd_RecursiveDeref(dd,lb);
309  Cudd_RecursiveDeref(dd,prime);
310  FREE(array);
311  return(0);
312  }
313  for (q = 0; q < dd->size; q++) {
314  switch (array[q]) {
315  case 0:
316  (void) fprintf(dd->out, "0");
317  break;
318  case 1:
319  (void) fprintf(dd->out, "1");
320  break;
321  case 2:
322  (void) fprintf(dd->out, "-");
323  break;
324  default:
325  (void) fprintf(dd->out, "?");
326  }
327  }
328  (void) fprintf(dd->out, " 1\n");
329 #ifdef DD_DEBUG
330  tmp = Cudd_bddOr(dd,prime,cover);
331  if (tmp == NULL) {
332  Cudd_RecursiveDeref(dd,cover);
333  Cudd_RecursiveDeref(dd,lb);
334  Cudd_RecursiveDeref(dd,prime);
335  FREE(array);
336  return(0);
337  }
338  cuddRef(tmp);
339  Cudd_RecursiveDeref(dd,cover);
340  cover = tmp;
341 #endif
342  Cudd_RecursiveDeref(dd,prime);
343  }
344  (void) fprintf(dd->out, "\n");
345  Cudd_RecursiveDeref(dd,lb);
346  FREE(array);
347 #ifdef DD_DEBUG
348  if (!Cudd_bddLeq(dd,cover,u) || !Cudd_bddLeq(dd,l,cover)) {
349  Cudd_RecursiveDeref(dd,cover);
350  return(0);
351  }
352  Cudd_RecursiveDeref(dd,cover);
353 #endif
354  return(1);
355 
356 } /* end of Cudd_bddPrintCover */
357 
358 
385 int
387  DdManager * dd,
388  DdNode * f,
389  int n,
390  int pr)
391 {
392  DdNode *azero, *bzero;
393  int nodes;
394  int leaves;
395  double minterms;
396  int retval = 1;
397 
398  if (f == NULL) {
399  (void) fprintf(dd->out,": is the NULL DD\n");
400  (void) fflush(dd->out);
401  return(0);
402  }
403  azero = DD_ZERO(dd);
404  bzero = Cudd_Not(DD_ONE(dd));
405  if ((f == azero || f == bzero) && pr > 0){
406  (void) fprintf(dd->out,": is the zero DD\n");
407  (void) fflush(dd->out);
408  return(1);
409  }
410  if (pr > 0) {
411  nodes = Cudd_DagSize(f);
412  if (nodes == CUDD_OUT_OF_MEM) retval = 0;
413  leaves = Cudd_CountLeaves(f);
414  if (leaves == CUDD_OUT_OF_MEM) retval = 0;
415  minterms = Cudd_CountMinterm(dd, f, n);
416  if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0;
417  (void) fprintf(dd->out,": %d nodes %d leaves %g minterms\n",
418  nodes, leaves, minterms);
419  if (pr > 2) {
420  if (!cuddP(dd, f)) retval = 0;
421  }
422  if (pr == 2 || pr > 3) {
423  if (!Cudd_PrintMinterm(dd,f)) retval = 0;
424  (void) fprintf(dd->out,"\n");
425  }
426  (void) fflush(dd->out);
427  }
428  return(retval);
429 
430 } /* end of Cudd_PrintDebug */
431 
432 
445 int
447  DdNode * node)
448 {
449  int i;
450 
451  i = ddDagInt(Cudd_Regular(node));
452  ddClearFlag(Cudd_Regular(node));
453 
454  return(i);
455 
456 } /* end of Cudd_DagSize */
457 
458 
480 int
482  DdManager *dd /* manager */,
483  DdNode * f /* function */,
484  int i /* index of variable */,
485  int phase /* 1: positive; 0: negative */
486  )
487 {
488  int val;
489  DdNode *ptr;
490  st_table *table;
491 
493  if (table == NULL) return(CUDD_OUT_OF_MEM);
494  val = cuddEstimateCofactor(dd,table,Cudd_Regular(f),i,phase,&ptr);
496  st_free_table(table);
497 
498  return(val);
499 
500 } /* end of Cudd_EstimateCofactor */
501 
502 
520 int
522  DdNode * node,
523  int i)
524 {
525  int val;
526 
528  ddClearFlag(Cudd_Regular(node));
529 
530  return(val);
531 
532 } /* end of Cudd_EstimateCofactorSimple */
533 
534 
547 int
549  DdNode ** nodeArray,
550  int n)
551 {
552  int i,j;
553 
554  i = 0;
555  for (j = 0; j < n; j++) {
556  i += ddDagInt(Cudd_Regular(nodeArray[j]));
557  }
558  for (j = 0; j < n; j++) {
559  ddClearFlag(Cudd_Regular(nodeArray[j]));
560  }
561  return(i);
562 
563 } /* end of Cudd_SharingSize */
564 
565 
581 double
583  DdManager * manager,
584  DdNode * node,
585  int nvars)
586 {
587  double max;
588  DdHashTable *table;
589  double res;
590  CUDD_VALUE_TYPE epsilon;
591 
592  background = manager->background;
593  zero = Cudd_Not(manager->one);
594 
595  max = pow(2.0,(double)nvars);
596  table = cuddHashTableInit(manager,1,2);
597  if (table == NULL) {
598  return((double)CUDD_OUT_OF_MEM);
599  }
600  epsilon = Cudd_ReadEpsilon(manager);
601  Cudd_SetEpsilon(manager,(CUDD_VALUE_TYPE)0.0);
602  res = ddCountMintermAux(node,max,table);
603  cuddHashTableQuit(table);
604  Cudd_SetEpsilon(manager,epsilon);
605 
606  return(res);
607 
608 } /* end of Cudd_CountMinterm */
609 
610 
626 double
628  DdNode * node)
629 {
630 
631  st_table *table;
632  double i;
633 
635  if (table == NULL) {
636  return((double)CUDD_OUT_OF_MEM);
637  }
638  i = ddCountPathAux(Cudd_Regular(node),table);
639  st_foreach(table, cuddStCountfree, NULL);
640  st_free_table(table);
641  return(i);
642 
643 } /* end of Cudd_CountPath */
644 
645 
660 int
662  DdManager * manager,
663  DdNode * node,
664  int nvars,
665  EpDouble * epd)
666 {
667  EpDouble max, tmp;
668  st_table *table;
669  int status;
670 
671  background = manager->background;
672  zero = Cudd_Not(manager->one);
673 
674  EpdPow2(nvars, &max);
675  table = st_init_table(EpdCmp, st_ptrhash);
676  if (table == NULL) {
677  EpdMakeZero(epd, 0);
678  return(CUDD_OUT_OF_MEM);
679  }
680  status = ddEpdCountMintermAux(Cudd_Regular(node),&max,epd,table);
681  st_foreach(table, ddEpdFree, NULL);
682  st_free_table(table);
683  if (status == CUDD_OUT_OF_MEM) {
684  EpdMakeZero(epd, 0);
685  return(CUDD_OUT_OF_MEM);
686  }
687  if (Cudd_IsComplement(node)) {
688  EpdSubtract3(&max, epd, &tmp);
689  EpdCopy(&tmp, epd);
690  }
691  return(0);
692 
693 } /* end of Cudd_EpdCountMinterm */
694 
695 
710 double
712  DdNode * node)
713 {
714 
715  st_table *table;
716  double i;
717 
719  if (table == NULL) {
720  return((double)CUDD_OUT_OF_MEM);
721  }
722  i = ddCountPathsToNonZero(node,table);
723  st_foreach(table, cuddStCountfree, NULL);
724  st_free_table(table);
725  return(i);
726 
727 } /* end of Cudd_CountPathsToNonZero */
728 
729 
743 int
745  DdManager * dd /* manager */,
746  DdNode * f /* DD whose support is sought */,
747  int **indices /* array containing (on return) the indices */)
748 {
749  int SP = 0;
750 
751  ddFindSupport(dd, Cudd_Regular(f), &SP);
753  ddClearVars(dd, SP);
754  if (SP > 0) {
755  int i;
756  *indices = ALLOC(int, SP);
757  if (*indices == NULL) {
759  return(CUDD_OUT_OF_MEM);
760  }
761 
762  for (i = 0; i < SP; i++)
763  (*indices)[i] = (int) (ptrint) dd->stack[i];
764 
765  qsort(*indices, SP, sizeof(int), indexCompare);
766  } else {
767  *indices = NULL;
768  }
769 
770  return(SP);
771 
772 } /* end of Cudd_SupportIndices */
773 
774 
788 DdNode *
790  DdManager * dd /* manager */,
791  DdNode * f /* DD whose support is sought */)
792 {
793  int *support;
794  DdNode *res;
795  int j;
796 
797  int size = Cudd_SupportIndices(dd, f, &support);
798  if (size == CUDD_OUT_OF_MEM)
799  return(NULL);
800 
801  /* Transform support from array of indices to cube. */
802  res = DD_ONE(dd);
803  cuddRef(res);
804 
805  for (j = size - 1; j >= 0; j--) { /* for each index bottom-up (almost) */
806  int index = support[j];
807  DdNode *var = dd->vars[index];
808  DdNode *tmp = Cudd_bddAnd(dd,res,var);
809  if (tmp == NULL) {
810  Cudd_RecursiveDeref(dd,res);
811  FREE(support);
812  return(NULL);
813  }
814  cuddRef(tmp);
815  Cudd_RecursiveDeref(dd,res);
816  res = tmp;
817  }
818 
819  FREE(support);
820  cuddDeref(res);
821  return(res);
822 
823 } /* end of Cudd_Support */
824 
825 
841 int *
843  DdManager * dd /* manager */,
844  DdNode * f /* DD whose support is sought */)
845 {
846  int *support;
847  int i;
848  int size;
849 
850  /* Allocate and initialize support array for ddSupportStep. */
851  size = ddMax(dd->size, dd->sizeZ);
852  support = ALLOC(int,size);
853  if (support == NULL) {
855  return(NULL);
856  }
857  for (i = 0; i < size; i++) {
858  support[i] = 0;
859  }
860 
861  /* Compute support and clean up markers. */
862  ddSupportStep(Cudd_Regular(f),support);
864 
865  return(support);
866 
867 } /* end of Cudd_SupportIndex */
868 
869 
881 int
883  DdManager * dd /* manager */,
884  DdNode * f /* DD whose support size is sought */)
885 {
886  int SP = 0;
887 
888  ddFindSupport(dd, Cudd_Regular(f), &SP);
890  ddClearVars(dd, SP);
891 
892  return(SP);
893 
894 } /* end of Cudd_SupportSize */
895 
896 
911 int
913  DdManager * dd /* manager */,
914  DdNode ** F /* DD whose support is sought */,
915  int n /* size of the array */,
916  int **indices /* array containing (on return) the indices */)
917 {
918  int i;
919  int SP = 0;
920 
921  /* Compute support and clean up markers. */
922  for (i = 0; i < n; i++) {
923  ddFindSupport(dd, Cudd_Regular(F[i]), &SP);
924  }
925  for (i = 0; i < n; i++) {
926  ddClearFlag(Cudd_Regular(F[i]));
927  }
928  ddClearVars(dd, SP);
929 
930  if (SP > 0) {
931  int i;
932  *indices = ALLOC(int, SP);
933  if (*indices == NULL) {
935  return(CUDD_OUT_OF_MEM);
936  }
937 
938  for (i = 0; i < SP; i++)
939  (*indices)[i] = (int) (ptrint) dd->stack[i];
940 
941  qsort(*indices, SP, sizeof(int), indexCompare);
942  } else {
943  *indices = NULL;
944  }
945 
946  return(SP);
947 
948 } /* end of Cudd_VectorSupportIndices */
949 
950 
965 DdNode *
967  DdManager * dd /* manager */,
968  DdNode ** F /* array of DDs whose support is sought */,
969  int n /* size of the array */)
970 {
971  int *support;
972  DdNode *res;
973  int j;
974  int size = Cudd_VectorSupportIndices(dd, F, n, &support);
975  if (size == CUDD_OUT_OF_MEM)
976  return(NULL);
977 
978  /* Transform support from array of indices to cube. */
979  res = DD_ONE(dd);
980  cuddRef(res);
981 
982  for (j = size - 1; j >= 0; j--) { /* for each index bottom-up (almost) */
983  int index = support[j];
984  DdNode *var = dd->vars[index];
985  DdNode *tmp = Cudd_bddAnd(dd,res,var);
986  if (tmp == NULL) {
987  Cudd_RecursiveDeref(dd,res);
988  FREE(support);
989  return(NULL);
990  }
991  cuddRef(tmp);
992  Cudd_RecursiveDeref(dd,res);
993  res = tmp;
994  }
995 
996  FREE(support);
997  cuddDeref(res);
998  return(res);
999 
1000 } /* end of Cudd_VectorSupport */
1001 
1002 
1016 int *
1018  DdManager * dd /* manager */,
1019  DdNode ** F /* array of DDs whose support is sought */,
1020  int n /* size of the array */)
1021 {
1022  int *support;
1023  int i;
1024  int size;
1025 
1026  /* Allocate and initialize support array for ddSupportStep. */
1027  size = ddMax(dd->size, dd->sizeZ);
1028  support = ALLOC(int,size);
1029  if (support == NULL) {
1030  dd->errorCode = CUDD_MEMORY_OUT;
1031  return(NULL);
1032  }
1033  for (i = 0; i < size; i++) {
1034  support[i] = 0;
1035  }
1036 
1037  /* Compute support and clean up markers. */
1038  for (i = 0; i < n; i++) {
1039  ddSupportStep(Cudd_Regular(F[i]),support);
1040  }
1041  for (i = 0; i < n; i++) {
1042  ddClearFlag(Cudd_Regular(F[i]));
1043  }
1044 
1045  return(support);
1046 
1047 } /* end of Cudd_VectorSupportIndex */
1048 
1049 
1062 int
1064  DdManager * dd /* manager */,
1065  DdNode ** F /* array of DDs whose support is sought */,
1066  int n /* size of the array */)
1067 {
1068  int i;
1069  int SP = 0;
1070 
1071  /* Compute support and clean up markers. */
1072  for (i = 0; i < n; i++) {
1073  ddFindSupport(dd, Cudd_Regular(F[i]), &SP);
1074  }
1075  for (i = 0; i < n; i++) {
1076  ddClearFlag(Cudd_Regular(F[i]));
1077  }
1078  ddClearVars(dd, SP);
1079 
1080  return(SP);
1081 
1082 } /* end of Cudd_VectorSupportSize */
1083 
1084 
1100 int
1102  DdManager * dd /* manager */,
1103  DdNode * f /* first DD */,
1104  DdNode * g /* second DD */,
1105  DdNode ** common /* cube of shared variables */,
1106  DdNode ** onlyF /* cube of variables only in f */,
1107  DdNode ** onlyG /* cube of variables only in g */)
1108 {
1109  int *supportF, *supportG;
1110  int fi, gi;
1111  int sizeF, sizeG;
1112 
1113  sizeF = Cudd_SupportIndices(dd, f, &supportF);
1114  if (sizeF == CUDD_OUT_OF_MEM)
1115  return(0);
1116 
1117  sizeG = Cudd_SupportIndices(dd, g, &supportG);
1118  if (sizeG == CUDD_OUT_OF_MEM) {
1119  FREE(supportF);
1120  return(0);
1121  }
1122 
1123  /* Classify variables and create cubes. This part of the procedure
1124  ** relies on the sorting of the indices in the two support arrays.
1125  */
1126  *common = *onlyF = *onlyG = DD_ONE(dd);
1127  cuddRef(*common); cuddRef(*onlyF); cuddRef(*onlyG);
1128  fi = sizeF - 1;
1129  gi = sizeG - 1;
1130  while (fi >= 0 || gi >= 0) {
1131  int indexF = fi >= 0 ? supportF[fi] : -1;
1132  int indexG = gi >= 0 ? supportG[gi] : -1;
1133  int index = ddMax(indexF, indexG);
1134  DdNode *var = dd->vars[index];
1135 #ifdef DD_DEBUG
1136  assert(index >= 0);
1137 #endif
1138  if (indexF == indexG) {
1139  DdNode *tmp = Cudd_bddAnd(dd,*common,var);
1140  if (tmp == NULL) {
1141  Cudd_RecursiveDeref(dd,*common);
1142  Cudd_RecursiveDeref(dd,*onlyF);
1143  Cudd_RecursiveDeref(dd,*onlyG);
1144  FREE(supportF); FREE(supportG);
1145  return(0);
1146  }
1147  cuddRef(tmp);
1148  Cudd_RecursiveDeref(dd,*common);
1149  *common = tmp;
1150  fi--;
1151  gi--;
1152  } else if (index == indexF) {
1153  DdNode *tmp = Cudd_bddAnd(dd,*onlyF,var);
1154  if (tmp == NULL) {
1155  Cudd_RecursiveDeref(dd,*common);
1156  Cudd_RecursiveDeref(dd,*onlyF);
1157  Cudd_RecursiveDeref(dd,*onlyG);
1158  FREE(supportF); FREE(supportG);
1159  return(0);
1160  }
1161  cuddRef(tmp);
1162  Cudd_RecursiveDeref(dd,*onlyF);
1163  *onlyF = tmp;
1164  fi--;
1165  } else { /* index == indexG */
1166  DdNode *tmp = Cudd_bddAnd(dd,*onlyG,var);
1167  if (tmp == NULL) {
1168  Cudd_RecursiveDeref(dd,*common);
1169  Cudd_RecursiveDeref(dd,*onlyF);
1170  Cudd_RecursiveDeref(dd,*onlyG);
1171  FREE(supportF); FREE(supportG);
1172  return(0);
1173  }
1174  cuddRef(tmp);
1175  Cudd_RecursiveDeref(dd,*onlyG);
1176  *onlyG = tmp;
1177  gi--;
1178  }
1179  }
1180 
1181  FREE(supportF); FREE(supportG);
1182  cuddDeref(*common); cuddDeref(*onlyF); cuddDeref(*onlyG);
1183  return(1);
1184 
1185 } /* end of Cudd_ClassifySupport */
1186 
1187 
1201 int
1203  DdNode * node)
1204 {
1205  int i;
1206 
1207  i = ddLeavesInt(Cudd_Regular(node));
1208  ddClearFlag(Cudd_Regular(node));
1209  return(i);
1210 
1211 } /* end of Cudd_CountLeaves */
1212 
1213 
1228 int
1230  DdManager * ddm,
1231  DdNode * node,
1232  char * string)
1233 {
1234  DdNode *N, *T, *E;
1235  DdNode *one, *bzero;
1236  char dir;
1237  int i;
1238 
1239  if (string == NULL || node == NULL) return(0);
1240 
1241  /* The constant 0 function has no on-set cubes. */
1242  one = DD_ONE(ddm);
1243  bzero = Cudd_Not(one);
1244  if (node == bzero) return(0);
1245 
1246  for (i = 0; i < ddm->size; i++) string[i] = 2;
1247 
1248  for (;;) {
1249 
1250  if (node == one) break;
1251 
1252  N = Cudd_Regular(node);
1253 
1254  T = cuddT(N); E = cuddE(N);
1255  if (Cudd_IsComplement(node)) {
1256  T = Cudd_Not(T); E = Cudd_Not(E);
1257  }
1258  if (T == bzero) {
1259  string[N->index] = 0;
1260  node = E;
1261  } else if (E == bzero) {
1262  string[N->index] = 1;
1263  node = T;
1264  } else {
1265  dir = (char) ((Cudd_Random() & 0x2000) >> 13);
1266  string[N->index] = dir;
1267  node = dir ? T : E;
1268  }
1269  }
1270  return(1);
1271 
1272 } /* end of Cudd_bddPickOneCube */
1273 
1274 
1298 DdNode *
1300  DdManager * dd /* manager */,
1301  DdNode * f /* function from which to pick one minterm */,
1302  DdNode ** vars /* array of variables */,
1303  int n /* size of <code>vars</code> */)
1304 {
1305  char *string;
1306  int i, size;
1307  int *indices;
1308  int result;
1309  DdNode *old, *neW;
1310 
1311  size = dd->size;
1312  string = ALLOC(char, size);
1313  if (string == NULL) {
1314  dd->errorCode = CUDD_MEMORY_OUT;
1315  return(NULL);
1316  }
1317  indices = ALLOC(int,n);
1318  if (indices == NULL) {
1319  dd->errorCode = CUDD_MEMORY_OUT;
1320  FREE(string);
1321  return(NULL);
1322  }
1323 
1324  for (i = 0; i < n; i++) {
1325  indices[i] = vars[i]->index;
1326  }
1327 
1328  result = Cudd_bddPickOneCube(dd,f,string);
1329  if (result == 0) {
1330  FREE(string);
1331  FREE(indices);
1332  return(NULL);
1333  }
1334 
1335  /* Randomize choice for don't cares. */
1336  for (i = 0; i < n; i++) {
1337  if (string[indices[i]] == 2)
1338  string[indices[i]] = (char) ((Cudd_Random() & 0x20) >> 5);
1339  }
1340 
1341  /* Build result BDD. */
1342  old = Cudd_ReadOne(dd);
1343  cuddRef(old);
1344 
1345  for (i = n-1; i >= 0; i--) {
1346  neW = Cudd_bddAnd(dd,old,Cudd_NotCond(vars[i],string[indices[i]]==0));
1347  if (neW == NULL) {
1348  FREE(string);
1349  FREE(indices);
1350  Cudd_RecursiveDeref(dd,old);
1351  return(NULL);
1352  }
1353  cuddRef(neW);
1354  Cudd_RecursiveDeref(dd,old);
1355  old = neW;
1356  }
1357 
1358 #ifdef DD_DEBUG
1359  /* Test. */
1360  if (Cudd_bddLeq(dd,old,f)) {
1361  cuddDeref(old);
1362  } else {
1363  Cudd_RecursiveDeref(dd,old);
1364  old = NULL;
1365  }
1366 #else
1367  cuddDeref(old);
1368 #endif
1369 
1370  FREE(string);
1371  FREE(indices);
1372  return(old);
1373 
1374 } /* end of Cudd_bddPickOneMinterm */
1375 
1376 
1400 DdNode **
1402  DdManager * dd /* manager */,
1403  DdNode * f /* function from which to pick k minterms */,
1404  DdNode ** vars /* array of variables */,
1405  int n /* size of <code>vars</code> */,
1406  int k /* number of minterms to find */)
1407 {
1408  char **string;
1409  int i, j, l, size;
1410  int *indices;
1411  int result;
1412  DdNode **old, *neW;
1413  double minterms;
1414  char *saveString;
1415  int saveFlag, savePoint, isSame;
1416 
1417  minterms = Cudd_CountMinterm(dd,f,n);
1418  if ((double)k > minterms) {
1419  return(NULL);
1420  }
1421 
1422  size = dd->size;
1423  string = ALLOC(char *, k);
1424  if (string == NULL) {
1425  dd->errorCode = CUDD_MEMORY_OUT;
1426  return(NULL);
1427  }
1428  for (i = 0; i < k; i++) {
1429  string[i] = ALLOC(char, size + 1);
1430  if (string[i] == NULL) {
1431  for (j = 0; j < i; j++)
1432  FREE(string[i]);
1433  FREE(string);
1434  dd->errorCode = CUDD_MEMORY_OUT;
1435  return(NULL);
1436  }
1437  for (j = 0; j < size; j++) string[i][j] = '2';
1438  string[i][size] = '\0';
1439  }
1440  indices = ALLOC(int,n);
1441  if (indices == NULL) {
1442  dd->errorCode = CUDD_MEMORY_OUT;
1443  for (i = 0; i < k; i++)
1444  FREE(string[i]);
1445  FREE(string);
1446  return(NULL);
1447  }
1448 
1449  for (i = 0; i < n; i++) {
1450  indices[i] = vars[i]->index;
1451  }
1452 
1453  result = ddPickArbitraryMinterms(dd,f,n,k,string);
1454  if (result == 0) {
1455  for (i = 0; i < k; i++)
1456  FREE(string[i]);
1457  FREE(string);
1458  FREE(indices);
1459  return(NULL);
1460  }
1461 
1462  old = ALLOC(DdNode *, k);
1463  if (old == NULL) {
1464  dd->errorCode = CUDD_MEMORY_OUT;
1465  for (i = 0; i < k; i++)
1466  FREE(string[i]);
1467  FREE(string);
1468  FREE(indices);
1469  return(NULL);
1470  }
1471  saveString = ALLOC(char, size + 1);
1472  if (saveString == NULL) {
1473  dd->errorCode = CUDD_MEMORY_OUT;
1474  for (i = 0; i < k; i++)
1475  FREE(string[i]);
1476  FREE(string);
1477  FREE(indices);
1478  FREE(old);
1479  return(NULL);
1480  }
1481  saveFlag = 0;
1482 
1483  /* Build result BDD array. */
1484  for (i = 0; i < k; i++) {
1485  isSame = 0;
1486  if (!saveFlag) {
1487  for (j = i + 1; j < k; j++) {
1488  if (strcmp(string[i], string[j]) == 0) {
1489  savePoint = i;
1490  strcpy(saveString, string[i]);
1491  saveFlag = 1;
1492  break;
1493  }
1494  }
1495  } else {
1496  if (strcmp(string[i], saveString) == 0) {
1497  isSame = 1;
1498  } else {
1499  saveFlag = 0;
1500  for (j = i + 1; j < k; j++) {
1501  if (strcmp(string[i], string[j]) == 0) {
1502  savePoint = i;
1503  strcpy(saveString, string[i]);
1504  saveFlag = 1;
1505  break;
1506  }
1507  }
1508  }
1509  }
1510  /* Randomize choice for don't cares. */
1511  for (j = 0; j < n; j++) {
1512  if (string[i][indices[j]] == '2')
1513  string[i][indices[j]] =
1514  (char) ((Cudd_Random() & 0x20) ? '1' : '0');
1515  }
1516 
1517  while (isSame) {
1518  isSame = 0;
1519  for (j = savePoint; j < i; j++) {
1520  if (strcmp(string[i], string[j]) == 0) {
1521  isSame = 1;
1522  break;
1523  }
1524  }
1525  if (isSame) {
1526  strcpy(string[i], saveString);
1527  /* Randomize choice for don't cares. */
1528  for (j = 0; j < n; j++) {
1529  if (string[i][indices[j]] == '2')
1530  string[i][indices[j]] =
1531  (char) ((Cudd_Random() & 0x20) ? '1' : '0');
1532  }
1533  }
1534  }
1535 
1536  old[i] = Cudd_ReadOne(dd);
1537  cuddRef(old[i]);
1538 
1539  for (j = 0; j < n; j++) {
1540  if (string[i][indices[j]] == '0') {
1541  neW = Cudd_bddAnd(dd,old[i],Cudd_Not(vars[j]));
1542  } else {
1543  neW = Cudd_bddAnd(dd,old[i],vars[j]);
1544  }
1545  if (neW == NULL) {
1546  FREE(saveString);
1547  for (l = 0; l < k; l++)
1548  FREE(string[l]);
1549  FREE(string);
1550  FREE(indices);
1551  for (l = 0; l <= i; l++)
1552  Cudd_RecursiveDeref(dd,old[l]);
1553  FREE(old);
1554  return(NULL);
1555  }
1556  cuddRef(neW);
1557  Cudd_RecursiveDeref(dd,old[i]);
1558  old[i] = neW;
1559  }
1560 
1561  /* Test. */
1562  if (!Cudd_bddLeq(dd,old[i],f)) {
1563  FREE(saveString);
1564  for (l = 0; l < k; l++)
1565  FREE(string[l]);
1566  FREE(string);
1567  FREE(indices);
1568  for (l = 0; l <= i; l++)
1569  Cudd_RecursiveDeref(dd,old[l]);
1570  FREE(old);
1571  return(NULL);
1572  }
1573  }
1574 
1575  FREE(saveString);
1576  for (i = 0; i < k; i++) {
1577  cuddDeref(old[i]);
1578  FREE(string[i]);
1579  }
1580  FREE(string);
1581  FREE(indices);
1582  return(old);
1583 
1584 } /* end of Cudd_bddPickArbitraryMinterms */
1585 
1586 
1609 DdNode *
1611  DdManager * dd /* manager */,
1612  DdNode * f /* function from which to pick a cube */,
1613  DdNode ** vars /* array of variables */,
1614  int nvars /* size of <code>vars</code> */,
1615  DdNode ** maskVars /* array of variables */,
1616  int mvars /* size of <code>maskVars</code> */)
1617 {
1618  double *weight;
1619  char *string;
1620  int i, size;
1621  int *indices, *mask;
1622  int result;
1623  DdNode *zero, *cube, *newCube, *subset;
1624  DdNode *cof;
1625 
1626  DdNode *support;
1627  support = Cudd_Support(dd,f);
1628  cuddRef(support);
1629  Cudd_RecursiveDeref(dd,support);
1630 
1631  zero = Cudd_Not(dd->one);
1632  size = dd->size;
1633 
1634  weight = ALLOC(double,size);
1635  if (weight == NULL) {
1636  dd->errorCode = CUDD_MEMORY_OUT;
1637  return(NULL);
1638  }
1639  for (i = 0; i < size; i++) {
1640  weight[i] = 0.0;
1641  }
1642  for (i = 0; i < mvars; i++) {
1643  cof = Cudd_Cofactor(dd, f, maskVars[i]);
1644  cuddRef(cof);
1645  weight[i] = Cudd_CountMinterm(dd, cof, nvars);
1646  Cudd_RecursiveDeref(dd,cof);
1647 
1648  cof = Cudd_Cofactor(dd, f, Cudd_Not(maskVars[i]));
1649  cuddRef(cof);
1650  weight[i] -= Cudd_CountMinterm(dd, cof, nvars);
1651  Cudd_RecursiveDeref(dd,cof);
1652  }
1653 
1654  string = ALLOC(char, size + 1);
1655  if (string == NULL) {
1656  dd->errorCode = CUDD_MEMORY_OUT;
1657  FREE(weight);
1658  return(NULL);
1659  }
1660  mask = ALLOC(int, size);
1661  if (mask == NULL) {
1662  dd->errorCode = CUDD_MEMORY_OUT;
1663  FREE(weight);
1664  FREE(string);
1665  return(NULL);
1666  }
1667  for (i = 0; i < size; i++) {
1668  string[i] = '2';
1669  mask[i] = 0;
1670  }
1671  string[size] = '\0';
1672  indices = ALLOC(int,nvars);
1673  if (indices == NULL) {
1674  dd->errorCode = CUDD_MEMORY_OUT;
1675  FREE(weight);
1676  FREE(string);
1677  FREE(mask);
1678  return(NULL);
1679  }
1680  for (i = 0; i < nvars; i++) {
1681  indices[i] = vars[i]->index;
1682  }
1683 
1684  result = ddPickRepresentativeCube(dd,f,weight,string);
1685  if (result == 0) {
1686  FREE(weight);
1687  FREE(string);
1688  FREE(mask);
1689  FREE(indices);
1690  return(NULL);
1691  }
1692 
1693  cube = Cudd_ReadOne(dd);
1694  cuddRef(cube);
1695  zero = Cudd_Not(Cudd_ReadOne(dd));
1696  for (i = 0; i < nvars; i++) {
1697  if (string[indices[i]] == '0') {
1698  newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero);
1699  } else if (string[indices[i]] == '1') {
1700  newCube = Cudd_bddIte(dd,cube,vars[i],zero);
1701  } else
1702  continue;
1703  if (newCube == NULL) {
1704  FREE(weight);
1705  FREE(string);
1706  FREE(mask);
1707  FREE(indices);
1708  Cudd_RecursiveDeref(dd,cube);
1709  return(NULL);
1710  }
1711  cuddRef(newCube);
1712  Cudd_RecursiveDeref(dd,cube);
1713  cube = newCube;
1714  }
1715  Cudd_RecursiveDeref(dd,cube);
1716 
1717  for (i = 0; i < mvars; i++) {
1718  mask[maskVars[i]->index] = 1;
1719  }
1720  for (i = 0; i < nvars; i++) {
1721  if (mask[indices[i]]) {
1722  if (string[indices[i]] == '2') {
1723  if (weight[indices[i]] >= 0.0)
1724  string[indices[i]] = '1';
1725  else
1726  string[indices[i]] = '0';
1727  }
1728  } else {
1729  string[indices[i]] = '2';
1730  }
1731  }
1732 
1733  cube = Cudd_ReadOne(dd);
1734  cuddRef(cube);
1735  zero = Cudd_Not(Cudd_ReadOne(dd));
1736 
1737  /* Build result BDD. */
1738  for (i = 0; i < nvars; i++) {
1739  if (string[indices[i]] == '0') {
1740  newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero);
1741  } else if (string[indices[i]] == '1') {
1742  newCube = Cudd_bddIte(dd,cube,vars[i],zero);
1743  } else
1744  continue;
1745  if (newCube == NULL) {
1746  FREE(weight);
1747  FREE(string);
1748  FREE(mask);
1749  FREE(indices);
1750  Cudd_RecursiveDeref(dd,cube);
1751  return(NULL);
1752  }
1753  cuddRef(newCube);
1754  Cudd_RecursiveDeref(dd,cube);
1755  cube = newCube;
1756  }
1757 
1758  subset = Cudd_bddAnd(dd,f,cube);
1759  cuddRef(subset);
1760  Cudd_RecursiveDeref(dd,cube);
1761 
1762  /* Test. */
1763  if (Cudd_bddLeq(dd,subset,f)) {
1764  cuddDeref(subset);
1765  } else {
1766  Cudd_RecursiveDeref(dd,subset);
1767  subset = NULL;
1768  }
1769 
1770  FREE(weight);
1771  FREE(string);
1772  FREE(mask);
1773  FREE(indices);
1774  return(subset);
1775 
1776 } /* end of Cudd_SubsetWithMaskVars */
1777 
1778 
1805 DdGen *
1807  DdManager * dd,
1808  DdNode * f,
1809  int ** cube,
1810  CUDD_VALUE_TYPE * value)
1811 {
1812  DdGen *gen;
1813  DdNode *top, *treg, *next, *nreg, *prev, *preg;
1814  int i;
1815  int nvars;
1816 
1817  /* Sanity Check. */
1818  if (dd == NULL || f == NULL) return(NULL);
1819 
1820  /* Allocate generator an initialize it. */
1821  gen = ALLOC(DdGen,1);
1822  if (gen == NULL) {
1823  dd->errorCode = CUDD_MEMORY_OUT;
1824  return(NULL);
1825  }
1826 
1827  gen->manager = dd;
1828  gen->type = CUDD_GEN_CUBES;
1829  gen->status = CUDD_GEN_EMPTY;
1830  gen->gen.cubes.cube = NULL;
1831  gen->gen.cubes.value = DD_ZERO_VAL;
1832  gen->stack.sp = 0;
1833  gen->stack.stack = NULL;
1834  gen->node = NULL;
1835 
1836  nvars = dd->size;
1837  gen->gen.cubes.cube = ALLOC(int,nvars);
1838  if (gen->gen.cubes.cube == NULL) {
1839  dd->errorCode = CUDD_MEMORY_OUT;
1840  FREE(gen);
1841  return(NULL);
1842  }
1843  for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2;
1844 
1845  /* The maximum stack depth is one plus the number of variables.
1846  ** because a path may have nodes at all levels, including the
1847  ** constant level.
1848  */
1849  gen->stack.stack = ALLOC(DdNodePtr, nvars+1);
1850  if (gen->stack.stack == NULL) {
1851  dd->errorCode = CUDD_MEMORY_OUT;
1852  FREE(gen->gen.cubes.cube);
1853  FREE(gen);
1854  return(NULL);
1855  }
1856  for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL;
1857 
1858  /* Find the first cube of the onset. */
1859  gen->stack.stack[gen->stack.sp] = f; gen->stack.sp++;
1860 
1861  while (1) {
1862  top = gen->stack.stack[gen->stack.sp-1];
1863  treg = Cudd_Regular(top);
1864  if (!cuddIsConstant(treg)) {
1865  /* Take the else branch first. */
1866  gen->gen.cubes.cube[treg->index] = 0;
1867  next = cuddE(treg);
1868  if (top != treg) next = Cudd_Not(next);
1869  gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++;
1870  } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) {
1871  /* Backtrack */
1872  while (1) {
1873  if (gen->stack.sp == 1) {
1874  /* The current node has no predecessor. */
1875  gen->status = CUDD_GEN_EMPTY;
1876  gen->stack.sp--;
1877  goto done;
1878  }
1879  prev = gen->stack.stack[gen->stack.sp-2];
1880  preg = Cudd_Regular(prev);
1881  nreg = cuddT(preg);
1882  if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;}
1883  if (next != top) { /* follow the then branch next */
1884  gen->gen.cubes.cube[preg->index] = 1;
1885  gen->stack.stack[gen->stack.sp-1] = next;
1886  break;
1887  }
1888  /* Pop the stack and try again. */
1889  gen->gen.cubes.cube[preg->index] = 2;
1890  gen->stack.sp--;
1891  top = gen->stack.stack[gen->stack.sp-1];
1892  treg = Cudd_Regular(top);
1893  }
1894  } else {
1895  gen->status = CUDD_GEN_NONEMPTY;
1896  gen->gen.cubes.value = cuddV(top);
1897  goto done;
1898  }
1899  }
1900 
1901 done:
1902  *cube = gen->gen.cubes.cube;
1903  *value = gen->gen.cubes.value;
1904  return(gen);
1905 
1906 } /* end of Cudd_FirstCube */
1907 
1908 
1924 int
1926  DdGen * gen,
1927  int ** cube,
1928  CUDD_VALUE_TYPE * value)
1929 {
1930  DdNode *top, *treg, *next, *nreg, *prev, *preg;
1931  DdManager *dd = gen->manager;
1932 
1933  /* Backtrack from previously reached terminal node. */
1934  while (1) {
1935  if (gen->stack.sp == 1) {
1936  /* The current node has no predecessor. */
1937  gen->status = CUDD_GEN_EMPTY;
1938  gen->stack.sp--;
1939  goto done;
1940  }
1941  top = gen->stack.stack[gen->stack.sp-1];
1942  treg = Cudd_Regular(top);
1943  prev = gen->stack.stack[gen->stack.sp-2];
1944  preg = Cudd_Regular(prev);
1945  nreg = cuddT(preg);
1946  if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;}
1947  if (next != top) { /* follow the then branch next */
1948  gen->gen.cubes.cube[preg->index] = 1;
1949  gen->stack.stack[gen->stack.sp-1] = next;
1950  break;
1951  }
1952  /* Pop the stack and try again. */
1953  gen->gen.cubes.cube[preg->index] = 2;
1954  gen->stack.sp--;
1955  }
1956 
1957  while (1) {
1958  top = gen->stack.stack[gen->stack.sp-1];
1959  treg = Cudd_Regular(top);
1960  if (!cuddIsConstant(treg)) {
1961  /* Take the else branch first. */
1962  gen->gen.cubes.cube[treg->index] = 0;
1963  next = cuddE(treg);
1964  if (top != treg) next = Cudd_Not(next);
1965  gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++;
1966  } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) {
1967  /* Backtrack */
1968  while (1) {
1969  if (gen->stack.sp == 1) {
1970  /* The current node has no predecessor. */
1971  gen->status = CUDD_GEN_EMPTY;
1972  gen->stack.sp--;
1973  goto done;
1974  }
1975  prev = gen->stack.stack[gen->stack.sp-2];
1976  preg = Cudd_Regular(prev);
1977  nreg = cuddT(preg);
1978  if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;}
1979  if (next != top) { /* follow the then branch next */
1980  gen->gen.cubes.cube[preg->index] = 1;
1981  gen->stack.stack[gen->stack.sp-1] = next;
1982  break;
1983  }
1984  /* Pop the stack and try again. */
1985  gen->gen.cubes.cube[preg->index] = 2;
1986  gen->stack.sp--;
1987  top = gen->stack.stack[gen->stack.sp-1];
1988  treg = Cudd_Regular(top);
1989  }
1990  } else {
1991  gen->status = CUDD_GEN_NONEMPTY;
1992  gen->gen.cubes.value = cuddV(top);
1993  goto done;
1994  }
1995  }
1996 
1997 done:
1998  if (gen->status == CUDD_GEN_EMPTY) return(0);
1999  *cube = gen->gen.cubes.cube;
2000  *value = gen->gen.cubes.value;
2001  return(1);
2002 
2003 } /* end of Cudd_NextCube */
2004 
2005 
2035 DdGen *
2037  DdManager *dd,
2038  DdNode *l,
2039  DdNode *u,
2040  int **cube)
2041 {
2042  DdGen *gen;
2043  DdNode *implicant, *prime, *tmp;
2044  int length, result;
2045 
2046  /* Sanity Check. */
2047  if (dd == NULL || l == NULL || u == NULL) return(NULL);
2048 
2049  /* Allocate generator an initialize it. */
2050  gen = ALLOC(DdGen,1);
2051  if (gen == NULL) {
2052  dd->errorCode = CUDD_MEMORY_OUT;
2053  return(NULL);
2054  }
2055 
2056  gen->manager = dd;
2057  gen->type = CUDD_GEN_PRIMES;
2058  gen->status = CUDD_GEN_EMPTY;
2059  gen->gen.primes.cube = NULL;
2060  gen->gen.primes.ub = u;
2061  gen->stack.sp = 0;
2062  gen->stack.stack = NULL;
2063  gen->node = l;
2064  cuddRef(l);
2065 
2066  gen->gen.primes.cube = ALLOC(int,dd->size);
2067  if (gen->gen.primes.cube == NULL) {
2068  dd->errorCode = CUDD_MEMORY_OUT;
2069  FREE(gen);
2070  return(NULL);
2071  }
2072 
2073  if (gen->node == Cudd_ReadLogicZero(dd)) {
2074  gen->status = CUDD_GEN_EMPTY;
2075  } else {
2076  implicant = Cudd_LargestCube(dd,gen->node,&length);
2077  if (implicant == NULL) {
2078  Cudd_RecursiveDeref(dd,gen->node);
2079  FREE(gen->gen.primes.cube);
2080  FREE(gen);
2081  return(NULL);
2082  }
2083  cuddRef(implicant);
2084  prime = Cudd_bddMakePrime(dd,implicant,gen->gen.primes.ub);
2085  if (prime == NULL) {
2086  Cudd_RecursiveDeref(dd,gen->node);
2087  Cudd_RecursiveDeref(dd,implicant);
2088  FREE(gen->gen.primes.cube);
2089  FREE(gen);
2090  return(NULL);
2091  }
2092  cuddRef(prime);
2093  Cudd_RecursiveDeref(dd,implicant);
2094  tmp = Cudd_bddAnd(dd,gen->node,Cudd_Not(prime));
2095  if (tmp == NULL) {
2096  Cudd_RecursiveDeref(dd,gen->node);
2097  Cudd_RecursiveDeref(dd,prime);
2098  FREE(gen->gen.primes.cube);
2099  FREE(gen);
2100  return(NULL);
2101  }
2102  cuddRef(tmp);
2103  Cudd_RecursiveDeref(dd,gen->node);
2104  gen->node = tmp;
2105  result = Cudd_BddToCubeArray(dd,prime,gen->gen.primes.cube);
2106  if (result == 0) {
2107  Cudd_RecursiveDeref(dd,gen->node);
2108  Cudd_RecursiveDeref(dd,prime);
2109  FREE(gen->gen.primes.cube);
2110  FREE(gen);
2111  return(NULL);
2112  }
2113  Cudd_RecursiveDeref(dd,prime);
2114  gen->status = CUDD_GEN_NONEMPTY;
2115  }
2116  *cube = gen->gen.primes.cube;
2117  return(gen);
2118 
2119 } /* end of Cudd_FirstPrime */
2120 
2121 
2137 int
2139  DdGen *gen,
2140  int **cube)
2141 {
2142  DdNode *implicant, *prime, *tmp;
2143  DdManager *dd = gen->manager;
2144  int length, result;
2145 
2146  if (gen->node == Cudd_ReadLogicZero(dd)) {
2147  gen->status = CUDD_GEN_EMPTY;
2148  } else {
2149  implicant = Cudd_LargestCube(dd,gen->node,&length);
2150  if (implicant == NULL) {
2151  gen->status = CUDD_GEN_EMPTY;
2152  return(0);
2153  }
2154  cuddRef(implicant);
2155  prime = Cudd_bddMakePrime(dd,implicant,gen->gen.primes.ub);
2156  if (prime == NULL) {
2157  Cudd_RecursiveDeref(dd,implicant);
2158  gen->status = CUDD_GEN_EMPTY;
2159  return(0);
2160  }
2161  cuddRef(prime);
2162  Cudd_RecursiveDeref(dd,implicant);
2163  tmp = Cudd_bddAnd(dd,gen->node,Cudd_Not(prime));
2164  if (tmp == NULL) {
2165  Cudd_RecursiveDeref(dd,prime);
2166  gen->status = CUDD_GEN_EMPTY;
2167  return(0);
2168  }
2169  cuddRef(tmp);
2170  Cudd_RecursiveDeref(dd,gen->node);
2171  gen->node = tmp;
2172  result = Cudd_BddToCubeArray(dd,prime,gen->gen.primes.cube);
2173  if (result == 0) {
2174  Cudd_RecursiveDeref(dd,prime);
2175  gen->status = CUDD_GEN_EMPTY;
2176  return(0);
2177  }
2178  Cudd_RecursiveDeref(dd,prime);
2179  gen->status = CUDD_GEN_NONEMPTY;
2180  }
2181  if (gen->status == CUDD_GEN_EMPTY) return(0);
2182  *cube = gen->gen.primes.cube;
2183  return(1);
2184 
2185 } /* end of Cudd_NextPrime */
2186 
2187 
2203 DdNode *
2205  DdManager * dd,
2206  DdNode ** vars,
2207  int * phase,
2208  int n)
2209 {
2210  DdNode *cube;
2211  DdNode *fn;
2212  int i;
2213 
2214  cube = DD_ONE(dd);
2215  cuddRef(cube);
2216 
2217  for (i = n - 1; i >= 0; i--) {
2218  if (phase == NULL || phase[i] != 0) {
2219  fn = Cudd_bddAnd(dd,vars[i],cube);
2220  } else {
2221  fn = Cudd_bddAnd(dd,Cudd_Not(vars[i]),cube);
2222  }
2223  if (fn == NULL) {
2224  Cudd_RecursiveDeref(dd,cube);
2225  return(NULL);
2226  }
2227  cuddRef(fn);
2228  Cudd_RecursiveDeref(dd,cube);
2229  cube = fn;
2230  }
2231  cuddDeref(cube);
2232 
2233  return(cube);
2234 
2235 } /* end of Cudd_bddComputeCube */
2236 
2237 
2253 DdNode *
2255  DdManager * dd,
2256  DdNode ** vars,
2257  int * phase,
2258  int n)
2259 {
2260  DdNode *cube, *zero;
2261  DdNode *fn;
2262  int i;
2263 
2264  cube = DD_ONE(dd);
2265  cuddRef(cube);
2266  zero = DD_ZERO(dd);
2267 
2268  for (i = n - 1; i >= 0; i--) {
2269  if (phase == NULL || phase[i] != 0) {
2270  fn = Cudd_addIte(dd,vars[i],cube,zero);
2271  } else {
2272  fn = Cudd_addIte(dd,vars[i],zero,cube);
2273  }
2274  if (fn == NULL) {
2275  Cudd_RecursiveDeref(dd,cube);
2276  return(NULL);
2277  }
2278  cuddRef(fn);
2279  Cudd_RecursiveDeref(dd,cube);
2280  cube = fn;
2281  }
2282  cuddDeref(cube);
2283 
2284  return(cube);
2285 
2286 } /* end of Cudd_addComputeCube */
2287 
2288 
2305 DdNode *
2307  DdManager *dd,
2308  int *array)
2309 {
2310  DdNode *cube, *var, *tmp;
2311  int i;
2312  int size = Cudd_ReadSize(dd);
2313 
2314  cube = DD_ONE(dd);
2315  cuddRef(cube);
2316  for (i = size - 1; i >= 0; i--) {
2317  if ((array[i] & ~1) == 0) {
2318  var = Cudd_bddIthVar(dd,i);
2319  tmp = Cudd_bddAnd(dd,cube,Cudd_NotCond(var,array[i]==0));
2320  if (tmp == NULL) {
2321  Cudd_RecursiveDeref(dd,cube);
2322  return(NULL);
2323  }
2324  cuddRef(tmp);
2325  Cudd_RecursiveDeref(dd,cube);
2326  cube = tmp;
2327  }
2328  }
2329  cuddDeref(cube);
2330  return(cube);
2331 
2332 } /* end of Cudd_CubeArrayToBdd */
2333 
2334 
2353 int
2355  DdManager *dd,
2356  DdNode *cube,
2357  int *array)
2358 {
2359  DdNode *scan, *t, *e;
2360  int i;
2361  int size = Cudd_ReadSize(dd);
2362  DdNode *zero = Cudd_Not(DD_ONE(dd));
2363 
2364  for (i = size-1; i >= 0; i--) {
2365  array[i] = 2;
2366  }
2367  scan = cube;
2368  while (!Cudd_IsConstant(scan)) {
2369  int index = Cudd_Regular(scan)->index;
2370  cuddGetBranches(scan,&t,&e);
2371  if (t == zero) {
2372  array[index] = 0;
2373  scan = e;
2374  } else if (e == zero) {
2375  array[index] = 1;
2376  scan = t;
2377  } else {
2378  return(0); /* cube is not a cube */
2379  }
2380  }
2381  if (scan == zero) {
2382  return(0);
2383  } else {
2384  return(1);
2385  }
2386 
2387 } /* end of Cudd_BddToCubeArray */
2388 
2389 
2407 DdGen *
2409  DdManager * dd,
2410  DdNode * f,
2411  DdNode ** node)
2412 {
2413  DdGen *gen;
2414  int size;
2415 
2416  /* Sanity Check. */
2417  if (dd == NULL || f == NULL) return(NULL);
2418 
2419  /* Allocate generator an initialize it. */
2420  gen = ALLOC(DdGen,1);
2421  if (gen == NULL) {
2422  dd->errorCode = CUDD_MEMORY_OUT;
2423  return(NULL);
2424  }
2425 
2426  gen->manager = dd;
2427  gen->type = CUDD_GEN_NODES;
2428  gen->status = CUDD_GEN_EMPTY;
2429  gen->stack.sp = 0;
2430  gen->node = NULL;
2431 
2432  /* Collect all the nodes on the generator stack for later perusal. */
2433  gen->stack.stack = cuddNodeArray(Cudd_Regular(f), &size);
2434  if (gen->stack.stack == NULL) {
2435  FREE(gen);
2436  dd->errorCode = CUDD_MEMORY_OUT;
2437  return(NULL);
2438  }
2439  gen->gen.nodes.size = size;
2440 
2441  /* Find the first node. */
2442  if (gen->stack.sp < gen->gen.nodes.size) {
2443  gen->status = CUDD_GEN_NONEMPTY;
2444  gen->node = gen->stack.stack[gen->stack.sp];
2445  *node = gen->node;
2446  }
2447 
2448  return(gen);
2449 
2450 } /* end of Cudd_FirstNode */
2451 
2452 
2466 int
2468  DdGen * gen,
2469  DdNode ** node)
2470 {
2471  /* Find the next node. */
2472  gen->stack.sp++;
2473  if (gen->stack.sp < gen->gen.nodes.size) {
2474  gen->node = gen->stack.stack[gen->stack.sp];
2475  *node = gen->node;
2476  return(1);
2477  } else {
2478  gen->status = CUDD_GEN_EMPTY;
2479  return(0);
2480  }
2481 
2482 } /* end of Cudd_NextNode */
2483 
2484 
2498 int
2500  DdGen * gen)
2501 {
2502  if (gen == NULL) return(0);
2503  switch (gen->type) {
2504  case CUDD_GEN_CUBES:
2505  case CUDD_GEN_ZDD_PATHS:
2506  FREE(gen->gen.cubes.cube);
2507  FREE(gen->stack.stack);
2508  break;
2509  case CUDD_GEN_PRIMES:
2510  FREE(gen->gen.primes.cube);
2511  Cudd_RecursiveDeref(gen->manager,gen->node);
2512  break;
2513  case CUDD_GEN_NODES:
2514  FREE(gen->stack.stack);
2515  break;
2516  default:
2517  return(0);
2518  }
2519  FREE(gen);
2520  return(0);
2521 
2522 } /* end of Cudd_GenFree */
2523 
2524 
2538 int
2540  DdGen * gen)
2541 {
2542  if (gen == NULL) return(1);
2543  return(gen->status == CUDD_GEN_EMPTY);
2544 
2545 } /* end of Cudd_IsGenEmpty */
2546 
2547 
2560 DdNode *
2562  DdManager * dd,
2563  int * array,
2564  int n)
2565 {
2566  DdNode *cube, *tmp;
2567  int i;
2568 
2569  cube = DD_ONE(dd);
2570  cuddRef(cube);
2571  for (i = n - 1; i >= 0; i--) {
2572  tmp = Cudd_bddAnd(dd,Cudd_bddIthVar(dd,array[i]),cube);
2573  if (tmp == NULL) {
2574  Cudd_RecursiveDeref(dd,cube);
2575  return(NULL);
2576  }
2577  cuddRef(tmp);
2578  Cudd_RecursiveDeref(dd,cube);
2579  cube = tmp;
2580  }
2581 
2582  cuddDeref(cube);
2583  return(cube);
2584 
2585 } /* end of Cudd_IndicesToCube */
2586 
2587 
2599 void
2601  FILE * fp)
2602 {
2603  (void) fprintf(fp, "%s\n", CUDD_VERSION);
2604 
2605 } /* end of Cudd_PrintVersion */
2606 
2607 
2621 double
2623  DdManager * dd)
2624 {
2625  double tetotal, nexttotal;
2626  double tesubtotal, nextsubtotal;
2627  double temeasured, nextmeasured;
2628  int i, j;
2629  int slots, nvars;
2630  long diff;
2631  DdNode *scan;
2632  DdNodePtr *nodelist;
2633  DdNode *sentinel = &(dd->sentinel);
2634 
2635  nvars = dd->size;
2636  if (nvars == 0) return(0.0);
2637 
2638  /* Initialize totals. */
2639  tetotal = 0.0;
2640  nexttotal = 0.0;
2641  temeasured = 0.0;
2642  nextmeasured = 0.0;
2643 
2644  /* Scan the variable subtables. */
2645  for (i = 0; i < nvars; i++) {
2646  nodelist = dd->subtables[i].nodelist;
2647  tesubtotal = 0.0;
2648  nextsubtotal = 0.0;
2649  slots = dd->subtables[i].slots;
2650  for (j = 0; j < slots; j++) {
2651  scan = nodelist[j];
2652  while (scan != sentinel) {
2653  diff = (long) scan - (long) cuddT(scan);
2654  tesubtotal += (double) ddAbs(diff);
2655  diff = (long) scan - (long) Cudd_Regular(cuddE(scan));
2656  tesubtotal += (double) ddAbs(diff);
2657  temeasured += 2.0;
2658  if (scan->next != sentinel) {
2659  diff = (long) scan - (long) scan->next;
2660  nextsubtotal += (double) ddAbs(diff);
2661  nextmeasured += 1.0;
2662  }
2663  scan = scan->next;
2664  }
2665  }
2666  tetotal += tesubtotal;
2667  nexttotal += nextsubtotal;
2668  }
2669 
2670  /* Scan the constant table. */
2671  nodelist = dd->constants.nodelist;
2672  nextsubtotal = 0.0;
2673  slots = dd->constants.slots;
2674  for (j = 0; j < slots; j++) {
2675  scan = nodelist[j];
2676  while (scan != NULL) {
2677  if (scan->next != NULL) {
2678  diff = (long) scan - (long) scan->next;
2679  nextsubtotal += (double) ddAbs(diff);
2680  nextmeasured += 1.0;
2681  }
2682  scan = scan->next;
2683  }
2684  }
2685  nexttotal += nextsubtotal;
2686 
2687  return((tetotal + nexttotal) / (temeasured + nextmeasured));
2688 
2689 } /* end of Cudd_AverageDistance */
2690 
2691 
2709 long
2711 {
2712  int i; /* index in the shuffle table */
2713  long int w; /* work variable */
2714 
2715  /* cuddRand == 0 if the geneartor has not been initialized yet. */
2716  if (cuddRand == 0) Cudd_Srandom(1);
2717 
2718  /* Compute cuddRand = (cuddRand * LEQA1) % MODULUS1 avoiding
2719  ** overflows by Schrage's method.
2720  */
2721  w = cuddRand / LEQQ1;
2722  cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1;
2723  cuddRand += (cuddRand < 0) * MODULUS1;
2724 
2725  /* Compute cuddRand2 = (cuddRand2 * LEQA2) % MODULUS2 avoiding
2726  ** overflows by Schrage's method.
2727  */
2728  w = cuddRand2 / LEQQ2;
2729  cuddRand2 = LEQA2 * (cuddRand2 - w * LEQQ2) - w * LEQR2;
2730  cuddRand2 += (cuddRand2 < 0) * MODULUS2;
2731 
2732  /* cuddRand is shuffled with the Bays-Durham algorithm.
2733  ** shuffleSelect and cuddRand2 are combined to generate the output.
2734  */
2735 
2736  /* Pick one element from the shuffle table; "i" will be in the range
2737  ** from 0 to STAB_SIZE-1.
2738  */
2739  i = (int) (shuffleSelect / STAB_DIV);
2740  /* Mix the element of the shuffle table with the current iterate of
2741  ** the second sub-generator, and replace the chosen element of the
2742  ** shuffle table with the current iterate of the first sub-generator.
2743  */
2745  shuffleTable[i] = cuddRand;
2746  shuffleSelect += (shuffleSelect < 1) * (MODULUS1 - 1);
2747  /* Since shuffleSelect != 0, and we want to be able to return 0,
2748  ** here we subtract 1 before returning.
2749  */
2750  return(shuffleSelect - 1);
2751 
2752 } /* end of Cudd_Random */
2753 
2754 
2771 void
2773  long seed)
2774 {
2775  int i;
2776 
2777  if (seed < 0) cuddRand = -seed;
2778  else if (seed == 0) cuddRand = 1;
2779  else cuddRand = seed;
2780  cuddRand2 = cuddRand;
2781  /* Load the shuffle table (after 11 warm-ups). */
2782  for (i = 0; i < STAB_SIZE + 11; i++) {
2783  long int w;
2784  w = cuddRand / LEQQ1;
2785  cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1;
2786  cuddRand += (cuddRand < 0) * MODULUS1;
2788  }
2790 
2791 } /* end of Cudd_Srandom */
2792 
2793 
2809 double
2811  DdManager * dd /* manager */,
2812  DdNode * f /* function whose density is sought */,
2813  int nvars /* size of the support of f */)
2814 {
2815  double minterms;
2816  int nodes;
2817  double density;
2818 
2819  if (nvars == 0) nvars = dd->size;
2820  minterms = Cudd_CountMinterm(dd,f,nvars);
2821  if (minterms == (double) CUDD_OUT_OF_MEM) return(minterms);
2822  nodes = Cudd_DagSize(f);
2823  density = minterms / (double) nodes;
2824  return(density);
2825 
2826 } /* end of Cudd_Density */
2827 
2828 
2844 void
2846  long size /* size of the allocation that failed */)
2847 {
2848  (void) fflush(stdout);
2849  (void) fprintf(stderr, "\nunable to allocate %ld bytes\n", size);
2850  return;
2851 
2852 } /* end of Cudd_OutOfMem */
2853 
2854 
2855 /*---------------------------------------------------------------------------*/
2856 /* Definition of internal functions */
2857 /*---------------------------------------------------------------------------*/
2858 
2859 
2873 int
2875  DdManager * dd,
2876  DdNode * f)
2877 {
2878  int retval;
2880 
2881  if (table == NULL) return(0);
2882 
2883  retval = dp2(dd,f,table);
2884  st_free_table(table);
2885  (void) fputc('\n',dd->out);
2886  return(retval);
2887 
2888 } /* end of cuddP */
2889 
2890 
2902 enum st_retval
2904  char * key,
2905  char * value,
2906  char * arg)
2907 {
2908  double *d;
2909 
2910  d = (double *)value;
2911  FREE(d);
2912  return(ST_CONTINUE);
2913 
2914 } /* end of cuddStCountfree */
2915 
2916 
2932 int
2934  DdNode * f,
2935  st_table * visited)
2936 {
2937  DdNode *T, *E;
2938  int retval;
2939 
2940 #ifdef DD_DEBUG
2942 #endif
2943 
2944  /* If already visited, nothing to do. */
2945  if (st_is_member(visited, (char *) f) == 1)
2946  return(1);
2947 
2948  /* Check for abnormal condition that should never happen. */
2949  if (f == NULL)
2950  return(0);
2951 
2952  /* Mark node as visited. */
2953  if (st_add_direct(visited, (char *) f, NULL) == ST_OUT_OF_MEM)
2954  return(0);
2955 
2956  /* Check terminal case. */
2957  if (cuddIsConstant(f))
2958  return(1);
2959 
2960  /* Recursive calls. */
2961  T = cuddT(f);
2962  retval = cuddCollectNodes(T,visited);
2963  if (retval != 1) return(retval);
2964  E = Cudd_Regular(cuddE(f));
2965  retval = cuddCollectNodes(E,visited);
2966  return(retval);
2967 
2968 } /* end of cuddCollectNodes */
2969 
2970 
2986 DdNodePtr *
2988  DdNode *f,
2989  int *n)
2990 {
2991  DdNodePtr *table;
2992  int size, retval;
2993 
2994  size = ddDagInt(Cudd_Regular(f));
2995  table = ALLOC(DdNodePtr, size);
2996  if (table == NULL) {
2998  return(NULL);
2999  }
3000 
3001  retval = cuddNodeArrayRecur(f, table, 0);
3002  assert(retval == size);
3003 
3004  *n = size;
3005  return(table);
3006 
3007 } /* cuddNodeArray */
3008 
3009 
3010 /*---------------------------------------------------------------------------*/
3011 /* Definition of static functions */
3012 /*---------------------------------------------------------------------------*/
3013 
3014 
3025 static int
3027  DdManager *dd,
3028  DdNode * f,
3029  st_table * t)
3030 {
3031  DdNode *g, *n, *N;
3032  int T,E;
3033 
3034  if (f == NULL) {
3035  return(0);
3036  }
3037  g = Cudd_Regular(f);
3038  if (cuddIsConstant(g)) {
3039 #if SIZEOF_VOID_P == 8
3040  (void) fprintf(dd->out,"ID = %c0x%lx\tvalue = %-9g\n", bang(f),
3041  (ptruint) g / (ptruint) sizeof(DdNode),cuddV(g));
3042 #else
3043  (void) fprintf(dd->out,"ID = %c0x%x\tvalue = %-9g\n", bang(f),
3044  (ptruint) g / (ptruint) sizeof(DdNode),cuddV(g));
3045 #endif
3046  return(1);
3047  }
3048  if (st_is_member(t,(char *) g) == 1) {
3049  return(1);
3050  }
3051  if (st_add_direct(t,(char *) g,NULL) == ST_OUT_OF_MEM)
3052  return(0);
3053 #ifdef DD_STATS
3054 #if SIZEOF_VOID_P == 8
3055  (void) fprintf(dd->out,"ID = %c0x%lx\tindex = %d\tr = %d\t", bang(f),
3056  (ptruint) g / (ptruint) sizeof(DdNode), g->index, g->ref);
3057 #else
3058  (void) fprintf(dd->out,"ID = %c0x%x\tindex = %d\tr = %d\t", bang(f),
3059  (ptruint) g / (ptruint) sizeof(DdNode),g->index,g->ref);
3060 #endif
3061 #else
3062 #if SIZEOF_VOID_P == 8
3063  (void) fprintf(dd->out,"ID = %c0x%lx\tindex = %u\t", bang(f),
3064  (ptruint) g / (ptruint) sizeof(DdNode),g->index);
3065 #else
3066  (void) fprintf(dd->out,"ID = %c0x%x\tindex = %hu\t", bang(f),
3067  (ptruint) g / (ptruint) sizeof(DdNode),g->index);
3068 #endif
3069 #endif
3070  n = cuddT(g);
3071  if (cuddIsConstant(n)) {
3072  (void) fprintf(dd->out,"T = %-9g\t",cuddV(n));
3073  T = 1;
3074  } else {
3075 #if SIZEOF_VOID_P == 8
3076  (void) fprintf(dd->out,"T = 0x%lx\t",(ptruint) n / (ptruint) sizeof(DdNode));
3077 #else
3078  (void) fprintf(dd->out,"T = 0x%x\t",(ptruint) n / (ptruint) sizeof(DdNode));
3079 #endif
3080  T = 0;
3081  }
3082 
3083  n = cuddE(g);
3084  N = Cudd_Regular(n);
3085  if (cuddIsConstant(N)) {
3086  (void) fprintf(dd->out,"E = %c%-9g\n",bang(n),cuddV(N));
3087  E = 1;
3088  } else {
3089 #if SIZEOF_VOID_P == 8
3090  (void) fprintf(dd->out,"E = %c0x%lx\n", bang(n), (ptruint) N/(ptruint) sizeof(DdNode));
3091 #else
3092  (void) fprintf(dd->out,"E = %c0x%x\n", bang(n), (ptruint) N/(ptruint) sizeof(DdNode));
3093 #endif
3094  E = 0;
3095  }
3096  if (E == 0) {
3097  if (dp2(dd,N,t) == 0)
3098  return(0);
3099  }
3100  if (T == 0) {
3101  if (dp2(dd,cuddT(g),t) == 0)
3102  return(0);
3103  }
3104  return(1);
3105 
3106 } /* end of dp2 */
3107 
3108 
3118 static void
3120  DdManager * dd /* manager */,
3121  DdNode * node /* current node */,
3122  int * list /* current recursion path */)
3123 {
3124  DdNode *N,*Nv,*Nnv;
3125  int i,v,index;
3126 
3127  N = Cudd_Regular(node);
3128 
3129  if (cuddIsConstant(N)) {
3130  /* Terminal case: Print one cube based on the current recursion
3131  ** path, unless we have reached the background value (ADDs) or
3132  ** the logical zero (BDDs).
3133  */
3134  if (node != background && node != zero) {
3135  for (i = 0; i < dd->size; i++) {
3136  v = list[i];
3137  if (v == 0) (void) fprintf(dd->out,"0");
3138  else if (v == 1) (void) fprintf(dd->out,"1");
3139  else (void) fprintf(dd->out,"-");
3140  }
3141  (void) fprintf(dd->out," % g\n", cuddV(node));
3142  }
3143  } else {
3144  Nv = cuddT(N);
3145  Nnv = cuddE(N);
3146  if (Cudd_IsComplement(node)) {
3147  Nv = Cudd_Not(Nv);
3148  Nnv = Cudd_Not(Nnv);
3149  }
3150  index = N->index;
3151  list[index] = 0;
3152  ddPrintMintermAux(dd,Nnv,list);
3153  list[index] = 1;
3154  ddPrintMintermAux(dd,Nv,list);
3155  list[index] = 2;
3156  }
3157  return;
3158 
3159 } /* end of ddPrintMintermAux */
3160 
3161 
3172 static int
3174  DdNode * n)
3175 {
3176  int tval, eval;
3177 
3178  if (Cudd_IsComplement(n->next)) {
3179  return(0);
3180  }
3181  n->next = Cudd_Not(n->next);
3182  if (cuddIsConstant(n)) {
3183  return(1);
3184  }
3185  tval = ddDagInt(cuddT(n));
3186  eval = ddDagInt(Cudd_Regular(cuddE(n)));
3187  return(1 + tval + eval);
3188 
3189 } /* end of ddDagInt */
3190 
3191 
3207 static int
3209  DdNode *f,
3210  DdNodePtr *table,
3211  int index)
3212 {
3213  int tindex, eindex;
3214 
3215  if (!Cudd_IsComplement(f->next)) {
3216  return(index);
3217  }
3218  /* Clear visited flag. */
3219  f->next = Cudd_Regular(f->next);
3220  if (cuddIsConstant(f)) {
3221  table[index] = f;
3222  return(index + 1);
3223  }
3224  tindex = cuddNodeArrayRecur(cuddT(f), table, index);
3225  eindex = cuddNodeArrayRecur(Cudd_Regular(cuddE(f)), table, tindex);
3226  table[eindex] = f;
3227  return(eindex + 1);
3228 
3229 } /* end of cuddNodeArrayRecur */
3230 
3231 
3247 static int
3249  DdManager *dd,
3250  st_table *table,
3251  DdNode * node,
3252  int i,
3253  int phase,
3254  DdNode ** ptr)
3255 {
3256  int tval, eval, val;
3257  DdNode *ptrT, *ptrE;
3258 
3259  if (Cudd_IsComplement(node->next)) {
3260  if (!st_lookup(table,(char *)node,(char **)ptr)) {
3261  if (st_add_direct(table,(char *)node,(char *)node) ==
3262  ST_OUT_OF_MEM)
3263  return(CUDD_OUT_OF_MEM);
3264  *ptr = node;
3265  }
3266  return(0);
3267  }
3268  node->next = Cudd_Not(node->next);
3269  if (cuddIsConstant(node)) {
3270  *ptr = node;
3271  if (st_add_direct(table,(char *)node,(char *)node) == ST_OUT_OF_MEM)
3272  return(CUDD_OUT_OF_MEM);
3273  return(1);
3274  }
3275  if ((int) node->index == i) {
3276  if (phase == 1) {
3277  *ptr = cuddT(node);
3278  val = ddDagInt(cuddT(node));
3279  } else {
3280  *ptr = cuddE(node);
3281  val = ddDagInt(Cudd_Regular(cuddE(node)));
3282  }
3283  if (node->ref > 1) {
3284  if (st_add_direct(table,(char *)node,(char *)*ptr) ==
3285  ST_OUT_OF_MEM)
3286  return(CUDD_OUT_OF_MEM);
3287  }
3288  return(val);
3289  }
3290  if (dd->perm[node->index] > dd->perm[i]) {
3291  *ptr = node;
3292  tval = ddDagInt(cuddT(node));
3293  eval = ddDagInt(Cudd_Regular(cuddE(node)));
3294  if (node->ref > 1) {
3295  if (st_add_direct(table,(char *)node,(char *)node) ==
3296  ST_OUT_OF_MEM)
3297  return(CUDD_OUT_OF_MEM);
3298  }
3299  val = 1 + tval + eval;
3300  return(val);
3301  }
3302  tval = cuddEstimateCofactor(dd,table,cuddT(node),i,phase,&ptrT);
3303  eval = cuddEstimateCofactor(dd,table,Cudd_Regular(cuddE(node)),i,
3304  phase,&ptrE);
3305  ptrE = Cudd_NotCond(ptrE,Cudd_IsComplement(cuddE(node)));
3306  if (ptrT == ptrE) { /* recombination */
3307  *ptr = ptrT;
3308  val = tval;
3309  if (node->ref > 1) {
3310  if (st_add_direct(table,(char *)node,(char *)*ptr) ==
3311  ST_OUT_OF_MEM)
3312  return(CUDD_OUT_OF_MEM);
3313  }
3314  } else if ((ptrT != cuddT(node) || ptrE != cuddE(node)) &&
3315  (*ptr = cuddUniqueLookup(dd,node->index,ptrT,ptrE)) != NULL) {
3316  if (Cudd_IsComplement((*ptr)->next)) {
3317  val = 0;
3318  } else {
3319  val = 1 + tval + eval;
3320  }
3321  if (node->ref > 1) {
3322  if (st_add_direct(table,(char *)node,(char *)*ptr) ==
3323  ST_OUT_OF_MEM)
3324  return(CUDD_OUT_OF_MEM);
3325  }
3326  } else {
3327  *ptr = node;
3328  val = 1 + tval + eval;
3329  }
3330  return(val);
3331 
3332 } /* end of cuddEstimateCofactor */
3333 
3334 
3347 static DdNode *
3349  DdManager * unique,
3350  int index,
3351  DdNode * T,
3352  DdNode * E)
3353 {
3354  int posn;
3355  unsigned int level;
3356  DdNodePtr *nodelist;
3357  DdNode *looking;
3358  DdSubtable *subtable;
3359 
3360  if (index >= unique->size) {
3361  return(NULL);
3362  }
3363 
3364  level = unique->perm[index];
3365  subtable = &(unique->subtables[level]);
3366 
3367 #ifdef DD_DEBUG
3368  assert(level < (unsigned) cuddI(unique,T->index));
3369  assert(level < (unsigned) cuddI(unique,Cudd_Regular(E)->index));
3370 #endif
3371 
3372  posn = ddHash(T, E, subtable->shift);
3373  nodelist = subtable->nodelist;
3374  looking = nodelist[posn];
3375 
3376  while (T < cuddT(looking)) {
3377  looking = Cudd_Regular(looking->next);
3378  }
3379  while (T == cuddT(looking) && E < cuddE(looking)) {
3380  looking = Cudd_Regular(looking->next);
3381  }
3382  if (cuddT(looking) == T && cuddE(looking) == E) {
3383  return(looking);
3384  }
3385 
3386  return(NULL);
3387 
3388 } /* end of cuddUniqueLookup */
3389 
3390 
3406 static int
3408  DdNode * node,
3409  int i)
3410 {
3411  int tval, eval;
3412 
3413  if (Cudd_IsComplement(node->next)) {
3414  return(0);
3415  }
3416  node->next = Cudd_Not(node->next);
3417  if (cuddIsConstant(node)) {
3418  return(1);
3419  }
3420  tval = cuddEstimateCofactorSimple(cuddT(node),i);
3421  if ((int) node->index == i) return(tval);
3423  return(1 + tval + eval);
3424 
3425 } /* end of cuddEstimateCofactorSimple */
3426 
3427 
3446 static double
3448  DdNode * node,
3449  double max,
3450  DdHashTable * table)
3451 {
3452  DdNode *N, *Nt, *Ne;
3453  double min, minT, minE;
3454  DdNode *res;
3455 
3456  N = Cudd_Regular(node);
3457 
3458  if (cuddIsConstant(N)) {
3459  if (node == background || node == zero) {
3460  return(0.0);
3461  } else {
3462  return(max);
3463  }
3464  }
3465  if (N->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) {
3466  min = cuddV(res);
3467  if (res->ref == 0) {
3468  table->manager->dead++;
3469  table->manager->constants.dead++;
3470  }
3471  return(min);
3472  }
3473 
3474  Nt = cuddT(N); Ne = cuddE(N);
3475  if (Cudd_IsComplement(node)) {
3476  Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne);
3477  }
3478 
3479  minT = ddCountMintermAux(Nt,max,table);
3480  if (minT == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
3481  minT *= 0.5;
3482  minE = ddCountMintermAux(Ne,max,table);
3483  if (minE == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
3484  minE *= 0.5;
3485  min = minT + minE;
3486 
3487  if (N->ref != 1) {
3488  ptrint fanout = (ptrint) N->ref;
3489  cuddSatDec(fanout);
3490  res = cuddUniqueConst(table->manager,min);
3491  if (!cuddHashTableInsert1(table,node,res,fanout)) {
3492  cuddRef(res); Cudd_RecursiveDeref(table->manager, res);
3493  return((double)CUDD_OUT_OF_MEM);
3494  }
3495  }
3496 
3497  return(min);
3498 
3499 } /* end of ddCountMintermAux */
3500 
3501 
3519 static double
3521  DdNode * node,
3522  st_table * table)
3523 {
3524 
3525  DdNode *Nv, *Nnv;
3526  double paths, *ppaths, paths1, paths2;
3527  double *dummy;
3528 
3529 
3530  if (cuddIsConstant(node)) {
3531  return(1.0);
3532  }
3533  if (st_lookup(table, node, &dummy)) {
3534  paths = *dummy;
3535  return(paths);
3536  }
3537 
3538  Nv = cuddT(node); Nnv = cuddE(node);
3539 
3540  paths1 = ddCountPathAux(Nv,table);
3541  if (paths1 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
3542  paths2 = ddCountPathAux(Cudd_Regular(Nnv),table);
3543  if (paths2 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
3544  paths = paths1 + paths2;
3545 
3546  ppaths = ALLOC(double,1);
3547  if (ppaths == NULL) {
3548  return((double)CUDD_OUT_OF_MEM);
3549  }
3550 
3551  *ppaths = paths;
3552 
3553  if (st_add_direct(table,(char *)node, (char *)ppaths) == ST_OUT_OF_MEM) {
3554  FREE(ppaths);
3555  return((double)CUDD_OUT_OF_MEM);
3556  }
3557  return(paths);
3558 
3559 } /* end of ddCountPathAux */
3560 
3561 
3580 static int
3582  DdNode * node,
3583  EpDouble * max,
3584  EpDouble * epd,
3585  st_table * table)
3586 {
3587  DdNode *Nt, *Ne;
3588  EpDouble *min, minT, minE;
3589  EpDouble *res;
3590  int status;
3591 
3592  /* node is assumed to be regular */
3593  if (cuddIsConstant(node)) {
3594  if (node == background || node == zero) {
3595  EpdMakeZero(epd, 0);
3596  } else {
3597  EpdCopy(max, epd);
3598  }
3599  return(0);
3600  }
3601  if (node->ref != 1 && st_lookup(table, node, &res)) {
3602  EpdCopy(res, epd);
3603  return(0);
3604  }
3605 
3606  Nt = cuddT(node); Ne = cuddE(node);
3607 
3608  status = ddEpdCountMintermAux(Nt,max,&minT,table);
3609  if (status == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM);
3610  EpdMultiply(&minT, (double)0.5);
3611  status = ddEpdCountMintermAux(Cudd_Regular(Ne),max,&minE,table);
3612  if (status == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM);
3613  if (Cudd_IsComplement(Ne)) {
3614  EpdSubtract3(max, &minE, epd);
3615  EpdCopy(epd, &minE);
3616  }
3617  EpdMultiply(&minE, (double)0.5);
3618  EpdAdd3(&minT, &minE, epd);
3619 
3620  if (node->ref > 1) {
3621  min = EpdAlloc();
3622  if (!min)
3623  return(CUDD_OUT_OF_MEM);
3624  EpdCopy(epd, min);
3625  if (st_insert(table, (char *)node, (char *)min) == ST_OUT_OF_MEM) {
3626  EpdFree(min);
3627  return(CUDD_OUT_OF_MEM);
3628  }
3629  }
3630 
3631  return(0);
3632 
3633 } /* end of ddEpdCountMintermAux */
3634 
3635 
3652 static double
3654  DdNode * N,
3655  st_table * table)
3656 {
3657 
3658  DdNode *node, *Nt, *Ne;
3659  double paths, *ppaths, paths1, paths2;
3660  double *dummy;
3661 
3662  node = Cudd_Regular(N);
3663  if (cuddIsConstant(node)) {
3664  return((double) !(Cudd_IsComplement(N) || cuddV(node)==DD_ZERO_VAL));
3665  }
3666  if (st_lookup(table, N, &dummy)) {
3667  paths = *dummy;
3668  return(paths);
3669  }
3670 
3671  Nt = cuddT(node); Ne = cuddE(node);
3672  if (node != N) {
3673  Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne);
3674  }
3675 
3676  paths1 = ddCountPathsToNonZero(Nt,table);
3677  if (paths1 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
3678  paths2 = ddCountPathsToNonZero(Ne,table);
3679  if (paths2 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
3680  paths = paths1 + paths2;
3681 
3682  ppaths = ALLOC(double,1);
3683  if (ppaths == NULL) {
3684  return((double)CUDD_OUT_OF_MEM);
3685  }
3686 
3687  *ppaths = paths;
3688 
3689  if (st_add_direct(table,(char *)N, (char *)ppaths) == ST_OUT_OF_MEM) {
3690  FREE(ppaths);
3691  return((double)CUDD_OUT_OF_MEM);
3692  }
3693  return(paths);
3694 
3695 } /* end of ddCountPathsToNonZero */
3696 
3697 
3711 static void
3713  DdNode * f,
3714  int * support)
3715 {
3716  if (cuddIsConstant(f) || Cudd_IsComplement(f->next))
3717  return;
3718 
3719  support[f->index] = 1;
3720  ddSupportStep(cuddT(f),support);
3721  ddSupportStep(Cudd_Regular(cuddE(f)),support);
3722  /* Mark as visited. */
3723  f->next = Cudd_Complement(f->next);
3724 
3725 } /* end of ddSupportStep */
3726 
3727 
3740 static void
3742  DdNode * f)
3743 {
3744  if (!Cudd_IsComplement(f->next)) {
3745  return;
3746  }
3747  /* Clear visited flag. */
3748  f->next = Cudd_Regular(f->next);
3749  if (cuddIsConstant(f)) {
3750  return;
3751  }
3752  ddClearFlag(cuddT(f));
3754  return;
3755 
3756 } /* end of ddClearFlag */
3757 
3758 
3771 static int
3773  DdNode * n)
3774 {
3775  int tval, eval;
3776 
3777  if (Cudd_IsComplement(n->next)) {
3778  return(0);
3779  }
3780  n->next = Cudd_Not(n->next);
3781  if (cuddIsConstant(n)) {
3782  return(1);
3783  }
3784  tval = ddLeavesInt(cuddT(n));
3785  eval = ddLeavesInt(Cudd_Regular(cuddE(n)));
3786  return(tval + eval);
3787 
3788 } /* end of ddLeavesInt */
3789 
3790 
3803 static int
3805  DdManager *dd,
3806  DdNode *node,
3807  int nvars,
3808  int nminterms,
3809  char **string)
3810 {
3811  DdNode *N, *T, *E;
3812  DdNode *one, *bzero;
3813  int i, t, result;
3814  double min1, min2;
3815 
3816  if (string == NULL || node == NULL) return(0);
3817 
3818  /* The constant 0 function has no on-set cubes. */
3819  one = DD_ONE(dd);
3820  bzero = Cudd_Not(one);
3821  if (nminterms == 0 || node == bzero) return(1);
3822  if (node == one) {
3823  return(1);
3824  }
3825 
3826  N = Cudd_Regular(node);
3827  T = cuddT(N); E = cuddE(N);
3828  if (Cudd_IsComplement(node)) {
3829  T = Cudd_Not(T); E = Cudd_Not(E);
3830  }
3831 
3832  min1 = Cudd_CountMinterm(dd, T, nvars) / 2.0;
3833  if (min1 == (double)CUDD_OUT_OF_MEM) return(0);
3834  min2 = Cudd_CountMinterm(dd, E, nvars) / 2.0;
3835  if (min2 == (double)CUDD_OUT_OF_MEM) return(0);
3836 
3837  t = (int)((double)nminterms * min1 / (min1 + min2) + 0.5);
3838  for (i = 0; i < t; i++)
3839  string[i][N->index] = '1';
3840  for (i = t; i < nminterms; i++)
3841  string[i][N->index] = '0';
3842 
3843  result = ddPickArbitraryMinterms(dd,T,nvars,t,&string[0]);
3844  if (result == 0)
3845  return(0);
3846  result = ddPickArbitraryMinterms(dd,E,nvars,nminterms-t,&string[t]);
3847  return(result);
3848 
3849 } /* end of ddPickArbitraryMinterms */
3850 
3851 
3864 static int
3866  DdManager *dd,
3867  DdNode *node,
3868  double *weight,
3869  char *string)
3870 {
3871  DdNode *N, *T, *E;
3872  DdNode *one, *bzero;
3873 
3874  if (string == NULL || node == NULL) return(0);
3875 
3876  /* The constant 0 function has no on-set cubes. */
3877  one = DD_ONE(dd);
3878  bzero = Cudd_Not(one);
3879  if (node == bzero) return(0);
3880 
3881  if (node == DD_ONE(dd)) return(1);
3882 
3883  for (;;) {
3884  N = Cudd_Regular(node);
3885  if (N == one)
3886  break;
3887  T = cuddT(N);
3888  E = cuddE(N);
3889  if (Cudd_IsComplement(node)) {
3890  T = Cudd_Not(T);
3891  E = Cudd_Not(E);
3892  }
3893  if (weight[N->index] >= 0.0) {
3894  if (T == bzero) {
3895  node = E;
3896  string[N->index] = '0';
3897  } else {
3898  node = T;
3899  string[N->index] = '1';
3900  }
3901  } else {
3902  if (E == bzero) {
3903  node = T;
3904  string[N->index] = '1';
3905  } else {
3906  node = E;
3907  string[N->index] = '0';
3908  }
3909  }
3910  }
3911  return(1);
3912 
3913 } /* end of ddPickRepresentativeCube */
3914 
3915 
3927 static enum st_retval
3929  char * key,
3930  char * value,
3931  char * arg)
3932 {
3933  EpDouble *epd;
3934 
3935  epd = (EpDouble *) value;
3936  EpdFree(epd);
3937  return(ST_CONTINUE);
3938 
3939 } /* end of ddEpdFree */
3940 
3941 
3956 static void
3958  DdManager *dd,
3959  DdNode *f,
3960  int *SP)
3961 {
3962  int index;
3963  DdNode *var;
3964 
3965  if (cuddIsConstant(f) || Cudd_IsComplement(f->next)) {
3966  return;
3967  }
3968 
3969  index = f->index;
3970  var = dd->vars[index];
3971  /* It is possible that var is embedded in f. That causes no problem,
3972  ** though, because if we see it after encountering another node with
3973  ** the same index, nothing is supposed to happen.
3974  */
3975  if (!Cudd_IsComplement(var->next)) {
3976  var->next = Cudd_Complement(var->next);
3977  dd->stack[*SP] = (DdNode *)(ptrint) index;
3978  (*SP)++;
3979  }
3980  ddFindSupport(dd, cuddT(f), SP);
3981  ddFindSupport(dd, Cudd_Regular(cuddE(f)), SP);
3982  /* Mark as visited. */
3983  f->next = Cudd_Complement(f->next);
3984 
3985 } /* end of ddFindSupport */
3986 
3987 
3997 static void
3999  DdManager *dd,
4000  int SP)
4001 {
4002  int i;
4003 
4004  for (i = 0; i < SP; i++) {
4005  int index = (int) (ptrint) dd->stack[i];
4006  DdNode *var = dd->vars[index];
4007  var->next = Cudd_Regular(var->next);
4008  }
4009 
4010 } /* end of ddClearVars */
4011 
4012 
4023 static int
4025  const void *a,
4026  const void *b)
4027 {
4028  int ia = *((int *) a);
4029  int ib = *((int *) b);
4030  return(ia - ib);
4031 
4032 } /* end of indexCompare */
DdHalfWord ref
Definition: cudd.h:272
DdNode * Cudd_bddPickOneMinterm(DdManager *dd, DdNode *f, DdNode **vars, int n)
Definition: cuddUtil.c:1299
#define cuddRef(n)
Definition: cuddInt.h:557
DdNode * node
Definition: cuddInt.h:227
int cuddCollectNodes(DdNode *f, st_table *visited)
Definition: cuddUtil.c:2933
DdGen * Cudd_FirstPrime(DdManager *dd, DdNode *l, DdNode *u, int **cube)
Definition: cuddUtil.c:2036
DdNode * Cudd_SubsetWithMaskVars(DdManager *dd, DdNode *f, DdNode **vars, int nvars, DdNode **maskVars, int mvars)
Definition: cuddUtil.c:1610
int ptrint
Definition: cuddInt.h:249
#define CUDD_OUT_OF_MEM
Definition: cudd.h:91
int Cudd_NextNode(DdGen *gen, DdNode **node)
Definition: cuddUtil.c:2467
static void ddFindSupport(DdManager *dd, DdNode *f, int *SP)
Definition: cuddUtil.c:3957
DdNode ** Cudd_bddPickArbitraryMinterms(DdManager *dd, DdNode *f, DdNode **vars, int n, int k)
Definition: cuddUtil.c:1401
int type
Definition: cuddInt.h:208
void EpdMultiply(EpDouble *epd1, double value)
Definition: epd.c:204
#define ddHash(f, g, s)
Definition: cuddInt.h:696
void EpdFree(EpDouble *epd)
Definition: epd.c:116
int st_lookup(st_table *, void *, void *)
Definition: st.c:286
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: st.h:60
#define CUDD_VERSION
Definition: cudd.h:75
int Cudd_SupportSize(DdManager *dd, DdNode *f)
Definition: cuddUtil.c:882
int strcmp()
int Cudd_SupportIndices(DdManager *dd, DdNode *f, int **indices)
Definition: cuddUtil.c:744
double Cudd_Density(DdManager *dd, DdNode *f, int nvars)
Definition: cuddUtil.c:2810
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:150
void Cudd_Srandom(long seed)
Definition: cuddUtil.c:2772
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
#define FREE(obj)
Definition: util.h:80
void Cudd_PrintVersion(FILE *fp)
Definition: cuddUtil.c:2600
#define CUDD_GEN_ZDD_PATHS
Definition: cuddInt.h:197
#define LEQQ1
Definition: cuddUtil.c:123
int st_foreach(st_table *, ST_PFSR, char *)
Definition: st.c:725
Definition: st.h:78
DdNode * Cudd_bddComputeCube(DdManager *dd, DdNode **vars, int *phase, int n)
Definition: cuddUtil.c:2204
#define assert(ex)
Definition: util.h:141
static double ddCountPathsToNonZero(DdNode *N, st_table *table)
Definition: cuddUtil.c:3653
DdNode * cuddUniqueConst(DdManager *unique, CUDD_VALUE_TYPE value)
Definition: cuddTable.c:1479
DdManager * manager
Definition: cuddInt.h:298
#define LEQQ2
Definition: cuddUtil.c:127
#define CUDD_GEN_NODES
Definition: cuddInt.h:196
static int ddPickArbitraryMinterms(DdManager *dd, DdNode *node, int nvars, int nminterms, char **string)
Definition: cuddUtil.c:3804
int size
Definition: cuddInt.h:345
static int cuddEstimateCofactorSimple(DdNode *node, int i)
Definition: cuddUtil.c:3407
void st_free_table(st_table *)
Definition: st.c:252
#define Cudd_IsConstant(node)
Definition: cudd.h:339
int Cudd_PrintDebug(DdManager *dd, DdNode *f, int n, int pr)
Definition: cuddUtil.c:386
struct DdGen::@1::@5 nodes
DdNode * Cudd_ReadLogicZero(DdManager *dd)
Definition: cuddAPI.c:1298
#define Cudd_Regular(node)
Definition: cudd.h:384
int Cudd_EstimateCofactor(DdManager *dd, DdNode *f, int i, int phase)
Definition: cuddUtil.c:481
void Cudd_OutOfMem(long size)
Definition: cuddUtil.c:2845
static DdNode * cuddUniqueLookup(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddUtil.c:3348
#define MODULUS1
Definition: cuddUtil.c:121
int Cudd_DagSize(DdNode *node)
Definition: cuddUtil.c:446
static double ddCountPathAux(DdNode *node, st_table *table)
Definition: cuddUtil.c:3520
Definition: cuddInt.h:206
DdSubtable * subtables
Definition: cuddInt.h:349
static int dp2(DdManager *dd, DdNode *f, st_table *t)
Definition: cuddUtil.c:3026
#define DD_ZERO_VAL
Definition: cuddInt.h:109
DdGen * Cudd_FirstCube(DdManager *dd, DdNode *f, int **cube, CUDD_VALUE_TYPE *value)
Definition: cuddUtil.c:1806
DdNode * Cudd_bddIte(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:142
DdNode * Cudd_addComputeCube(DdManager *dd, DdNode **vars, int *phase, int n)
Definition: cuddUtil.c:2254
int EpdCmp(const char *key1, const char *key2)
Definition: epd.c:92
DdGen * Cudd_FirstNode(DdManager *dd, DdNode *f, DdNode **node)
Definition: cuddUtil.c:2408
static DdNode * background
Definition: cuddUtil.c:149
static int ddPickRepresentativeCube(DdManager *dd, DdNode *node, double *weight, char *string)
Definition: cuddUtil.c:3865
#define LEQR2
Definition: cuddUtil.c:128
int Cudd_NextCube(DdGen *gen, int **cube, CUDD_VALUE_TYPE *value)
Definition: cuddUtil.c:1925
DdNode * cuddHashTableLookup1(DdHashTable *hash, DdNode *f)
Definition: cuddLCache.c:864
DdNode ** stack
Definition: cuddInt.h:364
int Cudd_ReadSize(DdManager *dd)
Definition: cuddAPI.c:1681
int Cudd_SharingSize(DdNode **nodeArray, int n)
Definition: cuddUtil.c:548
#define bang(f)
Definition: cuddUtil.c:160
double Cudd_CountPathsToNonZero(DdNode *node)
Definition: cuddUtil.c:711
#define CUDD_GEN_NONEMPTY
Definition: cuddInt.h:199
struct DdNode DdNode
Definition: cudd.h:262
#define cuddV(node)
Definition: cuddInt.h:641
DdNode * Cudd_LargestCube(DdManager *manager, DdNode *f, int *length)
Definition: cuddSat.c:288
int st_insert(st_table *, void *, void *)
Definition: st.c:358
static long shuffleSelect
Definition: cuddUtil.c:153
double Cudd_CountMinterm(DdManager *manager, DdNode *node, int nvars)
Definition: cuddUtil.c:582
char * strcpy()
long Cudd_Random(void)
Definition: cuddUtil.c:2710
unsigned int dead
Definition: cuddInt.h:355
static DdNode * one
Definition: cuddSat.c:105
static long shuffleTable[STAB_SIZE]
Definition: cuddUtil.c:154
static long cuddRand
Definition: cuddUtil.c:151
double Cudd_AverageDistance(DdManager *dd)
Definition: cuddUtil.c:2622
#define STAB_SIZE
Definition: cuddUtil.c:129
int Cudd_bddPrintCover(DdManager *dd, DdNode *l, DdNode *u)
Definition: cuddUtil.c:257
#define Cudd_IsComplement(node)
Definition: cudd.h:412
static char rcsid [] DD_UNUSED
Definition: cuddUtil.c:146
void Cudd_SetEpsilon(DdManager *dd, CUDD_VALUE_TYPE ep)
Definition: cuddAPI.c:2733
DdNode sentinel
Definition: cuddInt.h:328
DdNode * Cudd_bddMakePrime(DdManager *dd, DdNode *cube, DdNode *f)
Definition: cuddSat.c:871
int Cudd_BddToCubeArray(DdManager *dd, DdNode *cube, int *array)
Definition: cuddUtil.c:2354
DdNode ** stack
Definition: cuddInt.h:225
DdNode * Cudd_Cofactor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddCof.c:119
#define ALLOC(type, num)
Definition: util.h:76
DdNode * Cudd_IndicesToCube(DdManager *dd, int *array, int n)
Definition: cuddUtil.c:2561
int Cudd_NextPrime(DdGen *gen, int **cube)
Definition: cuddUtil.c:2138
static enum st_retval ddEpdFree(char *key, char *value, char *arg)
Definition: cuddUtil.c:3928
unsigned int dead
Definition: cuddInt.h:316
FILE * out
Definition: cuddInt.h:423
int Cudd_GenFree(DdGen *gen)
Definition: cuddUtil.c:2499
#define LEQA2
Definition: cuddUtil.c:126
int Cudd_PrintMinterm(DdManager *manager, DdNode *node)
Definition: cuddUtil.c:220
static int cuddEstimateCofactor(DdManager *dd, st_table *table, DdNode *node, int i, int phase, DdNode **ptr)
Definition: cuddUtil.c:3248
DdNode * next
Definition: cudd.h:273
DdManager * manager
Definition: cuddInt.h:207
struct DdGen::@1::@4 primes
DdNode * Cudd_VectorSupport(DdManager *dd, DdNode **F, int n)
Definition: cuddUtil.c:966
static void ddSupportStep(DdNode *f, int *support)
Definition: cuddUtil.c:3712
#define ddAbs(x)
Definition: cuddInt.h:799
int Cudd_CountLeaves(DdNode *node)
Definition: cuddUtil.c:1202
double Cudd_CountPath(DdNode *node)
Definition: cuddUtil.c:627
static int ddEpdCountMintermAux(DdNode *node, EpDouble *max, EpDouble *epd, st_table *table)
Definition: cuddUtil.c:3581
static void ddPrintMintermAux(DdManager *dd, DdNode *node, int *list)
Definition: cuddUtil.c:3119
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define ddMax(x, y)
Definition: cuddInt.h:785
static DdNode * zero
Definition: cuddUtil.c:149
DdNode ** nodelist
Definition: cuddInt.h:311
int Cudd_EpdCountMinterm(DdManager *manager, DdNode *node, int nvars, EpDouble *epd)
Definition: cuddUtil.c:661
int cuddP(DdManager *dd, DdNode *f)
Definition: cuddUtil.c:2874
#define Cudd_Complement(node)
Definition: cudd.h:398
DdNodePtr * cuddNodeArray(DdNode *f, int *n)
Definition: cuddUtil.c:2987
static int ddDagInt(DdNode *n)
Definition: cuddUtil.c:3173
#define LEQR1
Definition: cuddUtil.c:124
int st_ptrcmp(const char *, const char *)
Definition: st.c:849
void cuddHashTableQuit(DdHashTable *hash)
Definition: cuddLCache.c:607
st_retval
Definition: st.h:78
int Cudd_IsGenEmpty(DdGen *gen)
Definition: cuddUtil.c:2539
DdNode * Cudd_bddOr(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:417
#define cuddT(node)
Definition: cuddInt.h:609
enum st_retval cuddStCountfree(char *key, char *value, char *arg)
Definition: cuddUtil.c:2903
st_table * st_init_table(ST_PFICPCP, ST_PFICPI)
Definition: st.c:163
#define ST_OUT_OF_MEM
Definition: st.h:41
int Cudd_VectorSupportIndices(DdManager *dd, DdNode **F, int n, int **indices)
Definition: cuddUtil.c:912
void EpdAdd3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3)
Definition: epd.c:659
int st_add_direct(st_table *, void *, void *)
Definition: st.c:410
#define cuddI(dd, index)
Definition: cuddInt.h:659
unsigned int ptruint
Definition: cuddInt.h:250
DdNode * Cudd_ReadOne(DdManager *dd)
Definition: cuddAPI.c:1227
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:645
DdNode * Cudd_addIte(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddAddIte.c:125
#define st_is_member(table, key)
Definition: st.h:107
static int ddLeavesInt(DdNode *n)
Definition: cuddUtil.c:3772
#define CUDD_VALUE_TYPE
Definition: cudd.h:90
int Cudd_bddPickOneCube(DdManager *ddm, DdNode *node, char *string)
Definition: cuddUtil.c:1229
int cuddHashTableInsert1(DdHashTable *hash, DdNode *f, DdNode *value, ptrint count)
Definition: cuddLCache.c:812
void EpdPow2(int n, EpDouble *epd)
Definition: epd.c:916
void cuddGetBranches(DdNode *g, DdNode **g1, DdNode **g0)
Definition: cuddCof.c:196
struct DdGen::@1::@3 cubes
DdNode * Cudd_CubeArrayToBdd(DdManager *dd, int *array)
Definition: cuddUtil.c:2306
#define CUDD_GEN_EMPTY
Definition: cuddInt.h:198
int sizeZ
Definition: cuddInt.h:346
DdHalfWord index
Definition: cudd.h:271
void EpdSubtract3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3)
Definition: epd.c:849
unsigned int slots
Definition: cuddInt.h:313
DdNode ** vars
Definition: cuddInt.h:373
DdNode * Cudd_bddIthVar(DdManager *dd, int i)
Definition: cuddAPI.c:430
#define CUDD_GEN_CUBES
Definition: cuddInt.h:194
void EpdMakeZero(EpDouble *epd, int sign)
Definition: epd.c:1136
int * Cudd_VectorSupportIndex(DdManager *dd, DdNode **F, int n)
Definition: cuddUtil.c:1017
union DdGen::@1 gen
DdNode * one
Definition: cuddInt.h:329
#define STAB_DIV
Definition: cuddUtil.c:130
EpDouble * EpdAlloc(void)
Definition: epd.c:71
static long cuddRand2
Definition: cuddUtil.c:152
#define cuddE(node)
Definition: cuddInt.h:625
#define Cudd_NotCond(node, c)
Definition: cudd.h:370
DdNode * Cudd_bddAnd(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:350
static void ddClearFlag(DdNode *f)
Definition: cuddUtil.c:3741
static double ddCountMintermAux(DdNode *node, double max, DdHashTable *table)
Definition: cuddUtil.c:3447
static int indexCompare(const void *a, const void *b)
Definition: cuddUtil.c:4024
#define cuddSatDec(x)
Definition: cuddInt.h:849
DdHashTable * cuddHashTableInit(DdManager *manager, unsigned int keySize, unsigned int initSize)
Definition: cuddLCache.c:557
#define MODULUS2
Definition: cuddUtil.c:125
int st_ptrhash(char *, int)
Definition: st.c:811
int Cudd_EstimateCofactorSimple(DdNode *node, int i)
Definition: cuddUtil.c:521
int Cudd_VectorSupportSize(DdManager *dd, DdNode **F, int n)
Definition: cuddUtil.c:1063
DdSubtable constants
Definition: cuddInt.h:351
static int result
Definition: cuddGenetic.c:121
int * Cudd_SupportIndex(DdManager *dd, DdNode *f)
Definition: cuddUtil.c:842
#define DD_ONE(dd)
Definition: cuddInt.h:864
int shift
Definition: cuddInt.h:312
void EpdCopy(EpDouble *from, EpDouble *to)
Definition: epd.c:1181
int Cudd_ClassifySupport(DdManager *dd, DdNode *f, DdNode *g, DdNode **common, DdNode **onlyF, DdNode **onlyG)
Definition: cuddUtil.c:1101
DdNode * Cudd_Support(DdManager *dd, DdNode *f)
Definition: cuddUtil.c:789
#define CUDD_GEN_PRIMES
Definition: cuddInt.h:195
#define LEQA1
Definition: cuddUtil.c:122
int * perm
Definition: cuddInt.h:369
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
CUDD_VALUE_TYPE Cudd_ReadEpsilon(DdManager *dd)
Definition: cuddAPI.c:2712
static void ddClearVars(DdManager *dd, int SP)
Definition: cuddUtil.c:3998
DdNode * background
Definition: cuddInt.h:333
static int cuddNodeArrayRecur(DdNode *f, DdNodePtr *table, int index)
Definition: cuddUtil.c:3208
int status
Definition: cuddInt.h:209
#define DD_ZERO(dd)
Definition: cuddInt.h:880