SVF
cuddBddAbs.c
Go to the documentation of this file.
1 
66 #include "CUDD/util.h"
67 #include "CUDD/cuddInt.h"
68 
69 
70 /*---------------------------------------------------------------------------*/
71 /* Constant declarations */
72 /*---------------------------------------------------------------------------*/
73 
74 
75 /*---------------------------------------------------------------------------*/
76 /* Stucture declarations */
77 /*---------------------------------------------------------------------------*/
78 
79 
80 /*---------------------------------------------------------------------------*/
81 /* Type declarations */
82 /*---------------------------------------------------------------------------*/
83 
84 
85 /*---------------------------------------------------------------------------*/
86 /* Variable declarations */
87 /*---------------------------------------------------------------------------*/
88 
89 #ifndef lint
90 static char rcsid[] DD_UNUSED = "$Id: cuddBddAbs.c,v 1.28 2012/02/05 01:07:18 fabio Exp $";
91 #endif
92 
93 /*---------------------------------------------------------------------------*/
94 /* Macro declarations */
95 /*---------------------------------------------------------------------------*/
96 
97 
100 /*---------------------------------------------------------------------------*/
101 /* Static function prototypes */
102 /*---------------------------------------------------------------------------*/
103 
104 static int bddCheckPositiveCube (DdManager *manager, DdNode *cube);
105 
109 /*---------------------------------------------------------------------------*/
110 /* Definition of exported functions */
111 /*---------------------------------------------------------------------------*/
112 
113 
126 DdNode *
128  DdManager * manager,
129  DdNode * f,
130  DdNode * cube)
131 {
132  DdNode *res;
133 
134  if (bddCheckPositiveCube(manager, cube) == 0) {
135  (void) fprintf(manager->err,
136  "Error: Can only abstract positive cubes\n");
137  manager->errorCode = CUDD_INVALID_ARG;
138  return(NULL);
139  }
140 
141  do {
142  manager->reordered = 0;
143  res = cuddBddExistAbstractRecur(manager, f, cube);
144  } while (manager->reordered == 1);
145 
146  return(res);
147 
148 } /* end of Cudd_bddExistAbstract */
149 
150 
165 DdNode *
167  DdManager * manager,
168  DdNode * f,
169  DdNode * cube,
170  unsigned int limit)
171 {
172  DdNode *res;
173  unsigned int saveLimit = manager->maxLive;
174 
175  if (bddCheckPositiveCube(manager, cube) == 0) {
176  (void) fprintf(manager->err,
177  "Error: Can only abstract positive cubes\n");
178  manager->errorCode = CUDD_INVALID_ARG;
179  return(NULL);
180  }
181 
182  manager->maxLive = (manager->keys - manager->dead) +
183  (manager->keysZ - manager->deadZ) + limit;
184  do {
185  manager->reordered = 0;
186  res = cuddBddExistAbstractRecur(manager, f, cube);
187  } while (manager->reordered == 1);
188  manager->maxLive = saveLimit;
189 
190  return(res);
191 
192 } /* end of Cudd_bddExistAbstractLimit */
193 
194 
209 DdNode *
211  DdManager * manager,
212  DdNode * f,
213  DdNode * g,
214  DdNode * cube)
215 {
216  DdNode *res;
217 
218  if (bddCheckPositiveCube(manager, cube) == 0) {
219  (void) fprintf(manager->err,
220  "Error: Can only abstract positive cubes\n");
221  manager->errorCode = CUDD_INVALID_ARG;
222  return(NULL);
223  }
224 
225  do {
226  manager->reordered = 0;
227  res = cuddBddXorExistAbstractRecur(manager, f, g, cube);
228  } while (manager->reordered == 1);
229 
230  return(res);
231 
232 } /* end of Cudd_bddXorExistAbstract */
233 
234 
247 DdNode *
249  DdManager * manager,
250  DdNode * f,
251  DdNode * cube)
252 {
253  DdNode *res;
254 
255  if (bddCheckPositiveCube(manager, cube) == 0) {
256  (void) fprintf(manager->err,
257  "Error: Can only abstract positive cubes\n");
258  manager->errorCode = CUDD_INVALID_ARG;
259  return(NULL);
260  }
261 
262  do {
263  manager->reordered = 0;
264  res = cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube);
265  } while (manager->reordered == 1);
266  if (res != NULL) res = Cudd_Not(res);
267 
268  return(res);
269 
270 } /* end of Cudd_bddUnivAbstract */
271 
272 
286 DdNode *
288  DdManager * manager,
289  DdNode * f,
290  int x)
291 {
292  DdNode *res, *var;
293 
294  /* If the variable is not currently in the manager, f cannot
295  ** depend on it.
296  */
297  if (x >= manager->size) return(Cudd_Not(DD_ONE(manager)));
298  var = manager->vars[x];
299 
300  do {
301  manager->reordered = 0;
302  res = cuddBddBooleanDiffRecur(manager, Cudd_Regular(f), var);
303  } while (manager->reordered == 1);
304 
305  return(res);
306 
307 } /* end of Cudd_bddBooleanDiff */
308 
309 
324 int
326  DdManager *dd, /* manager */
327  DdNode *f, /* function */
328  DdNode *var /* variable */)
329 {
330  DdNode *F, *res, *zero, *ft, *fe;
331  unsigned topf, level;
332  DD_CTFP cacheOp;
333  int retval;
334 
335  zero = Cudd_Not(DD_ONE(dd));
336  if (Cudd_IsConstant(f)) return(f == zero);
337 
338  /* From now on f is not constant. */
339  F = Cudd_Regular(f);
340  topf = (unsigned) dd->perm[F->index];
341  level = (unsigned) dd->perm[var->index];
342 
343  /* Check terminal case. If topf > index of var, f does not depend on var.
344  ** Therefore, var is not dependent in f. */
345  if (topf > level) {
346  return(0);
347  }
348 
349  cacheOp = (DD_CTFP) Cudd_bddVarIsDependent;
350  res = cuddCacheLookup2(dd,cacheOp,f,var);
351  if (res != NULL) {
352  return(res != zero);
353  }
354 
355  /* Compute cofactors. */
356  ft = Cudd_NotCond(cuddT(F), f != F);
357  fe = Cudd_NotCond(cuddE(F), f != F);
358 
359  if (topf == level) {
360  retval = Cudd_bddLeq(dd,ft,Cudd_Not(fe));
361  } else {
362  retval = Cudd_bddVarIsDependent(dd,ft,var) &&
363  Cudd_bddVarIsDependent(dd,fe,var);
364  }
365 
366  cuddCacheInsert2(dd,cacheOp,f,var,Cudd_NotCond(zero,retval));
367 
368  return(retval);
369 
370 } /* Cudd_bddVarIsDependent */
371 
372 
373 /*---------------------------------------------------------------------------*/
374 /* Definition of internal functions */
375 /*---------------------------------------------------------------------------*/
376 
377 
392 DdNode *
394  DdManager * manager,
395  DdNode * f,
396  DdNode * cube)
397 {
398  DdNode *F, *T, *E, *res, *res1, *res2, *one;
399 
400  statLine(manager);
401  one = DD_ONE(manager);
402  F = Cudd_Regular(f);
403 
404  /* Cube is guaranteed to be a cube at this point. */
405  if (cube == one || F == one) {
406  return(f);
407  }
408  /* From now on, f and cube are non-constant. */
409 
410  /* Abstract a variable that does not appear in f. */
411  while (manager->perm[F->index] > manager->perm[cube->index]) {
412  cube = cuddT(cube);
413  if (cube == one) return(f);
414  }
415 
416  /* Check the cache. */
417  if (F->ref != 1 && (res = cuddCacheLookup2(manager, Cudd_bddExistAbstract, f, cube)) != NULL) {
418  return(res);
419  }
420 
421  /* Compute the cofactors of f. */
422  T = cuddT(F); E = cuddE(F);
423  if (f != F) {
424  T = Cudd_Not(T); E = Cudd_Not(E);
425  }
426 
427  /* If the two indices are the same, so are their levels. */
428  if (F->index == cube->index) {
429  if (T == one || E == one || T == Cudd_Not(E)) {
430  return(one);
431  }
432  res1 = cuddBddExistAbstractRecur(manager, T, cuddT(cube));
433  if (res1 == NULL) return(NULL);
434  if (res1 == one) {
435  if (F->ref != 1)
436  cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, one);
437  return(one);
438  }
439  cuddRef(res1);
440  res2 = cuddBddExistAbstractRecur(manager, E, cuddT(cube));
441  if (res2 == NULL) {
442  Cudd_IterDerefBdd(manager,res1);
443  return(NULL);
444  }
445  cuddRef(res2);
446  res = cuddBddAndRecur(manager, Cudd_Not(res1), Cudd_Not(res2));
447  if (res == NULL) {
448  Cudd_IterDerefBdd(manager, res1);
449  Cudd_IterDerefBdd(manager, res2);
450  return(NULL);
451  }
452  res = Cudd_Not(res);
453  cuddRef(res);
454  Cudd_IterDerefBdd(manager, res1);
455  Cudd_IterDerefBdd(manager, res2);
456  if (F->ref != 1)
457  cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res);
458  cuddDeref(res);
459  return(res);
460  } else { /* if (cuddI(manager,F->index) < cuddI(manager,cube->index)) */
461  res1 = cuddBddExistAbstractRecur(manager, T, cube);
462  if (res1 == NULL) return(NULL);
463  cuddRef(res1);
464  res2 = cuddBddExistAbstractRecur(manager, E, cube);
465  if (res2 == NULL) {
466  Cudd_IterDerefBdd(manager, res1);
467  return(NULL);
468  }
469  cuddRef(res2);
470  /* ITE takes care of possible complementation of res1 and of the
471  ** case in which res1 == res2. */
472  res = cuddBddIteRecur(manager, manager->vars[F->index], res1, res2);
473  if (res == NULL) {
474  Cudd_IterDerefBdd(manager, res1);
475  Cudd_IterDerefBdd(manager, res2);
476  return(NULL);
477  }
478  cuddDeref(res1);
479  cuddDeref(res2);
480  if (F->ref != 1)
481  cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res);
482  return(res);
483  }
484 
485 } /* end of cuddBddExistAbstractRecur */
486 
487 
502 DdNode *
504  DdManager * manager,
505  DdNode * f,
506  DdNode * g,
507  DdNode * cube)
508 {
509  DdNode *F, *fv, *fnv, *G, *gv, *gnv;
510  DdNode *one, *zero, *r, *t, *e, *Cube;
511  unsigned int topf, topg, topcube, top, index;
512 
513  statLine(manager);
514  one = DD_ONE(manager);
515  zero = Cudd_Not(one);
516 
517  /* Terminal cases. */
518  if (f == g) {
519  return(zero);
520  }
521  if (f == Cudd_Not(g)) {
522  return(one);
523  }
524  if (cube == one) {
525  return(cuddBddXorRecur(manager, f, g));
526  }
527  if (f == one) {
528  return(cuddBddExistAbstractRecur(manager, Cudd_Not(g), cube));
529  }
530  if (g == one) {
531  return(cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube));
532  }
533  if (f == zero) {
534  return(cuddBddExistAbstractRecur(manager, g, cube));
535  }
536  if (g == zero) {
537  return(cuddBddExistAbstractRecur(manager, f, cube));
538  }
539 
540  /* At this point f, g, and cube are not constant. */
541 
542  if (f > g) { /* Try to increase cache efficiency. */
543  DdNode *tmp = f;
544  f = g;
545  g = tmp;
546  }
547 
548  /* Check cache. */
549  r = cuddCacheLookup(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube);
550  if (r != NULL) {
551  return(r);
552  }
553 
554  /* Here we can skip the use of cuddI, because the operands are known
555  ** to be non-constant.
556  */
557  F = Cudd_Regular(f);
558  topf = manager->perm[F->index];
559  G = Cudd_Regular(g);
560  topg = manager->perm[G->index];
561  top = ddMin(topf, topg);
562  topcube = manager->perm[cube->index];
563 
564  if (topcube < top) {
565  return(cuddBddXorExistAbstractRecur(manager, f, g, cuddT(cube)));
566  }
567  /* Now, topcube >= top. */
568 
569  if (topf == top) {
570  index = F->index;
571  fv = cuddT(F);
572  fnv = cuddE(F);
573  if (Cudd_IsComplement(f)) {
574  fv = Cudd_Not(fv);
575  fnv = Cudd_Not(fnv);
576  }
577  } else {
578  index = G->index;
579  fv = fnv = f;
580  }
581 
582  if (topg == top) {
583  gv = cuddT(G);
584  gnv = cuddE(G);
585  if (Cudd_IsComplement(g)) {
586  gv = Cudd_Not(gv);
587  gnv = Cudd_Not(gnv);
588  }
589  } else {
590  gv = gnv = g;
591  }
592 
593  if (topcube == top) {
594  Cube = cuddT(cube);
595  } else {
596  Cube = cube;
597  }
598 
599  t = cuddBddXorExistAbstractRecur(manager, fv, gv, Cube);
600  if (t == NULL) return(NULL);
601 
602  /* Special case: 1 OR anything = 1. Hence, no need to compute
603  ** the else branch if t is 1.
604  */
605  if (t == one && topcube == top) {
606  cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, one);
607  return(one);
608  }
609  cuddRef(t);
610 
611  e = cuddBddXorExistAbstractRecur(manager, fnv, gnv, Cube);
612  if (e == NULL) {
613  Cudd_IterDerefBdd(manager, t);
614  return(NULL);
615  }
616  cuddRef(e);
617 
618  if (topcube == top) { /* abstract */
619  r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e));
620  if (r == NULL) {
621  Cudd_IterDerefBdd(manager, t);
622  Cudd_IterDerefBdd(manager, e);
623  return(NULL);
624  }
625  r = Cudd_Not(r);
626  cuddRef(r);
627  Cudd_IterDerefBdd(manager, t);
628  Cudd_IterDerefBdd(manager, e);
629  cuddDeref(r);
630  } else if (t == e) {
631  r = t;
632  cuddDeref(t);
633  cuddDeref(e);
634  } else {
635  if (Cudd_IsComplement(t)) {
636  r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e));
637  if (r == NULL) {
638  Cudd_IterDerefBdd(manager, t);
639  Cudd_IterDerefBdd(manager, e);
640  return(NULL);
641  }
642  r = Cudd_Not(r);
643  } else {
644  r = cuddUniqueInter(manager,(int)index,t,e);
645  if (r == NULL) {
646  Cudd_IterDerefBdd(manager, t);
647  Cudd_IterDerefBdd(manager, e);
648  return(NULL);
649  }
650  }
651  cuddDeref(e);
652  cuddDeref(t);
653  }
654  cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, r);
655  return (r);
656 
657 } /* end of cuddBddXorExistAbstractRecur */
658 
659 
674 DdNode *
676  DdManager * manager,
677  DdNode * f,
678  DdNode * var)
679 {
680  DdNode *T, *E, *res, *res1, *res2;
681 
682  statLine(manager);
683  if (cuddI(manager,f->index) > manager->perm[var->index]) {
684  /* f does not depend on var. */
685  return(Cudd_Not(DD_ONE(manager)));
686  }
687 
688  /* From now on, f is non-constant. */
689 
690  /* If the two indices are the same, so are their levels. */
691  if (f->index == var->index) {
692  res = cuddBddXorRecur(manager, cuddT(f), cuddE(f));
693  return(res);
694  }
695 
696  /* From now on, cuddI(manager,f->index) < cuddI(manager,cube->index). */
697 
698  /* Check the cache. */
699  res = cuddCacheLookup2(manager, cuddBddBooleanDiffRecur, f, var);
700  if (res != NULL) {
701  return(res);
702  }
703 
704  /* Compute the cofactors of f. */
705  T = cuddT(f); E = cuddE(f);
706 
707  res1 = cuddBddBooleanDiffRecur(manager, T, var);
708  if (res1 == NULL) return(NULL);
709  cuddRef(res1);
710  res2 = cuddBddBooleanDiffRecur(manager, Cudd_Regular(E), var);
711  if (res2 == NULL) {
712  Cudd_IterDerefBdd(manager, res1);
713  return(NULL);
714  }
715  cuddRef(res2);
716  /* ITE takes care of possible complementation of res1 and of the
717  ** case in which res1 == res2. */
718  res = cuddBddIteRecur(manager, manager->vars[f->index], res1, res2);
719  if (res == NULL) {
720  Cudd_IterDerefBdd(manager, res1);
721  Cudd_IterDerefBdd(manager, res2);
722  return(NULL);
723  }
724  cuddDeref(res1);
725  cuddDeref(res2);
726  cuddCacheInsert2(manager, cuddBddBooleanDiffRecur, f, var, res);
727  return(res);
728 
729 } /* end of cuddBddBooleanDiffRecur */
730 
731 
732 /*---------------------------------------------------------------------------*/
733 /* Definition of static functions */
734 /*---------------------------------------------------------------------------*/
735 
746 static int
748  DdManager * manager,
749  DdNode * cube)
750 {
751  if (Cudd_IsComplement(cube)) return(0);
752  if (cube == DD_ONE(manager)) return(1);
753  if (cuddIsConstant(cube)) return(0);
754  if (cuddE(cube) == Cudd_Not(DD_ONE(manager))) {
755  return(bddCheckPositiveCube(manager, cuddT(cube)));
756  }
757  return(0);
758 
759 } /* end of bddCheckPositiveCube */
760 
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:213
DdHalfWord ref
Definition: cudd.h:272
DdNode * cuddBddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:393
#define cuddRef(n)
Definition: cuddInt.h:557
DdNode * Cudd_bddBooleanDiff(DdManager *manager, DdNode *f, int x)
Definition: cuddBddAbs.c:287
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
unsigned int deadZ
Definition: cuddInt.h:356
DdNode * Cudd_bddExistAbstractLimit(DdManager *manager, DdNode *f, DdNode *cube, unsigned int limit)
Definition: cuddBddAbs.c:166
int size
Definition: cuddInt.h:345
DdNode * cuddCacheLookup2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
#define Cudd_IsConstant(node)
Definition: cudd.h:339
#define Cudd_Regular(node)
Definition: cudd.h:384
FILE * err
Definition: cuddInt.h:424
DdNode * Cudd_bddUnivAbstract(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:248
#define statLine(dd)
Definition: cuddInt.h:990
int reordered
Definition: cuddInt.h:392
unsigned int dead
Definition: cuddInt.h:355
static DdNode * one
Definition: cuddSat.c:105
#define Cudd_IsComplement(node)
Definition: cudd.h:412
unsigned int maxLive
Definition: cuddInt.h:357
int Cudd_bddVarIsDependent(DdManager *dd, DdNode *f, DdNode *var)
Definition: cuddBddAbs.c:325
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:308
unsigned int keys
Definition: cuddInt.h:353
#define DD_BDD_XOR_EXIST_ABSTRACT_TAG
Definition: cuddInt.h:175
DdNode * cuddBddBooleanDiffRecur(DdManager *manager, DdNode *f, DdNode *var)
Definition: cuddBddAbs.c:675
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define ddMin(x, y)
Definition: cuddInt.h:771
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:742
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995
#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
DdNode * cuddBddXorExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)
Definition: cuddBddAbs.c:503
DdNode * Cudd_bddExistAbstract(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:127
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
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
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1123
static int bddCheckPositiveCube(DdManager *manager, DdNode *cube)
Definition: cuddBddAbs.c:747
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:217
#define DD_ONE(dd)
Definition: cuddInt.h:864
unsigned int keysZ
Definition: cuddInt.h:354
int * perm
Definition: cuddInt.h:369
DdNode * Cudd_bddXorExistAbstract(DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)
Definition: cuddBddAbs.c:210
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1137
static char rcsid [] DD_UNUSED
Definition: cuddBddAbs.c:90