SVF
Functions | Variables
cuddBddAbs.c File Reference
#include "CUDD/util.h"
#include "CUDD/cuddInt.h"

Go to the source code of this file.

Functions

static int bddCheckPositiveCube (DdManager *manager, DdNode *cube)
 
DdNodeCudd_bddExistAbstract (DdManager *manager, DdNode *f, DdNode *cube)
 
DdNodeCudd_bddExistAbstractLimit (DdManager *manager, DdNode *f, DdNode *cube, unsigned int limit)
 
DdNodeCudd_bddXorExistAbstract (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)
 
DdNodeCudd_bddUnivAbstract (DdManager *manager, DdNode *f, DdNode *cube)
 
DdNodeCudd_bddBooleanDiff (DdManager *manager, DdNode *f, int x)
 
int Cudd_bddVarIsDependent (DdManager *dd, DdNode *f, DdNode *var)
 
DdNodecuddBddExistAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube)
 
DdNodecuddBddXorExistAbstractRecur (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)
 
DdNodecuddBddBooleanDiffRecur (DdManager *manager, DdNode *f, DdNode *var)
 

Variables

static char rcsid [] DD_UNUSED = "$Id: cuddBddAbs.c,v 1.28 2012/02/05 01:07:18 fabio Exp $"
 

Function Documentation

◆ bddCheckPositiveCube()

static int bddCheckPositiveCube ( DdManager manager,
DdNode cube 
)
static

AutomaticStart

Function********************************************************************

Synopsis [Checks whether cube is an BDD representing the product of positive literals.]

Description [Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 747 of file cuddBddAbs.c.

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 */
#define Cudd_Not(node)
Definition: cudd.h:354
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddE(node)
Definition: cuddInt.h:625
static int bddCheckPositiveCube(DdManager *manager, DdNode *cube)
Definition: cuddBddAbs.c:747
#define DD_ONE(dd)
Definition: cuddInt.h:864

◆ Cudd_bddBooleanDiff()

DdNode* Cudd_bddBooleanDiff ( DdManager manager,
DdNode f,
int  x 
)

Function********************************************************************

Synopsis [Computes the boolean difference of f with respect to x.]

Description [Computes the boolean difference of f with respect to the variable with index x. Returns the BDD of the boolean difference if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 287 of file cuddBddAbs.c.

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 */
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
int size
Definition: cuddInt.h:345
#define Cudd_Regular(node)
Definition: cudd.h:384
int reordered
Definition: cuddInt.h:392
DdNode * cuddBddBooleanDiffRecur(DdManager *manager, DdNode *f, DdNode *var)
Definition: cuddBddAbs.c:675
DdNode ** vars
Definition: cuddInt.h:373
#define DD_ONE(dd)
Definition: cuddInt.h:864

◆ Cudd_bddExistAbstract()

DdNode* Cudd_bddExistAbstract ( DdManager manager,
DdNode f,
DdNode cube 
)

AutomaticEnd Function********************************************************************

Synopsis [Existentially abstracts all the variables in cube from f.]

Description [Existentially abstracts all the variables in cube from f. Returns the abstracted BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddUnivAbstract Cudd_addExistAbstract]

Definition at line 127 of file cuddBddAbs.c.

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 */
DdNode * cuddBddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:393
Definition: cudd.h:270
FILE * err
Definition: cuddInt.h:424
int reordered
Definition: cuddInt.h:392
static int bddCheckPositiveCube(DdManager *manager, DdNode *cube)
Definition: cuddBddAbs.c:747
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ Cudd_bddExistAbstractLimit()

DdNode* Cudd_bddExistAbstractLimit ( DdManager manager,
DdNode f,
DdNode cube,
unsigned int  limit 
)

Function********************************************************************

Synopsis [Existentially abstracts all the variables in cube from f.]

Description [Existentially abstracts all the variables in cube from f. Returns the abstracted BDD if successful; NULL if the intermediate result blows up or more new nodes than limit are required.]

SideEffects [None]

SeeAlso [Cudd_bddExistAbstract]

Definition at line 166 of file cuddBddAbs.c.

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 */
DdNode * cuddBddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:393
Definition: cudd.h:270
unsigned int deadZ
Definition: cuddInt.h:356
FILE * err
Definition: cuddInt.h:424
int reordered
Definition: cuddInt.h:392
unsigned int dead
Definition: cuddInt.h:355
unsigned int maxLive
Definition: cuddInt.h:357
unsigned int keys
Definition: cuddInt.h:353
static int bddCheckPositiveCube(DdManager *manager, DdNode *cube)
Definition: cuddBddAbs.c:747
unsigned int keysZ
Definition: cuddInt.h:354
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ Cudd_bddUnivAbstract()

DdNode* Cudd_bddUnivAbstract ( DdManager manager,
DdNode f,
DdNode cube 
)

Function********************************************************************

Synopsis [Universally abstracts all the variables in cube from f.]

Description [Universally abstracts all the variables in cube from f. Returns the abstracted BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddExistAbstract Cudd_addUnivAbstract]

Definition at line 248 of file cuddBddAbs.c.

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 */
DdNode * cuddBddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:393
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
FILE * err
Definition: cuddInt.h:424
int reordered
Definition: cuddInt.h:392
static int bddCheckPositiveCube(DdManager *manager, DdNode *cube)
Definition: cuddBddAbs.c:747
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ Cudd_bddVarIsDependent()

int Cudd_bddVarIsDependent ( DdManager dd,
DdNode f,
DdNode var 
)

Function********************************************************************

Synopsis [Checks whether a variable is dependent on others in a function.]

Description [Checks whether a variable is dependent on others in a function. Returns 1 if the variable is dependent; 0 otherwise. No new nodes are created.]

SideEffects [None]

SeeAlso []

Definition at line 325 of file cuddBddAbs.c.

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 */
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
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
int Cudd_bddVarIsDependent(DdManager *dd, DdNode *f, DdNode *var)
Definition: cuddBddAbs.c:325
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:308
#define cuddT(node)
Definition: cuddInt.h:609
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:645
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
static DdNode * zero
Definition: cuddSat.c:105
#define cuddE(node)
Definition: cuddInt.h:625
#define Cudd_NotCond(node, c)
Definition: cudd.h:370
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369

◆ Cudd_bddXorExistAbstract()

DdNode* Cudd_bddXorExistAbstract ( DdManager manager,
DdNode f,
DdNode g,
DdNode cube 
)

Function********************************************************************

Synopsis [Takes the exclusive OR of two BDDs and simultaneously abstracts the variables in cube.]

Description [Takes the exclusive OR of two BDDs and simultaneously abstracts the variables in cube. The variables are existentially abstracted. Returns a pointer to the result is successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddUnivAbstract Cudd_bddExistAbstract Cudd_bddAndAbstract]

Definition at line 210 of file cuddBddAbs.c.

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 */
Definition: cudd.h:270
FILE * err
Definition: cuddInt.h:424
int reordered
Definition: cuddInt.h:392
DdNode * cuddBddXorExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)
Definition: cuddBddAbs.c:503
static int bddCheckPositiveCube(DdManager *manager, DdNode *cube)
Definition: cuddBddAbs.c:747
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddBddBooleanDiffRecur()

DdNode* cuddBddBooleanDiffRecur ( DdManager manager,
DdNode f,
DdNode var 
)

Function********************************************************************

Synopsis [Performs the recursive steps of Cudd_bddBoleanDiff.]

Description [Performs the recursive steps of Cudd_bddBoleanDiff. Returns the BDD obtained by XORing the cofactors of f with respect to var if successful; NULL otherwise. Exploits the fact that dF/dx = dF'/dx.]

SideEffects [None]

SeeAlso []

Definition at line 675 of file cuddBddAbs.c.

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 */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:213
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
DdNode * cuddCacheLookup2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
#define Cudd_Regular(node)
Definition: cudd.h:384
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddBddBooleanDiffRecur(DdManager *manager, DdNode *f, DdNode *var)
Definition: cuddBddAbs.c:675
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:742
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddI(dd, index)
Definition: cuddInt.h:659
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
#define cuddE(node)
Definition: cuddInt.h:625
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1123
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369

◆ cuddBddExistAbstractRecur()

DdNode* cuddBddExistAbstractRecur ( DdManager manager,
DdNode f,
DdNode cube 
)

Function********************************************************************

Synopsis [Performs the recursive steps of Cudd_bddExistAbstract.]

Description [Performs the recursive steps of Cudd_bddExistAbstract. Returns the BDD obtained by abstracting the variables of cube from f if successful; NULL otherwise. It is also used by Cudd_bddUnivAbstract.]

SideEffects [None]

SeeAlso [Cudd_bddExistAbstract Cudd_bddUnivAbstract]

Definition at line 393 of file cuddBddAbs.c.

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 */
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
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
DdNode * cuddCacheLookup2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
#define Cudd_Regular(node)
Definition: cudd.h:384
#define statLine(dd)
Definition: cuddInt.h:990
static DdNode * one
Definition: cuddSat.c:105
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
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
#define cuddE(node)
Definition: cuddInt.h:625
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369

◆ cuddBddXorExistAbstractRecur()

DdNode* cuddBddXorExistAbstractRecur ( DdManager manager,
DdNode f,
DdNode g,
DdNode cube 
)

Function********************************************************************

Synopsis [Takes the exclusive OR of two BDDs and simultaneously abstracts the variables in cube.]

Description [Takes the exclusive OR of two BDDs and simultaneously abstracts the variables in cube. The variables are existentially abstracted. Returns a pointer to the result is successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddAndAbstract]

Definition at line 503 of file cuddBddAbs.c.

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 */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:213
DdNode * cuddBddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:393
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
#define Cudd_Regular(node)
Definition: cudd.h:384
#define statLine(dd)
Definition: cuddInt.h:990
static DdNode * one
Definition: cuddSat.c:105
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define DD_BDD_XOR_EXIST_ABSTRACT_TAG
Definition: cuddInt.h:175
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995
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
DdHalfWord index
Definition: cudd.h:271
static DdNode * zero
Definition: cuddSat.c:105
#define cuddE(node)
Definition: cuddInt.h:625
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1123
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
int * perm
Definition: cuddInt.h:369
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1137

Variable Documentation

◆ DD_UNUSED

char rcsid [] DD_UNUSED = "$Id: cuddBddAbs.c,v 1.28 2012/02/05 01:07:18 fabio Exp $"
static

CFile***********************************************************************

FileName [cuddBddAbs.c]

PackageName [cudd]

Synopsis [Quantification functions for BDDs.]

Description [External procedures included in this module:

Internal procedures included in this module:

Static procedures included in this module:

]

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 90 of file cuddBddAbs.c.