SVF
cuddSat.c
Go to the documentation of this file.
1 
75 #include "CUDD/util.h"
76 #include "CUDD/cuddInt.h"
77 
78 /*---------------------------------------------------------------------------*/
79 /* Constant declarations */
80 /*---------------------------------------------------------------------------*/
81 
82 #define DD_BIGGY 100000000
83 
84 /*---------------------------------------------------------------------------*/
85 /* Stucture declarations */
86 /*---------------------------------------------------------------------------*/
87 
88 /*---------------------------------------------------------------------------*/
89 /* Type declarations */
90 /*---------------------------------------------------------------------------*/
91 
92 typedef struct cuddPathPair {
93  int pos;
94  int neg;
95 } cuddPathPair;
96 
97 /*---------------------------------------------------------------------------*/
98 /* Variable declarations */
99 /*---------------------------------------------------------------------------*/
100 
101 #ifndef lint
102 static char rcsid[] DD_UNUSED = "$Id: cuddSat.c,v 1.39 2012/02/05 01:07:19 fabio Exp $";
103 #endif
104 
105 static DdNode *one, *zero;
106 
107 /*---------------------------------------------------------------------------*/
108 /* Macro declarations */
109 /*---------------------------------------------------------------------------*/
110 
111 #define WEIGHT(weight, col) ((weight) == NULL ? 1 : weight[col])
112 
113 #ifdef __cplusplus
114 extern "C" {
115 #endif
116 
119 /*---------------------------------------------------------------------------*/
120 /* Static function prototypes */
121 /*---------------------------------------------------------------------------*/
122 
123 static enum st_retval freePathPair (char *key, char *value, char *arg);
124 static cuddPathPair getShortest (DdNode *root, int *cost, int *support, st_table *visited);
125 static DdNode * getPath (DdManager *manager, st_table *visited, DdNode *f, int *weight, int cost);
126 static cuddPathPair getLargest (DdNode *root, st_table *visited);
127 static DdNode * getCube (DdManager *manager, st_table *visited, DdNode *f, int cost);
128 static DdNode * ddBddMaximallyExpand(DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f);
129 static int ddBddShortestPathUnate(DdManager *dd, DdNode *f, int *phases, st_table *table);
130 static DdNode * ddGetLargestCubeUnate(DdManager *dd, DdNode *f, int *phases, st_table *table);
131 
134 #ifdef __cplusplus
135 }
136 #endif
137 
138 /*---------------------------------------------------------------------------*/
139 /* Definition of exported functions */
140 /*---------------------------------------------------------------------------*/
141 
142 
158 DdNode *
160  DdManager * dd,
161  DdNode * f,
162  int * inputs)
163 {
164  int comple;
165  DdNode *ptr;
166 
167  comple = Cudd_IsComplement(f);
168  ptr = Cudd_Regular(f);
169 
170  while (!cuddIsConstant(ptr)) {
171  if (inputs[ptr->index] == 1) {
172  ptr = cuddT(ptr);
173  } else {
174  comple ^= Cudd_IsComplement(cuddE(ptr));
175  ptr = Cudd_Regular(cuddE(ptr));
176  }
177  }
178  return(Cudd_NotCond(ptr,comple));
179 
180 } /* end of Cudd_Eval */
181 
182 
202 DdNode *
204  DdManager * manager,
205  DdNode * f,
206  int * weight,
207  int * support,
208  int * length)
209 {
210  DdNode *F;
211  st_table *visited;
212  DdNode *sol;
213  cuddPathPair *rootPair;
214  int complement, cost;
215  int i;
216 
217  one = DD_ONE(manager);
218  zero = DD_ZERO(manager);
219 
220  /* Initialize support. Support does not depend on variable order.
221  ** Hence, it does not need to be reinitialized if reordering occurs.
222  */
223  if (support) {
224  for (i = 0; i < manager->size; i++) {
225  support[i] = 0;
226  }
227  }
228 
229  if (f == Cudd_Not(one) || f == zero) {
230  *length = DD_BIGGY;
231  return(Cudd_Not(one));
232  }
233  /* From this point on, a path exists. */
234 
235  do {
236  manager->reordered = 0;
237 
238  /* Initialize visited table. */
239  visited = st_init_table(st_ptrcmp, st_ptrhash);
240 
241  /* Now get the length of the shortest path(s) from f to 1. */
242  (void) getShortest(f, weight, support, visited);
243 
244  complement = Cudd_IsComplement(f);
245 
246  F = Cudd_Regular(f);
247 
248  if (!st_lookup(visited, F, &rootPair)) return(NULL);
249 
250  if (complement) {
251  cost = rootPair->neg;
252  } else {
253  cost = rootPair->pos;
254  }
255 
256  /* Recover an actual shortest path. */
257  sol = getPath(manager,visited,f,weight,cost);
258 
259  st_foreach(visited, freePathPair, NULL);
260  st_free_table(visited);
261 
262  } while (manager->reordered == 1);
263 
264  *length = cost;
265  return(sol);
266 
267 } /* end of Cudd_ShortestPath */
268 
269 
287 DdNode *
289  DdManager * manager,
290  DdNode * f,
291  int * length)
292 {
293  register DdNode *F;
294  st_table *visited;
295  DdNode *sol;
296  cuddPathPair *rootPair;
297  int complement, cost;
298 
299  one = DD_ONE(manager);
300  zero = DD_ZERO(manager);
301 
302  if (f == Cudd_Not(one) || f == zero) {
303  if (length != NULL) {
304  *length = DD_BIGGY;
305  }
306  return(Cudd_Not(one));
307  }
308  /* From this point on, a path exists. */
309 
310  do {
311  manager->reordered = 0;
312 
313  /* Initialize visited table. */
314  visited = st_init_table(st_ptrcmp, st_ptrhash);
315 
316  /* Now get the length of the shortest path(s) from f to 1. */
317  (void) getLargest(f, visited);
318 
319  complement = Cudd_IsComplement(f);
320 
321  F = Cudd_Regular(f);
322 
323  if (!st_lookup(visited, F, &rootPair)) return(NULL);
324 
325  if (complement) {
326  cost = rootPair->neg;
327  } else {
328  cost = rootPair->pos;
329  }
330 
331  /* Recover an actual shortest path. */
332  sol = getCube(manager,visited,f,cost);
333 
334  st_foreach(visited, freePathPair, NULL);
335  st_free_table(visited);
336 
337  } while (manager->reordered == 1);
338 
339  if (length != NULL) {
340  *length = cost;
341  }
342  return(sol);
343 
344 } /* end of Cudd_LargestCube */
345 
346 
363 int
365  DdManager * manager,
366  DdNode * f,
367  int * weight)
368 {
369  register DdNode *F;
370  st_table *visited;
371  cuddPathPair *my_pair;
372  int complement, cost;
373 
374  one = DD_ONE(manager);
375  zero = DD_ZERO(manager);
376 
377  if (f == Cudd_Not(one) || f == zero) {
378  return(DD_BIGGY);
379  }
380 
381  /* From this point on, a path exists. */
382  /* Initialize visited table and support. */
383  visited = st_init_table(st_ptrcmp, st_ptrhash);
384 
385  /* Now get the length of the shortest path(s) from f to 1. */
386  (void) getShortest(f, weight, NULL, visited);
387 
388  complement = Cudd_IsComplement(f);
389 
390  F = Cudd_Regular(f);
391 
392  if (!st_lookup(visited, F, &my_pair)) return(CUDD_OUT_OF_MEM);
393 
394  if (complement) {
395  cost = my_pair->neg;
396  } else {
397  cost = my_pair->pos;
398  }
399 
400  st_foreach(visited, freePathPair, NULL);
401  st_free_table(visited);
402 
403  return(cost);
404 
405 } /* end of Cudd_ShortestLength */
406 
407 
423 DdNode *
425  DdManager * dd,
426  DdNode * f,
427  int i)
428 {
429  unsigned int topf, level;
430  DdNode *F, *fv, *fvn, *res;
431  DD_CTFP cacheOp;
432 
433  statLine(dd);
434 #ifdef DD_DEBUG
435  assert(0 <= i && i < dd->size);
436 #endif
437 
438  F = Cudd_Regular(f);
439  topf = cuddI(dd,F->index);
440 
441  /* Check terminal case. If topf > i, f does not depend on var.
442  ** Therefore, f is unate in i.
443  */
444  level = (unsigned) dd->perm[i];
445  if (topf > level) {
446  return(DD_ONE(dd));
447  }
448 
449  /* From now on, f is not constant. */
450 
451  /* Check cache. */
452  cacheOp = (DD_CTFP) Cudd_Decreasing;
453  res = cuddCacheLookup2(dd,cacheOp,f,dd->vars[i]);
454  if (res != NULL) {
455  return(res);
456  }
457 
458  /* Compute cofactors. */
459  fv = cuddT(F); fvn = cuddE(F);
460  if (F != f) {
461  fv = Cudd_Not(fv);
462  fvn = Cudd_Not(fvn);
463  }
464 
465  if (topf == (unsigned) level) {
466  /* Special case: if fv is regular, fv(1,...,1) = 1;
467  ** If in addition fvn is complemented, fvn(1,...,1) = 0.
468  ** But then f(1,1,...,1) > f(0,1,...,1). Hence f is not
469  ** monotonic decreasing in i.
470  */
471  if (!Cudd_IsComplement(fv) && Cudd_IsComplement(fvn)) {
472  return(Cudd_Not(DD_ONE(dd)));
473  }
474  res = Cudd_bddLeq(dd,fv,fvn) ? DD_ONE(dd) : Cudd_Not(DD_ONE(dd));
475  } else {
476  res = Cudd_Decreasing(dd,fv,i);
477  if (res == DD_ONE(dd)) {
478  res = Cudd_Decreasing(dd,fvn,i);
479  }
480  }
481 
482  cuddCacheInsert2(dd,cacheOp,f,dd->vars[i],res);
483  return(res);
484 
485 } /* end of Cudd_Decreasing */
486 
487 
503 DdNode *
505  DdManager * dd,
506  DdNode * f,
507  int i)
508 {
509  return(Cudd_Decreasing(dd,Cudd_Not(f),i));
510 
511 } /* end of Cudd_Increasing */
512 
513 
528 int
530  DdManager * dd,
531  DdNode * F,
532  DdNode * G,
533  DdNode * D)
534 {
535  DdNode *tmp, *One, *Gr, *Dr;
536  DdNode *Fv, *Fvn, *Gv, *Gvn, *Dv, *Dvn;
537  int res;
538  unsigned int flevel, glevel, dlevel, top;
539 
540  One = DD_ONE(dd);
541 
542  statLine(dd);
543  /* Check terminal cases. */
544  if (D == One || F == G) return(1);
545  if (D == Cudd_Not(One) || D == DD_ZERO(dd) || F == Cudd_Not(G)) return(0);
546 
547  /* From now on, D is non-constant. */
548 
549  /* Normalize call to increase cache efficiency. */
550  if (F > G) {
551  tmp = F;
552  F = G;
553  G = tmp;
554  }
555  if (Cudd_IsComplement(F)) {
556  F = Cudd_Not(F);
557  G = Cudd_Not(G);
558  }
559 
560  /* From now on, F is regular. */
561 
562  /* Check cache. */
563  tmp = cuddCacheLookup(dd,DD_EQUIV_DC_TAG,F,G,D);
564  if (tmp != NULL) return(tmp == One);
565 
566  /* Find splitting variable. */
567  flevel = cuddI(dd,F->index);
568  Gr = Cudd_Regular(G);
569  glevel = cuddI(dd,Gr->index);
570  top = ddMin(flevel,glevel);
571  Dr = Cudd_Regular(D);
572  dlevel = dd->perm[Dr->index];
573  top = ddMin(top,dlevel);
574 
575  /* Compute cofactors. */
576  if (top == flevel) {
577  Fv = cuddT(F);
578  Fvn = cuddE(F);
579  } else {
580  Fv = Fvn = F;
581  }
582  if (top == glevel) {
583  Gv = cuddT(Gr);
584  Gvn = cuddE(Gr);
585  if (G != Gr) {
586  Gv = Cudd_Not(Gv);
587  Gvn = Cudd_Not(Gvn);
588  }
589  } else {
590  Gv = Gvn = G;
591  }
592  if (top == dlevel) {
593  Dv = cuddT(Dr);
594  Dvn = cuddE(Dr);
595  if (D != Dr) {
596  Dv = Cudd_Not(Dv);
597  Dvn = Cudd_Not(Dvn);
598  }
599  } else {
600  Dv = Dvn = D;
601  }
602 
603  /* Solve recursively. */
604  res = Cudd_EquivDC(dd,Fv,Gv,Dv);
605  if (res != 0) {
606  res = Cudd_EquivDC(dd,Fvn,Gvn,Dvn);
607  }
608  cuddCacheInsert(dd,DD_EQUIV_DC_TAG,F,G,D,(res) ? One : Cudd_Not(One));
609 
610  return(res);
611 
612 } /* end of Cudd_EquivDC */
613 
614 
628 int
630  DdManager *dd,
631  DdNode *f,
632  DdNode *g,
633  DdNode *D)
634 {
635  DdNode *tmp, *One, *F, *G;
636  DdNode *Ft, *Fe, *Gt, *Ge, *Dt, *De;
637  int res;
638  unsigned int flevel, glevel, dlevel, top;
639 
640  statLine(dd);
641 
642  One = DD_ONE(dd);
643 
644  /* Check terminal cases. */
645  if (f == g || g == One || f == Cudd_Not(One) || D == One ||
646  D == f || D == Cudd_Not(g)) return(1);
647  /* Check for two-operand cases. */
648  if (D == Cudd_Not(One) || D == g || D == Cudd_Not(f))
649  return(Cudd_bddLeq(dd,f,g));
650  if (g == Cudd_Not(One) || g == Cudd_Not(f)) return(Cudd_bddLeq(dd,f,D));
651  if (f == One) return(Cudd_bddLeq(dd,Cudd_Not(g),D));
652 
653  /* From now on, f, g, and D are non-constant, distinct, and
654  ** non-complementary. */
655 
656  /* Normalize call to increase cache efficiency. We rely on the
657  ** fact that f <= g unless D is equivalent to not(g) <= not(f)
658  ** unless D and to f <= D unless g. We make sure that D is
659  ** regular, and that at most one of f and g is complemented. We also
660  ** ensure that when two operands can be swapped, the one with the
661  ** lowest address comes first. */
662 
663  if (Cudd_IsComplement(D)) {
664  if (Cudd_IsComplement(g)) {
665  /* Special case: if f is regular and g is complemented,
666  ** f(1,...,1) = 1 > 0 = g(1,...,1). If D(1,...,1) = 0, return 0.
667  */
668  if (!Cudd_IsComplement(f)) return(0);
669  /* !g <= D unless !f or !D <= g unless !f */
670  tmp = D;
671  D = Cudd_Not(f);
672  if (g < tmp) {
673  f = Cudd_Not(g);
674  g = tmp;
675  } else {
676  f = Cudd_Not(tmp);
677  }
678  } else {
679  if (Cudd_IsComplement(f)) {
680  /* !D <= !f unless g or !D <= g unless !f */
681  tmp = f;
682  f = Cudd_Not(D);
683  if (tmp < g) {
684  D = g;
685  g = Cudd_Not(tmp);
686  } else {
687  D = Cudd_Not(tmp);
688  }
689  } else {
690  /* f <= D unless g or !D <= !f unless g */
691  tmp = D;
692  D = g;
693  if (tmp < f) {
694  g = Cudd_Not(f);
695  f = Cudd_Not(tmp);
696  } else {
697  g = tmp;
698  }
699  }
700  }
701  } else {
702  if (Cudd_IsComplement(g)) {
703  if (Cudd_IsComplement(f)) {
704  /* !g <= !f unless D or !g <= D unless !f */
705  tmp = f;
706  f = Cudd_Not(g);
707  if (D < tmp) {
708  g = D;
709  D = Cudd_Not(tmp);
710  } else {
711  g = Cudd_Not(tmp);
712  }
713  } else {
714  /* f <= g unless D or !g <= !f unless D */
715  if (g < f) {
716  tmp = g;
717  g = Cudd_Not(f);
718  f = Cudd_Not(tmp);
719  }
720  }
721  } else {
722  /* f <= g unless D or f <= D unless g */
723  if (D < g) {
724  tmp = D;
725  D = g;
726  g = tmp;
727  }
728  }
729  }
730 
731  /* From now on, D is regular. */
732 
733  /* Check cache. */
734  tmp = cuddCacheLookup(dd,DD_BDD_LEQ_UNLESS_TAG,f,g,D);
735  if (tmp != NULL) return(tmp == One);
736 
737  /* Find splitting variable. */
738  F = Cudd_Regular(f);
739  flevel = dd->perm[F->index];
740  G = Cudd_Regular(g);
741  glevel = dd->perm[G->index];
742  top = ddMin(flevel,glevel);
743  dlevel = dd->perm[D->index];
744  top = ddMin(top,dlevel);
745 
746  /* Compute cofactors. */
747  if (top == flevel) {
748  Ft = cuddT(F);
749  Fe = cuddE(F);
750  if (F != f) {
751  Ft = Cudd_Not(Ft);
752  Fe = Cudd_Not(Fe);
753  }
754  } else {
755  Ft = Fe = f;
756  }
757  if (top == glevel) {
758  Gt = cuddT(G);
759  Ge = cuddE(G);
760  if (G != g) {
761  Gt = Cudd_Not(Gt);
762  Ge = Cudd_Not(Ge);
763  }
764  } else {
765  Gt = Ge = g;
766  }
767  if (top == dlevel) {
768  Dt = cuddT(D);
769  De = cuddE(D);
770  } else {
771  Dt = De = D;
772  }
773 
774  /* Solve recursively. */
775  res = Cudd_bddLeqUnless(dd,Ft,Gt,Dt);
776  if (res != 0) {
777  res = Cudd_bddLeqUnless(dd,Fe,Ge,De);
778  }
780 
781  return(res);
782 
783 } /* end of Cudd_bddLeqUnless */
784 
785 
802 int
804  DdManager * dd /* manager */,
805  DdNode * f /* first ADD */,
806  DdNode * g /* second ADD */,
807  CUDD_VALUE_TYPE tolerance /* maximum allowed difference */,
808  int pr /* verbosity level */)
809 {
810  DdNode *fv, *fvn, *gv, *gvn, *r;
811  unsigned int topf, topg;
812 
813  statLine(dd);
814  /* Check terminal cases. */
815  if (f == g) return(1);
816  if (Cudd_IsConstant(f) && Cudd_IsConstant(g)) {
817  if (ddEqualVal(cuddV(f),cuddV(g),tolerance)) {
818  return(1);
819  } else {
820  if (pr>0) {
821  (void) fprintf(dd->out,"Offending nodes:\n");
822  (void) fprintf(dd->out,
823  "f: address = %p\t value = %40.30f\n",
824  (void *) f, cuddV(f));
825  (void) fprintf(dd->out,
826  "g: address = %p\t value = %40.30f\n",
827  (void *) g, cuddV(g));
828  }
829  return(0);
830  }
831  }
832 
833  /* We only insert the result in the cache if the comparison is
834  ** successful. Therefore, if we hit we return 1. */
836  if (r != NULL) {
837  return(1);
838  }
839 
840  /* Compute the cofactors and solve the recursive subproblems. */
841  topf = cuddI(dd,f->index);
842  topg = cuddI(dd,g->index);
843 
844  if (topf <= topg) {fv = cuddT(f); fvn = cuddE(f);} else {fv = fvn = f;}
845  if (topg <= topf) {gv = cuddT(g); gvn = cuddE(g);} else {gv = gvn = g;}
846 
847  if (!Cudd_EqualSupNorm(dd,fv,gv,tolerance,pr)) return(0);
848  if (!Cudd_EqualSupNorm(dd,fvn,gvn,tolerance,pr)) return(0);
849 
850  cuddCacheInsert2(dd,(DD_CTFP)Cudd_EqualSupNorm,f,g,DD_ONE(dd));
851 
852  return(1);
853 
854 } /* end of Cudd_EqualSupNorm */
855 
856 
870 DdNode *
872  DdManager *dd /* manager */,
873  DdNode *cube /* cube to be expanded */,
874  DdNode *f /* function of which the cube is to be made a prime */)
875 {
876  DdNode *res;
877 
878  if (!Cudd_bddLeq(dd,cube,f)) return(NULL);
879 
880  do {
881  dd->reordered = 0;
882  res = cuddBddMakePrime(dd,cube,f);
883  } while (dd->reordered == 1);
884  return(res);
885 
886 } /* end of Cudd_bddMakePrime */
887 
888 
905 DdNode *
907  DdManager *dd /* manager */,
908  DdNode *lb /* cube to be expanded */,
909  DdNode *ub /* upper bound cube */,
910  DdNode *f /* function against which to expand */)
911 {
912  DdNode *res;
913 
914  if (!Cudd_bddLeq(dd,lb,ub)) return(NULL);
915 
916  do {
917  dd->reordered = 0;
918  res = ddBddMaximallyExpand(dd,lb,ub,f);
919  } while (dd->reordered == 1);
920  return(res);
921 
922 } /* end of Cudd_bddMaximallyExpand */
923 
924 
940 DdNode *
942  DdManager *dd /* manager */,
943  DdNode *f /* unate function */,
944  DdNode *phaseBdd /* cube of the phases */)
945 {
946  DdNode *res;
947  int *phases;
948  int retval;
949  st_table *table;
950 
951  /* Extract phase vector for quick access. */
952  phases = ALLOC(int, dd->size);
953  if (phases == NULL) return(NULL);
954  retval = Cudd_BddToCubeArray(dd, phaseBdd, phases);
955  if (retval == 0) {
956  FREE(phases);
957  return(NULL);
958  }
959  do {
960  dd->reordered = 0;
962  if (table == NULL) {
963  FREE(phases);
964  return(NULL);
965  }
966  (void) ddBddShortestPathUnate(dd, f, phases, table);
967  res = ddGetLargestCubeUnate(dd, f, phases, table);
968  st_free_table(table);
969  } while (dd->reordered == 1);
970 
971  FREE(phases);
972  return(res);
973 
974 } /* end of Cudd_bddLargestPrimeUnate */
975 
976 
977 /*---------------------------------------------------------------------------*/
978 /* Definition of internal functions */
979 /*---------------------------------------------------------------------------*/
980 
981 
994 DdNode *
996  DdManager *dd /* manager */,
997  DdNode *cube /* cube to be expanded */,
998  DdNode *f /* function of which the cube is to be made a prime */)
999 {
1000  DdNode *scan;
1001  DdNode *t, *e;
1002  DdNode *res = cube;
1003  DdNode *zero = Cudd_Not(DD_ONE(dd));
1004 
1005  Cudd_Ref(res);
1006  scan = cube;
1007  while (!Cudd_IsConstant(scan)) {
1008  DdNode *reg = Cudd_Regular(scan);
1009  DdNode *var = dd->vars[reg->index];
1010  DdNode *expanded = Cudd_bddExistAbstract(dd,res,var);
1011  if (expanded == NULL) {
1012  Cudd_RecursiveDeref(dd,res);
1013  return(NULL);
1014  }
1015  Cudd_Ref(expanded);
1016  if (Cudd_bddLeq(dd,expanded,f)) {
1017  Cudd_RecursiveDeref(dd,res);
1018  res = expanded;
1019  } else {
1020  Cudd_RecursiveDeref(dd,expanded);
1021  }
1022  cuddGetBranches(scan,&t,&e);
1023  if (t == zero) {
1024  scan = e;
1025  } else if (e == zero) {
1026  scan = t;
1027  } else {
1028  Cudd_RecursiveDeref(dd,res);
1029  return(NULL); /* cube is not a cube */
1030  }
1031  }
1032 
1033  if (scan == DD_ONE(dd)) {
1034  Cudd_Deref(res);
1035  return(res);
1036  } else {
1037  Cudd_RecursiveDeref(dd,res);
1038  return(NULL);
1039  }
1040 
1041 } /* end of cuddBddMakePrime */
1042 
1043 
1044 /*---------------------------------------------------------------------------*/
1045 /* Definition of static functions */
1046 /*---------------------------------------------------------------------------*/
1047 
1048 
1059 static enum st_retval
1061  char * key,
1062  char * value,
1063  char * arg)
1064 {
1065  cuddPathPair *pair;
1066 
1067  pair = (cuddPathPair *) value;
1068  FREE(pair);
1069  return(ST_CONTINUE);
1070 
1071 } /* end of freePathPair */
1072 
1073 
1092 static cuddPathPair
1094  DdNode * root,
1095  int * cost,
1096  int * support,
1097  st_table * visited)
1098 {
1099  cuddPathPair *my_pair, res_pair, pair_T, pair_E;
1100  DdNode *my_root, *T, *E;
1101  int weight;
1102 
1103  my_root = Cudd_Regular(root);
1104 
1105  if (st_lookup(visited, my_root, &my_pair)) {
1106  if (Cudd_IsComplement(root)) {
1107  res_pair.pos = my_pair->neg;
1108  res_pair.neg = my_pair->pos;
1109  } else {
1110  res_pair.pos = my_pair->pos;
1111  res_pair.neg = my_pair->neg;
1112  }
1113  return(res_pair);
1114  }
1115 
1116  /* In the case of a BDD the following test is equivalent to
1117  ** testing whether the BDD is the constant 1. This formulation,
1118  ** however, works for ADDs as well, by assuming the usual
1119  ** dichotomy of 0 and != 0.
1120  */
1121  if (cuddIsConstant(my_root)) {
1122  if (my_root != zero) {
1123  res_pair.pos = 0;
1124  res_pair.neg = DD_BIGGY;
1125  } else {
1126  res_pair.pos = DD_BIGGY;
1127  res_pair.neg = 0;
1128  }
1129  } else {
1130  T = cuddT(my_root);
1131  E = cuddE(my_root);
1132 
1133  pair_T = getShortest(T, cost, support, visited);
1134  pair_E = getShortest(E, cost, support, visited);
1135  weight = WEIGHT(cost, my_root->index);
1136  res_pair.pos = ddMin(pair_T.pos+weight, pair_E.pos);
1137  res_pair.neg = ddMin(pair_T.neg+weight, pair_E.neg);
1138 
1139  /* Update support. */
1140  if (support != NULL) {
1141  support[my_root->index] = 1;
1142  }
1143  }
1144 
1145  my_pair = ALLOC(cuddPathPair, 1);
1146  if (my_pair == NULL) {
1147  if (Cudd_IsComplement(root)) {
1148  int tmp = res_pair.pos;
1149  res_pair.pos = res_pair.neg;
1150  res_pair.neg = tmp;
1151  }
1152  return(res_pair);
1153  }
1154  my_pair->pos = res_pair.pos;
1155  my_pair->neg = res_pair.neg;
1156 
1157  st_insert(visited, (char *)my_root, (char *)my_pair);
1158  if (Cudd_IsComplement(root)) {
1159  res_pair.pos = my_pair->neg;
1160  res_pair.neg = my_pair->pos;
1161  } else {
1162  res_pair.pos = my_pair->pos;
1163  res_pair.neg = my_pair->neg;
1164  }
1165  return(res_pair);
1166 
1167 } /* end of getShortest */
1168 
1169 
1188 static DdNode *
1190  DdManager * manager,
1191  st_table * visited,
1192  DdNode * f,
1193  int * weight,
1194  int cost)
1195 {
1196  DdNode *sol, *tmp;
1197  DdNode *my_dd, *T, *E;
1198  cuddPathPair *T_pair, *E_pair;
1199  int Tcost, Ecost;
1200  int complement;
1201 
1202  my_dd = Cudd_Regular(f);
1203  complement = Cudd_IsComplement(f);
1204 
1205  sol = one;
1206  cuddRef(sol);
1207 
1208  while (!cuddIsConstant(my_dd)) {
1209  Tcost = cost - WEIGHT(weight, my_dd->index);
1210  Ecost = cost;
1211 
1212  T = cuddT(my_dd);
1213  E = cuddE(my_dd);
1214 
1215  if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);}
1216 
1217  st_lookup(visited, Cudd_Regular(T), &T_pair);
1218  if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) ||
1219  (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) {
1220  tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol);
1221  if (tmp == NULL) {
1222  Cudd_RecursiveDeref(manager,sol);
1223  return(NULL);
1224  }
1225  cuddRef(tmp);
1226  Cudd_RecursiveDeref(manager,sol);
1227  sol = tmp;
1228 
1229  complement = Cudd_IsComplement(T);
1230  my_dd = Cudd_Regular(T);
1231  cost = Tcost;
1232  continue;
1233  }
1234  st_lookup(visited, Cudd_Regular(E), &E_pair);
1235  if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) ||
1236  (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) {
1237  tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol);
1238  if (tmp == NULL) {
1239  Cudd_RecursiveDeref(manager,sol);
1240  return(NULL);
1241  }
1242  cuddRef(tmp);
1243  Cudd_RecursiveDeref(manager,sol);
1244  sol = tmp;
1245  complement = Cudd_IsComplement(E);
1246  my_dd = Cudd_Regular(E);
1247  cost = Ecost;
1248  continue;
1249  }
1250  (void) fprintf(manager->err,"We shouldn't be here!!\n");
1251  manager->errorCode = CUDD_INTERNAL_ERROR;
1252  return(NULL);
1253  }
1254 
1255  cuddDeref(sol);
1256  return(sol);
1257 
1258 } /* end of getPath */
1259 
1260 
1281 static cuddPathPair
1283  DdNode * root,
1284  st_table * visited)
1285 {
1286  cuddPathPair *my_pair, res_pair, pair_T, pair_E;
1287  DdNode *my_root, *T, *E;
1288 
1289  my_root = Cudd_Regular(root);
1290 
1291  if (st_lookup(visited, my_root, &my_pair)) {
1292  if (Cudd_IsComplement(root)) {
1293  res_pair.pos = my_pair->neg;
1294  res_pair.neg = my_pair->pos;
1295  } else {
1296  res_pair.pos = my_pair->pos;
1297  res_pair.neg = my_pair->neg;
1298  }
1299  return(res_pair);
1300  }
1301 
1302  /* In the case of a BDD the following test is equivalent to
1303  ** testing whether the BDD is the constant 1. This formulation,
1304  ** however, works for ADDs as well, by assuming the usual
1305  ** dichotomy of 0 and != 0.
1306  */
1307  if (cuddIsConstant(my_root)) {
1308  if (my_root != zero) {
1309  res_pair.pos = 0;
1310  res_pair.neg = DD_BIGGY;
1311  } else {
1312  res_pair.pos = DD_BIGGY;
1313  res_pair.neg = 0;
1314  }
1315  } else {
1316  T = cuddT(my_root);
1317  E = cuddE(my_root);
1318 
1319  pair_T = getLargest(T, visited);
1320  pair_E = getLargest(E, visited);
1321  res_pair.pos = ddMin(pair_T.pos, pair_E.pos) + 1;
1322  res_pair.neg = ddMin(pair_T.neg, pair_E.neg) + 1;
1323  }
1324 
1325  my_pair = ALLOC(cuddPathPair, 1);
1326  if (my_pair == NULL) { /* simply do not cache this result */
1327  if (Cudd_IsComplement(root)) {
1328  int tmp = res_pair.pos;
1329  res_pair.pos = res_pair.neg;
1330  res_pair.neg = tmp;
1331  }
1332  return(res_pair);
1333  }
1334  my_pair->pos = res_pair.pos;
1335  my_pair->neg = res_pair.neg;
1336 
1337  /* Caching may fail without affecting correctness. */
1338  st_insert(visited, (char *)my_root, (char *)my_pair);
1339  if (Cudd_IsComplement(root)) {
1340  res_pair.pos = my_pair->neg;
1341  res_pair.neg = my_pair->pos;
1342  } else {
1343  res_pair.pos = my_pair->pos;
1344  res_pair.neg = my_pair->neg;
1345  }
1346  return(res_pair);
1347 
1348 } /* end of getLargest */
1349 
1350 
1369 static DdNode *
1371  DdManager * manager,
1372  st_table * visited,
1373  DdNode * f,
1374  int cost)
1375 {
1376  DdNode *sol, *tmp;
1377  DdNode *my_dd, *T, *E;
1378  cuddPathPair *T_pair, *E_pair;
1379  int Tcost, Ecost;
1380  int complement;
1381 
1382  my_dd = Cudd_Regular(f);
1383  complement = Cudd_IsComplement(f);
1384 
1385  sol = one;
1386  cuddRef(sol);
1387 
1388  while (!cuddIsConstant(my_dd)) {
1389  Tcost = cost - 1;
1390  Ecost = cost - 1;
1391 
1392  T = cuddT(my_dd);
1393  E = cuddE(my_dd);
1394 
1395  if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);}
1396 
1397  if (!st_lookup(visited, Cudd_Regular(T), &T_pair)) return(NULL);
1398  if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) ||
1399  (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) {
1400  tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol);
1401  if (tmp == NULL) {
1402  Cudd_RecursiveDeref(manager,sol);
1403  return(NULL);
1404  }
1405  cuddRef(tmp);
1406  Cudd_RecursiveDeref(manager,sol);
1407  sol = tmp;
1408 
1409  complement = Cudd_IsComplement(T);
1410  my_dd = Cudd_Regular(T);
1411  cost = Tcost;
1412  continue;
1413  }
1414  if (!st_lookup(visited, Cudd_Regular(E), &E_pair)) return(NULL);
1415  if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) ||
1416  (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) {
1417  tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol);
1418  if (tmp == NULL) {
1419  Cudd_RecursiveDeref(manager,sol);
1420  return(NULL);
1421  }
1422  cuddRef(tmp);
1423  Cudd_RecursiveDeref(manager,sol);
1424  sol = tmp;
1425  complement = Cudd_IsComplement(E);
1426  my_dd = Cudd_Regular(E);
1427  cost = Ecost;
1428  continue;
1429  }
1430  (void) fprintf(manager->err,"We shouldn't be here!\n");
1431  manager->errorCode = CUDD_INTERNAL_ERROR;
1432  return(NULL);
1433  }
1434 
1435  cuddDeref(sol);
1436  return(sol);
1437 
1438 } /* end of getCube */
1439 
1440 
1455 static DdNode *
1457  DdManager *dd /* manager */,
1458  DdNode *lb /* cube to be expanded */,
1459  DdNode *ub /* upper bound cube */,
1460  DdNode *f /* function against which to expand */)
1461 {
1462  DdNode *one, *zero, *lbv, *lbvn, *lbnx, *ubv, *ubvn, *fv, *fvn, *res;
1463  DdNode *F, *UB, *LB, *t, *e;
1464  unsigned int top, toplb, topub, topf, index;
1465 
1466  statLine(dd);
1467  /* Terminal cases. */
1468  one = DD_ONE(dd);
1469  zero = Cudd_Not(one);
1470  assert(ub != zero && lb != zero);
1478  if (ub == f || f == one) return(ub);
1479  if (lb == f) return(lb);
1480  if (f == zero || ub == Cudd_Not(f) || lb == one || lb == Cudd_Not(f))
1481  return(zero);
1482  if (!Cudd_IsComplement(lb) && Cudd_IsComplement(f)) return(zero);
1483 
1484  /* Here lb and f are not constant. */
1485 
1486  /* Check cache. Since lb and ub are cubes, their local reference counts
1487  ** are always 1. Hence, we only check the reference count of f.
1488  */
1489  F = Cudd_Regular(f);
1490  if (F->ref != 1) {
1491  DdNode *tmp = cuddCacheLookup(dd, DD_BDD_MAX_EXP_TAG, lb, ub, f);
1492  if (tmp != NULL) {
1493  return(tmp);
1494  }
1495  }
1496 
1497  /* Compute cofactors. For lb we use the non-zero one in
1498  ** both branches of the recursion.
1499  */
1500  LB = Cudd_Regular(lb);
1501  UB = Cudd_Regular(ub);
1502  topf = dd->perm[F->index];
1503  toplb = dd->perm[LB->index];
1504  topub = (ub == one) ? CUDD_CONST_INDEX : dd->perm[UB->index];
1505  assert(toplb <= topub);
1506  top = ddMin(topf,toplb);
1507  if (toplb == top) {
1508  index = LB->index;
1509  lbv = cuddT(LB);
1510  lbvn = cuddE(LB);
1511  if (lb != LB) {
1512  lbv = Cudd_Not(lbv);
1513  lbvn = Cudd_Not(lbvn);
1514  }
1515  if (lbv == zero) {
1516  lbnx = lbvn;
1517  } else {
1518  lbnx = lbv;
1519  }
1520  } else {
1521  index = F->index;
1522  lbnx = lbv = lbvn = lb;
1523  }
1524  if (topub == top) {
1525  ubv = cuddT(UB);
1526  ubvn = cuddE(UB);
1527  if (ub != UB) {
1528  ubv = Cudd_Not(ubv);
1529  ubvn = Cudd_Not(ubvn);
1530  }
1531  } else {
1532  ubv = ubvn = ub;
1533  }
1534  if (topf == top) {
1535  fv = cuddT(F);
1536  fvn = cuddE(F);
1537  if (f != F) {
1538  fv = Cudd_Not(fv);
1539  fvn = Cudd_Not(fvn);
1540  }
1541  } else {
1542  fv = fvn = f;
1543  }
1544 
1545  /* Recursive calls. */
1546  if (ubv != zero) {
1547  t = ddBddMaximallyExpand(dd, lbnx, ubv, fv);
1548  if (t == NULL) return(NULL);
1549  } else {
1550  assert(topub == toplb && topub == top && lbv == zero);
1551  t = zero;
1552  }
1553  cuddRef(t);
1554 
1555  /* If the top variable appears only in lb, the positive and negative
1556  ** cofactors of each operand are the same. We want to avoid a
1557  ** needless recursive call, which would force us to give up the
1558  ** cache optimization trick based on reference counts.
1559  */
1560  if (ubv == ubvn && fv == fvn) {
1561  res = t;
1562  } else {
1563  if (ubvn != zero) {
1564  e = ddBddMaximallyExpand(dd, lbnx, ubvn, fvn);
1565  if (e == NULL) {
1566  Cudd_IterDerefBdd(dd,t);
1567  return(NULL);
1568  }
1569  } else {
1570  assert(topub == toplb && topub == top && lbvn == zero);
1571  e = zero;
1572  }
1573 
1574  if (t == e) {
1575  res = t;
1576  } else {
1577  cuddRef(e);
1578 
1579  if (toplb == top) {
1580  if (lbv == zero) {
1581  /* Top variable appears in negative phase. */
1582  if (t != one) {
1583  DdNode *newT;
1584  if (Cudd_IsComplement(t)) {
1585  newT = cuddUniqueInter(dd, index, Cudd_Not(t), zero);
1586  if (newT == NULL) {
1587  Cudd_IterDerefBdd(dd,t);
1588  Cudd_IterDerefBdd(dd,e);
1589  return(NULL);
1590  }
1591  newT = Cudd_Not(newT);
1592  } else {
1593  newT = cuddUniqueInter(dd, index, t, one);
1594  if (newT == NULL) {
1595  Cudd_IterDerefBdd(dd,t);
1596  Cudd_IterDerefBdd(dd,e);
1597  return(NULL);
1598  }
1599  }
1600  cuddRef(newT);
1601  cuddDeref(t);
1602  t = newT;
1603  }
1604  } else if (lbvn == zero) {
1605  /* Top variable appears in positive phase. */
1606  if (e != one) {
1607  DdNode *newE;
1608  newE = cuddUniqueInter(dd, index, one, e);
1609  if (newE == NULL) {
1610  Cudd_IterDerefBdd(dd,t);
1611  Cudd_IterDerefBdd(dd,e);
1612  return(NULL);
1613  }
1614  cuddRef(newE);
1615  cuddDeref(e);
1616  e = newE;
1617  }
1618  } else {
1619  /* Not a cube. */
1620  Cudd_IterDerefBdd(dd,t);
1621  Cudd_IterDerefBdd(dd,e);
1622  return(NULL);
1623  }
1624  }
1625 
1626  /* Combine results. */
1627  res = cuddBddAndRecur(dd, t, e);
1628  if (res == NULL) {
1629  Cudd_IterDerefBdd(dd,t);
1630  Cudd_IterDerefBdd(dd,e);
1631  return(NULL);
1632  }
1633  cuddRef(res);
1634  Cudd_IterDerefBdd(dd,t);
1635  Cudd_IterDerefBdd(dd,e);
1636  }
1637  }
1638 
1639  /* Cache result and return. */
1640  if (F->ref != 1) {
1641  cuddCacheInsert(dd, DD_BDD_MAX_EXP_TAG, lb, ub, f, res);
1642  }
1643  cuddDeref(res);
1644  return(res);
1645 
1646 } /* end of ddBddMaximallyExpand */
1647 
1648 
1664 static int
1666  DdManager *dd,
1667  DdNode *f,
1668  int *phases,
1669  st_table *table)
1670 {
1671  int positive, l, lT, lE;
1672  DdNode *one = DD_ONE(dd);
1673  DdNode *zero = Cudd_Not(one);
1674  DdNode *F, *fv, *fvn;
1675 
1676  if (st_lookup_int(table, f, &l)) {
1677  return(l);
1678  }
1679  if (f == one) {
1680  l = 0;
1681  } else if (f == zero) {
1682  l = DD_BIGGY;
1683  } else {
1684  F = Cudd_Regular(f);
1685  fv = cuddT(F);
1686  fvn = cuddE(F);
1687  if (f != F) {
1688  fv = Cudd_Not(fv);
1689  fvn = Cudd_Not(fvn);
1690  }
1691  lT = ddBddShortestPathUnate(dd, fv, phases, table);
1692  lE = ddBddShortestPathUnate(dd, fvn, phases, table);
1693  positive = phases[F->index];
1694  l = positive ? ddMin(lT+1, lE) : ddMin(lT, lE+1);
1695  }
1696  if (st_insert(table, f, (void *)(ptrint) l) == ST_OUT_OF_MEM) {
1697  return(CUDD_OUT_OF_MEM);
1698  }
1699  return(l);
1700 
1701 } /* end of ddShortestPathUnate */
1702 
1703 
1716 static DdNode *
1718  DdManager *dd,
1719  DdNode *f,
1720  int *phases,
1721  st_table *table)
1722 {
1723  DdNode *res, *scan;
1724  DdNode *one = DD_ONE(dd);
1725  int cost;
1726 
1727  res = one;
1728  cuddRef(res);
1729  scan = f;
1730  st_lookup_int(table, scan, &cost);
1731 
1732  while (!Cudd_IsConstant(scan)) {
1733  int Pcost, Ncost, Tcost;
1734  DdNode *tmp, *T, *E;
1735  DdNode *rscan = Cudd_Regular(scan);
1736  int index = rscan->index;
1737  assert(phases[index] == 0 || phases[index] == 1);
1738  int positive = phases[index] == 1;
1739  Pcost = positive ? cost - 1 : cost;
1740  Ncost = positive ? cost : cost - 1;
1741  T = cuddT(rscan);
1742  E = cuddE(rscan);
1743  if (rscan != scan) {
1744  T = Cudd_Not(T);
1745  E = Cudd_Not(E);
1746  }
1747  tmp = res;
1748  st_lookup_int(table, T, &Tcost);
1749  if (Tcost == Pcost) {
1750  cost = Pcost;
1751  scan = T;
1752  if (positive) {
1753  tmp = cuddBddAndRecur(dd, dd->vars[index], res);
1754  }
1755  } else {
1756  cost = Ncost;
1757  scan = E;
1758  if (!positive) {
1759  tmp = cuddBddAndRecur(dd, Cudd_Not(dd->vars[index]), res);
1760  }
1761  }
1762  if (tmp == NULL) {
1763  Cudd_IterDerefBdd(dd, res);
1764  return(NULL);
1765  }
1766  cuddRef(tmp);
1767  Cudd_IterDerefBdd(dd, res);
1768  res = tmp;
1769  }
1770 
1771  cuddDeref(res);
1772  return(res);
1773 
1774 } /* end of ddGetLargestCubeUnate */
static char rcsid [] DD_UNUSED
Definition: cuddSat.c:102
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:213
DdHalfWord ref
Definition: cudd.h:272
#define cuddRef(n)
Definition: cuddInt.h:557
DdNode * Cudd_LargestCube(DdManager *manager, DdNode *f, int *length)
Definition: cuddSat.c:288
int ptrint
Definition: cuddInt.h:249
#define CUDD_OUT_OF_MEM
Definition: cudd.h:91
#define cuddDeref(n)
Definition: cuddInt.h:577
int st_lookup(st_table *, void *, void *)
Definition: st.c:286
Definition: st.h:60
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:150
int st_lookup_int(st_table *, void *, int *)
Definition: st.c:322
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
#define FREE(obj)
Definition: util.h:80
int st_foreach(st_table *, ST_PFSR, char *)
Definition: st.c:725
Definition: st.h:78
#define assert(ex)
Definition: util.h:141
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:434
int size
Definition: cuddInt.h:345
DdNode * cuddCacheLookup2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
int Cudd_EquivDC(DdManager *dd, DdNode *F, DdNode *G, DdNode *D)
Definition: cuddSat.c:529
void st_free_table(st_table *)
Definition: st.c:252
#define Cudd_IsConstant(node)
Definition: cudd.h:339
#define Cudd_Regular(node)
Definition: cudd.h:384
DdNode * Cudd_bddExistAbstract(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:127
DdNode * Cudd_Eval(DdManager *dd, DdNode *f, int *inputs)
Definition: cuddSat.c:159
int Cudd_EqualSupNorm(DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE tolerance, int pr)
Definition: cuddSat.c:803
FILE * err
Definition: cuddInt.h:424
#define DD_BDD_MAX_EXP_TAG
Definition: cuddInt.h:191
static enum st_retval freePathPair(char *key, char *value, char *arg)
Definition: cuddSat.c:1060
DdNode * Cudd_ShortestPath(DdManager *manager, DdNode *f, int *weight, int *support, int *length)
Definition: cuddSat.c:203
#define statLine(dd)
Definition: cuddInt.h:990
#define cuddV(node)
Definition: cuddInt.h:641
int st_insert(st_table *, void *, void *)
Definition: st.c:358
DdNode * cuddBddMakePrime(DdManager *dd, DdNode *cube, DdNode *f)
Definition: cuddSat.c:995
int reordered
Definition: cuddInt.h:392
static DdNode * one
Definition: cuddSat.c:105
static cuddPathPair getShortest(DdNode *root, int *cost, int *support, st_table *visited)
Definition: cuddSat.c:1093
#define Cudd_IsComplement(node)
Definition: cudd.h:412
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:308
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
DdNode * Cudd_bddLargestPrimeUnate(DdManager *dd, DdNode *f, DdNode *phaseBdd)
Definition: cuddSat.c:941
#define cuddIsConstant(node)
Definition: cuddInt.h:593
DdNode * Cudd_Increasing(DdManager *dd, DdNode *f, int i)
Definition: cuddSat.c:504
#define CUDD_CONST_INDEX
Definition: cudd.h:113
static DdNode * getPath(DdManager *manager, st_table *visited, DdNode *f, int *weight, int cost)
Definition: cuddSat.c:1189
DdNode * Cudd_bddMaximallyExpand(DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f)
Definition: cuddSat.c:906
#define ddMin(x, y)
Definition: cuddInt.h:771
int st_ptrcmp(const char *, const char *)
Definition: st.c:849
st_retval
Definition: st.h:78
#define cuddT(node)
Definition: cuddInt.h:609
int Cudd_ShortestLength(DdManager *manager, DdNode *f, int *weight)
Definition: cuddSat.c:364
st_table * st_init_table(ST_PFICPCP, ST_PFICPI)
Definition: st.c:163
static DdNode * ddBddMaximallyExpand(DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f)
Definition: cuddSat.c:1456
#define WEIGHT(weight, col)
Definition: cuddSat.c:111
static DdNode * ddGetLargestCubeUnate(DdManager *dd, DdNode *f, int *phases, st_table *table)
Definition: cuddSat.c:1717
#define DD_BDD_LEQ_UNLESS_TAG
Definition: cuddInt.h:189
#define ST_OUT_OF_MEM
Definition: st.h:41
#define ddEqualVal(x, y, e)
Definition: cuddInt.h:814
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995
static DdNode * getCube(DdManager *manager, st_table *visited, DdNode *f, int cost)
Definition: cuddSat.c:1370
struct cuddPathPair cuddPathPair
#define cuddI(dd, index)
Definition: cuddInt.h:659
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:645
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:347
#define CUDD_VALUE_TYPE
Definition: cudd.h:90
#define DD_EQUIV_DC_TAG
Definition: cuddInt.h:183
void cuddGetBranches(DdNode *g, DdNode **g1, DdNode **g0)
Definition: cuddCof.c:196
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdNode * Cudd_Decreasing(DdManager *dd, DdNode *f, int i)
Definition: cuddSat.c:424
DdHalfWord index
Definition: cudd.h:271
DdNode * Cudd_bddMakePrime(DdManager *dd, DdNode *cube, DdNode *f)
Definition: cuddSat.c:871
static int ddBddShortestPathUnate(DdManager *dd, DdNode *f, int *phases, st_table *table)
Definition: cuddSat.c:1665
DdNode ** vars
Definition: cuddInt.h:373
static DdNode * zero
Definition: cuddSat.c:105
#define cuddE(node)
Definition: cuddInt.h:625
#define Cudd_NotCond(node, c)
Definition: cudd.h:370
int st_ptrhash(char *, int)
Definition: st.c:811
#define DD_BIGGY
Definition: cuddSat.c:82
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:217
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:125
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369
int Cudd_bddLeqUnless(DdManager *dd, DdNode *f, DdNode *g, DdNode *D)
Definition: cuddSat.c:629
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1137
static cuddPathPair getLargest(DdNode *root, st_table *visited)
Definition: cuddSat.c:1282
int Cudd_BddToCubeArray(DdManager *dd, DdNode *cube, int *array)
Definition: cuddUtil.c:2354
if(DEFINED IN_SOURCE_BUILD) set(LLVM_LINK_COMPONENTS BitWriter Core IPO IrReader InstCombine Instrumentation Target Linker Analysis ScalarOpts Support Svf Cudd) add_llvm_tool(dvf dda.cpp) else() add_executable(dvf dda.cpp) target_link_libraries(dvf Svf Cudd $
Definition: CMakeLists.txt:2
#define DD_ZERO(dd)
Definition: cuddInt.h:880