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

Go to the source code of this file.

Functions

static void bddVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *one)
 
static int bddVarToCanonical (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp)
 
static int bddVarToCanonicalSimple (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp)
 
DdNodeCudd_bddIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
 
DdNodeCudd_bddIteLimit (DdManager *dd, DdNode *f, DdNode *g, DdNode *h, unsigned int limit)
 
DdNodeCudd_bddIteConstant (DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
 
DdNodeCudd_bddIntersect (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodeCudd_bddAnd (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodeCudd_bddAndLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit)
 
DdNodeCudd_bddOr (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodeCudd_bddOrLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit)
 
DdNodeCudd_bddNand (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodeCudd_bddNor (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodeCudd_bddXor (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodeCudd_bddXnor (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodeCudd_bddXnorLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit)
 
int Cudd_bddLeq (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodecuddBddIteRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
 
DdNodecuddBddIntersectRecur (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodecuddBddAndRecur (DdManager *manager, DdNode *f, DdNode *g)
 
DdNodecuddBddXorRecur (DdManager *manager, DdNode *f, DdNode *g)
 

Variables

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

Function Documentation

◆ bddVarToCanonical()

static int bddVarToCanonical ( DdManager dd,
DdNode **  fp,
DdNode **  gp,
DdNode **  hp,
unsigned int *  topfp,
unsigned int *  topgp,
unsigned int *  tophp 
)
static

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

Synopsis [Picks unique member from equiv expressions.]

Description [Reduces 2 variable expressions to canonical form.]

SideEffects [None]

SeeAlso [bddVarToConst bddVarToCanonicalSimple]

Definition at line 1279 of file cuddBddIte.c.

1287 {
1288  register DdNode *F, *G, *H, *r, *f, *g, *h;
1289  register unsigned int topf, topg, toph;
1290  DdNode *one = dd->one;
1291  int comple, change;
1292 
1293  f = *fp;
1294  g = *gp;
1295  h = *hp;
1296  F = Cudd_Regular(f);
1297  G = Cudd_Regular(g);
1298  H = Cudd_Regular(h);
1299  topf = cuddI(dd,F->index);
1300  topg = cuddI(dd,G->index);
1301  toph = cuddI(dd,H->index);
1302 
1303  change = 0;
1304 
1305  if (G == one) { /* ITE(F,c,H) */
1306  if ((topf > toph) || (topf == toph && f > h)) {
1307  r = h;
1308  h = f;
1309  f = r; /* ITE(F,1,H) = ITE(H,1,F) */
1310  if (g != one) { /* g == zero */
1311  f = Cudd_Not(f); /* ITE(F,0,H) = ITE(!H,0,!F) */
1312  h = Cudd_Not(h);
1313  }
1314  change = 1;
1315  }
1316  } else if (H == one) { /* ITE(F,G,c) */
1317  if ((topf > topg) || (topf == topg && f > g)) {
1318  r = g;
1319  g = f;
1320  f = r; /* ITE(F,G,0) = ITE(G,F,0) */
1321  if (h == one) {
1322  f = Cudd_Not(f); /* ITE(F,G,1) = ITE(!G,!F,1) */
1323  g = Cudd_Not(g);
1324  }
1325  change = 1;
1326  }
1327  } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = ITE(G,F,!F) */
1328  if ((topf > topg) || (topf == topg && f > g)) {
1329  r = f;
1330  f = g;
1331  g = r;
1332  h = Cudd_Not(r);
1333  change = 1;
1334  }
1335  }
1336  /* adjust pointers so that the first 2 arguments to ITE are regular */
1337  if (Cudd_IsComplement(f) != 0) { /* ITE(!F,G,H) = ITE(F,H,G) */
1338  f = Cudd_Not(f);
1339  r = g;
1340  g = h;
1341  h = r;
1342  change = 1;
1343  }
1344  comple = 0;
1345  if (Cudd_IsComplement(g) != 0) { /* ITE(F,!G,H) = !ITE(F,G,!H) */
1346  g = Cudd_Not(g);
1347  h = Cudd_Not(h);
1348  change = 1;
1349  comple = 1;
1350  }
1351  if (change != 0) {
1352  *fp = f;
1353  *gp = g;
1354  *hp = h;
1355  }
1356  *topfp = cuddI(dd,f->index);
1357  *topgp = cuddI(dd,g->index);
1358  *tophp = cuddI(dd,Cudd_Regular(h)->index);
1359 
1360  return(comple);
1361 
1362 } /* end of bddVarToCanonical */
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
#define Cudd_Regular(node)
Definition: cudd.h:384
static DdNode * one
Definition: cuddSat.c:105
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define cuddI(dd, index)
Definition: cuddInt.h:659
DdHalfWord index
Definition: cudd.h:271
DdNode * one
Definition: cuddInt.h:329

◆ bddVarToCanonicalSimple()

static int bddVarToCanonicalSimple ( DdManager dd,
DdNode **  fp,
DdNode **  gp,
DdNode **  hp,
unsigned int *  topfp,
unsigned int *  topgp,
unsigned int *  tophp 
)
static

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

Synopsis [Picks unique member from equiv expressions.]

Description [Makes sure the first two pointers are regular. This mat require the complementation of the result, which is signaled by returning 1 instead of 0. This function is simpler than the general case because it assumes that no two arguments are the same or complementary, and no argument is constant.]

SideEffects [None]

SeeAlso [bddVarToConst bddVarToCanonical]

Definition at line 1381 of file cuddBddIte.c.

1389 {
1390  register DdNode *r, *f, *g, *h;
1391  int comple, change;
1392 
1393  f = *fp;
1394  g = *gp;
1395  h = *hp;
1396 
1397  change = 0;
1398 
1399  /* adjust pointers so that the first 2 arguments to ITE are regular */
1400  if (Cudd_IsComplement(f)) { /* ITE(!F,G,H) = ITE(F,H,G) */
1401  f = Cudd_Not(f);
1402  r = g;
1403  g = h;
1404  h = r;
1405  change = 1;
1406  }
1407  comple = 0;
1408  if (Cudd_IsComplement(g)) { /* ITE(F,!G,H) = !ITE(F,G,!H) */
1409  g = Cudd_Not(g);
1410  h = Cudd_Not(h);
1411  change = 1;
1412  comple = 1;
1413  }
1414  if (change) {
1415  *fp = f;
1416  *gp = g;
1417  *hp = h;
1418  }
1419 
1420  /* Here we can skip the use of cuddI, because the operands are known
1421  ** to be non-constant.
1422  */
1423  *topfp = dd->perm[f->index];
1424  *topgp = dd->perm[g->index];
1425  *tophp = dd->perm[Cudd_Regular(h)->index];
1426 
1427  return(comple);
1428 
1429 } /* end of bddVarToCanonicalSimple */
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
#define Cudd_Regular(node)
Definition: cudd.h:384
#define Cudd_IsComplement(node)
Definition: cudd.h:412
DdHalfWord index
Definition: cudd.h:271
int * perm
Definition: cuddInt.h:369

◆ bddVarToConst()

static void bddVarToConst ( DdNode f,
DdNode **  gp,
DdNode **  hp,
DdNode one 
)
static

AutomaticStart

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

Synopsis [Replaces variables with constants if possible.]

Description [This function performs part of the transformation to standard form by replacing variables with constants if possible.]

SideEffects [None]

SeeAlso [bddVarToCanonical bddVarToCanonicalSimple]

Definition at line 1244 of file cuddBddIte.c.

1249 {
1250  DdNode *g = *gp;
1251  DdNode *h = *hp;
1252 
1253  if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */
1254  *gp = one;
1255  } else if (f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */
1256  *gp = Cudd_Not(one);
1257  }
1258  if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */
1259  *hp = Cudd_Not(one);
1260  } else if (f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */
1261  *hp = one;
1262  }
1263 
1264 } /* end of bddVarToConst */
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
static DdNode * one
Definition: cuddSat.c:105

◆ Cudd_bddAnd()

DdNode* Cudd_bddAnd ( DdManager dd,
DdNode f,
DdNode g 
)

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

Synopsis [Computes the conjunction of two BDDs f and g.]

Description [Computes the conjunction of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]

SideEffects [None]

SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAndAbstract Cudd_bddIntersect Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXor Cudd_bddXnor]

Definition at line 350 of file cuddBddIte.c.

354 {
355  DdNode *res;
356 
357  do {
358  dd->reordered = 0;
359  res = cuddBddAndRecur(dd,f,g);
360  } while (dd->reordered == 1);
361  return(res);
362 
363 } /* end of Cudd_bddAnd */
Definition: cudd.h:270
int reordered
Definition: cuddInt.h:392
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995

◆ Cudd_bddAndLimit()

DdNode* Cudd_bddAndLimit ( DdManager dd,
DdNode f,
DdNode g,
unsigned int  limit 
)

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

Synopsis [Computes the conjunction of two BDDs f and g. Returns NULL if too many nodes are required.]

Description [Computes the conjunction of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up or more new nodes than limit are required.]

SideEffects [None]

SeeAlso [Cudd_bddAnd]

Definition at line 382 of file cuddBddIte.c.

387 {
388  DdNode *res;
389  unsigned int saveLimit = dd->maxLive;
390 
391  dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit;
392  do {
393  dd->reordered = 0;
394  res = cuddBddAndRecur(dd,f,g);
395  } while (dd->reordered == 1);
396  dd->maxLive = saveLimit;
397  return(res);
398 
399 } /* end of Cudd_bddAndLimit */
Definition: cudd.h:270
unsigned int deadZ
Definition: cuddInt.h:356
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
unsigned int keysZ
Definition: cuddInt.h:354
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995

◆ Cudd_bddIntersect()

DdNode* Cudd_bddIntersect ( DdManager dd,
DdNode f,
DdNode g 
)

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

Synopsis [Returns a function included in the intersection of f and g.]

Description [Computes a function included in the intersection of f and g. (That is, a witness that the intersection is not empty.) Cudd_bddIntersect tries to build as few new nodes as possible. If the only result of interest is whether f and g intersect, Cudd_bddLeq should be used instead.]

SideEffects [None]

SeeAlso [Cudd_bddLeq Cudd_bddIteConstant]

Definition at line 318 of file cuddBddIte.c.

322 {
323  DdNode *res;
324 
325  do {
326  dd->reordered = 0;
327  res = cuddBddIntersectRecur(dd,f,g);
328  } while (dd->reordered == 1);
329 
330  return(res);
331 
332 } /* end of Cudd_bddIntersect */
Definition: cudd.h:270
int reordered
Definition: cuddInt.h:392
DdNode * cuddBddIntersectRecur(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:880

◆ Cudd_bddIte()

DdNode* Cudd_bddIte ( DdManager dd,
DdNode f,
DdNode g,
DdNode h 
)

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

Synopsis [Implements ITE(f,g,h).]

Description [Implements ITE(f,g,h). Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]

SideEffects [None]

SeeAlso [Cudd_addIte Cudd_bddIteConstant Cudd_bddIntersect]

Definition at line 142 of file cuddBddIte.c.

147 {
148  DdNode *res;
149 
150  do {
151  dd->reordered = 0;
152  res = cuddBddIteRecur(dd,f,g,h);
153  } while (dd->reordered == 1);
154  return(res);
155 
156 } /* end of Cudd_bddIte */
Definition: cudd.h:270
int reordered
Definition: cuddInt.h:392
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:742

◆ Cudd_bddIteConstant()

DdNode* Cudd_bddIteConstant ( DdManager dd,
DdNode f,
DdNode g,
DdNode h 
)

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

Synopsis [Implements ITEconstant(f,g,h).]

Description [Implements ITEconstant(f,g,h). Returns a pointer to the resulting BDD (which may or may not be constant) or DD_NON_CONSTANT. No new nodes are created.]

SideEffects [None]

SeeAlso [Cudd_bddIte Cudd_bddIntersect Cudd_bddLeq Cudd_addIteConstant]

Definition at line 210 of file cuddBddIte.c.

215 {
216  DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e;
217  DdNode *one = DD_ONE(dd);
218  DdNode *zero = Cudd_Not(one);
219  int comple;
220  unsigned int topf, topg, toph, v;
221 
222  statLine(dd);
223  /* Trivial cases. */
224  if (f == one) /* ITE(1,G,H) => G */
225  return(g);
226 
227  if (f == zero) /* ITE(0,G,H) => H */
228  return(h);
229 
230  /* f now not a constant. */
231  bddVarToConst(f, &g, &h, one); /* possibly convert g or h */
232  /* to constants */
233 
234  if (g == h) /* ITE(F,G,G) => G */
235  return(g);
236 
237  if (Cudd_IsConstant(g) && Cudd_IsConstant(h))
238  return(DD_NON_CONSTANT); /* ITE(F,1,0) or ITE(F,0,1) */
239  /* => DD_NON_CONSTANT */
240 
241  if (g == Cudd_Not(h))
242  return(DD_NON_CONSTANT); /* ITE(F,G,G') => DD_NON_CONSTANT */
243  /* if F != G and F != G' */
244 
245  comple = bddVarToCanonical(dd, &f, &g, &h, &topf, &topg, &toph);
246 
247  /* Cache lookup. */
249  if (r != NULL) {
250  return(Cudd_NotCond(r,comple && r != DD_NON_CONSTANT));
251  }
252 
253  v = ddMin(topg, toph);
254 
255  /* ITE(F,G,H) = (v,G,H) (non constant) if F = (v,1,0), v < top(G,H). */
256  if (topf < v && cuddT(f) == one && cuddE(f) == zero) {
257  return(DD_NON_CONSTANT);
258  }
259 
260  /* Compute cofactors. */
261  if (topf <= v) {
262  v = ddMin(topf, v); /* v = top_var(F,G,H) */
263  Fv = cuddT(f); Fnv = cuddE(f);
264  } else {
265  Fv = Fnv = f;
266  }
267 
268  if (topg == v) {
269  Gv = cuddT(g); Gnv = cuddE(g);
270  } else {
271  Gv = Gnv = g;
272  }
273 
274  if (toph == v) {
275  H = Cudd_Regular(h);
276  Hv = cuddT(H); Hnv = cuddE(H);
277  if (Cudd_IsComplement(h)) {
278  Hv = Cudd_Not(Hv);
279  Hnv = Cudd_Not(Hnv);
280  }
281  } else {
282  Hv = Hnv = h;
283  }
284 
285  /* Recursion. */
286  t = Cudd_bddIteConstant(dd, Fv, Gv, Hv);
287  if (t == DD_NON_CONSTANT || !Cudd_IsConstant(t)) {
289  return(DD_NON_CONSTANT);
290  }
291  e = Cudd_bddIteConstant(dd, Fnv, Gnv, Hnv);
292  if (e == DD_NON_CONSTANT || !Cudd_IsConstant(e) || t != e) {
294  return(DD_NON_CONSTANT);
295  }
296  cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, t);
297  return(Cudd_NotCond(t,comple));
298 
299 } /* end of Cudd_bddIteConstant */
static int bddVarToCanonical(DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp)
Definition: cuddBddIte.c:1279
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
#define DD_BDD_ITE_CONSTANT_TAG
Definition: cuddInt.h:187
#define Cudd_IsConstant(node)
Definition: cudd.h:339
#define Cudd_Regular(node)
Definition: cudd.h:384
DdNode * Cudd_bddIteConstant(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:210
#define statLine(dd)
Definition: cuddInt.h:990
static DdNode * one
Definition: cuddSat.c:105
static void bddVarToConst(DdNode *f, DdNode **gp, DdNode **hp, DdNode *one)
Definition: cuddBddIte.c:1244
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
static DdNode * zero
Definition: cuddSat.c:105
DdNode * cuddConstantLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:690
#define cuddE(node)
Definition: cuddInt.h:625
#define Cudd_NotCond(node, c)
Definition: cudd.h:370
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
#define DD_NON_CONSTANT
Definition: cuddInt.h:124

◆ Cudd_bddIteLimit()

DdNode* Cudd_bddIteLimit ( DdManager dd,
DdNode f,
DdNode g,
DdNode h,
unsigned int  limit 
)

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

Synopsis [Implements ITE(f,g,h). Returns NULL if too many nodes are required.]

Description [Implements ITE(f,g,h). Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up or more new nodes than limit are required.]

SideEffects [None]

SeeAlso [Cudd_bddIte]

Definition at line 175 of file cuddBddIte.c.

181 {
182  DdNode *res;
183  unsigned int saveLimit = dd->maxLive;
184 
185  dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit;
186  do {
187  dd->reordered = 0;
188  res = cuddBddIteRecur(dd,f,g,h);
189  } while (dd->reordered == 1);
190  dd->maxLive = saveLimit;
191  return(res);
192 
193 } /* end of Cudd_bddIteLimit */
Definition: cudd.h:270
unsigned int deadZ
Definition: cuddInt.h:356
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
unsigned int keysZ
Definition: cuddInt.h:354
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:742

◆ Cudd_bddLeq()

int Cudd_bddLeq ( DdManager dd,
DdNode f,
DdNode g 
)

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

Synopsis [Determines whether f is less than or equal to g.]

Description [Returns 1 if f is less than or equal to g; 0 otherwise. No new nodes are created.]

SideEffects [None]

SeeAlso [Cudd_bddIteConstant Cudd_addEvalConst]

Definition at line 645 of file cuddBddIte.c.

649 {
650  DdNode *one, *zero, *tmp, *F, *fv, *fvn, *gv, *gvn;
651  unsigned int topf, topg, res;
652 
653  statLine(dd);
654  /* Terminal cases and normalization. */
655  if (f == g) return(1);
656 
657  if (Cudd_IsComplement(g)) {
658  /* Special case: if f is regular and g is complemented,
659  ** f(1,...,1) = 1 > 0 = g(1,...,1).
660  */
661  if (!Cudd_IsComplement(f)) return(0);
662  /* Both are complemented: Swap and complement because
663  ** f <= g <=> g' <= f' and we want the second argument to be regular.
664  */
665  tmp = g;
666  g = Cudd_Not(f);
667  f = Cudd_Not(tmp);
668  } else if (Cudd_IsComplement(f) && g < f) {
669  tmp = g;
670  g = Cudd_Not(f);
671  f = Cudd_Not(tmp);
672  }
673 
674  /* Now g is regular and, if f is not regular, f < g. */
675  one = DD_ONE(dd);
676  if (g == one) return(1); /* no need to test against zero */
677  if (f == one) return(0); /* since at this point g != one */
678  if (Cudd_Not(f) == g) return(0); /* because neither is constant */
679  zero = Cudd_Not(one);
680  if (f == zero) return(1);
681 
682  /* Here neither f nor g is constant. */
683 
684  /* Check cache. */
685  tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_bddLeq,f,g);
686  if (tmp != NULL) {
687  return(tmp == one);
688  }
689 
690  /* Compute cofactors. */
691  F = Cudd_Regular(f);
692  topf = dd->perm[F->index];
693  topg = dd->perm[g->index];
694  if (topf <= topg) {
695  fv = cuddT(F); fvn = cuddE(F);
696  if (f != F) {
697  fv = Cudd_Not(fv);
698  fvn = Cudd_Not(fvn);
699  }
700  } else {
701  fv = fvn = f;
702  }
703  if (topg <= topf) {
704  gv = cuddT(g); gvn = cuddE(g);
705  } else {
706  gv = gvn = g;
707  }
708 
709  /* Recursive calls. Since we want to maximize the probability of
710  ** the special case f(1,...,1) > g(1,...,1), we consider the negative
711  ** cofactors first. Indeed, the complementation parity of the positive
712  ** cofactors is the same as the one of the parent functions.
713  */
714  res = Cudd_bddLeq(dd,fvn,gvn) && Cudd_bddLeq(dd,fv,gv);
715 
716  /* Store result in cache and return. */
717  cuddCacheInsert2(dd,(DD_CTFP)Cudd_bddLeq,f,g,(res ? one : zero));
718  return(res);
719 
720 } /* end of Cudd_bddLeq */
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
#define Cudd_IsComplement(node)
Definition: cudd.h:412
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 DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369

◆ Cudd_bddNand()

DdNode* Cudd_bddNand ( DdManager dd,
DdNode f,
DdNode g 
)

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

Synopsis [Computes the NAND of two BDDs f and g.]

Description [Computes the NAND of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]

SideEffects [None]

SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNor Cudd_bddXor Cudd_bddXnor]

Definition at line 486 of file cuddBddIte.c.

490 {
491  DdNode *res;
492 
493  do {
494  dd->reordered = 0;
495  res = cuddBddAndRecur(dd,f,g);
496  } while (dd->reordered == 1);
497  res = Cudd_NotCond(res,res != NULL);
498  return(res);
499 
500 } /* end of Cudd_bddNand */
Definition: cudd.h:270
int reordered
Definition: cuddInt.h:392
#define Cudd_NotCond(node, c)
Definition: cudd.h:370
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995

◆ Cudd_bddNor()

DdNode* Cudd_bddNor ( DdManager dd,
DdNode f,
DdNode g 
)

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

Synopsis [Computes the NOR of two BDDs f and g.]

Description [Computes the NOR of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]

SideEffects [None]

SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNand Cudd_bddXor Cudd_bddXnor]

Definition at line 518 of file cuddBddIte.c.

522 {
523  DdNode *res;
524 
525  do {
526  dd->reordered = 0;
527  res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g));
528  } while (dd->reordered == 1);
529  return(res);
530 
531 } /* end of Cudd_bddNor */
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
int reordered
Definition: cuddInt.h:392
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995

◆ Cudd_bddOr()

DdNode* Cudd_bddOr ( DdManager dd,
DdNode f,
DdNode g 
)

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

Synopsis [Computes the disjunction of two BDDs f and g.]

Description [Computes the disjunction of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]

SideEffects [None]

SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddNand Cudd_bddNor Cudd_bddXor Cudd_bddXnor]

Definition at line 417 of file cuddBddIte.c.

421 {
422  DdNode *res;
423 
424  do {
425  dd->reordered = 0;
426  res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g));
427  } while (dd->reordered == 1);
428  res = Cudd_NotCond(res,res != NULL);
429  return(res);
430 
431 } /* end of Cudd_bddOr */
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
int reordered
Definition: cuddInt.h:392
#define Cudd_NotCond(node, c)
Definition: cudd.h:370
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995

◆ Cudd_bddOrLimit()

DdNode* Cudd_bddOrLimit ( DdManager dd,
DdNode f,
DdNode g,
unsigned int  limit 
)

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

Synopsis [Computes the disjunction of two BDDs f and g. Returns NULL if too many nodes are required.]

Description [Computes the disjunction of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up or more new nodes than limit are required.]

SideEffects [None]

SeeAlso [Cudd_bddOr]

Definition at line 450 of file cuddBddIte.c.

455 {
456  DdNode *res;
457  unsigned int saveLimit = dd->maxLive;
458 
459  dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit;
460  do {
461  dd->reordered = 0;
462  res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g));
463  } while (dd->reordered == 1);
464  dd->maxLive = saveLimit;
465  res = Cudd_NotCond(res,res != NULL);
466  return(res);
467 
468 } /* end of Cudd_bddOrLimit */
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
unsigned int deadZ
Definition: cuddInt.h:356
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
#define Cudd_NotCond(node, c)
Definition: cudd.h:370
unsigned int keysZ
Definition: cuddInt.h:354
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995

◆ Cudd_bddXnor()

DdNode* Cudd_bddXnor ( DdManager dd,
DdNode f,
DdNode g 
)

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

Synopsis [Computes the exclusive NOR of two BDDs f and g.]

Description [Computes the exclusive NOR of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]

SideEffects [None]

SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXor]

Definition at line 580 of file cuddBddIte.c.

584 {
585  DdNode *res;
586 
587  do {
588  dd->reordered = 0;
589  res = cuddBddXorRecur(dd,f,Cudd_Not(g));
590  } while (dd->reordered == 1);
591  return(res);
592 
593 } /* end of Cudd_bddXnor */
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
int reordered
Definition: cuddInt.h:392
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1123

◆ Cudd_bddXnorLimit()

DdNode* Cudd_bddXnorLimit ( DdManager dd,
DdNode f,
DdNode g,
unsigned int  limit 
)

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

Synopsis [Computes the exclusive NOR of two BDDs f and g. Returns NULL if too many nodes are required.]

Description [Computes the exclusive NOR of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up or more new nodes than limit are required.]

SideEffects [None]

SeeAlso [Cudd_bddXnor]

Definition at line 612 of file cuddBddIte.c.

617 {
618  DdNode *res;
619  unsigned int saveLimit = dd->maxLive;
620 
621  dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit;
622  do {
623  dd->reordered = 0;
624  res = cuddBddXorRecur(dd,f,Cudd_Not(g));
625  } while (dd->reordered == 1);
626  dd->maxLive = saveLimit;
627  return(res);
628 
629 } /* end of Cudd_bddXnorLimit */
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
unsigned int deadZ
Definition: cuddInt.h:356
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
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1123
unsigned int keysZ
Definition: cuddInt.h:354

◆ Cudd_bddXor()

DdNode* Cudd_bddXor ( DdManager dd,
DdNode f,
DdNode g 
)

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

Synopsis [Computes the exclusive OR of two BDDs f and g.]

Description [Computes the exclusive OR of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]

SideEffects [None]

SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXnor]

Definition at line 549 of file cuddBddIte.c.

553 {
554  DdNode *res;
555 
556  do {
557  dd->reordered = 0;
558  res = cuddBddXorRecur(dd,f,g);
559  } while (dd->reordered == 1);
560  return(res);
561 
562 } /* end of Cudd_bddXor */
Definition: cudd.h:270
int reordered
Definition: cuddInt.h:392
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1123

◆ cuddBddAndRecur()

DdNode* cuddBddAndRecur ( DdManager manager,
DdNode f,
DdNode g 
)

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

Synopsis [Implements the recursive step of Cudd_bddAnd.]

Description [Implements the recursive step of Cudd_bddAnd by taking the conjunction of two BDDs. Returns a pointer to the result is successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddAnd]

Definition at line 995 of file cuddBddIte.c.

999 {
1000  DdNode *F, *fv, *fnv, *G, *gv, *gnv;
1001  DdNode *one, *r, *t, *e;
1002  unsigned int topf, topg, index;
1003 
1004  statLine(manager);
1005  one = DD_ONE(manager);
1006 
1007  /* Terminal cases. */
1008  F = Cudd_Regular(f);
1009  G = Cudd_Regular(g);
1010  if (F == G) {
1011  if (f == g) return(f);
1012  else return(Cudd_Not(one));
1013  }
1014  if (F == one) {
1015  if (f == one) return(g);
1016  else return(f);
1017  }
1018  if (G == one) {
1019  if (g == one) return(f);
1020  else return(g);
1021  }
1022 
1023  /* At this point f and g are not constant. */
1024  if (f > g) { /* Try to increase cache efficiency. */
1025  DdNode *tmp = f;
1026  f = g;
1027  g = tmp;
1028  F = Cudd_Regular(f);
1029  G = Cudd_Regular(g);
1030  }
1031 
1032  /* Check cache. */
1033  if (F->ref != 1 || G->ref != 1) {
1034  r = cuddCacheLookup2(manager, Cudd_bddAnd, f, g);
1035  if (r != NULL) return(r);
1036  }
1037 
1038  /* Here we can skip the use of cuddI, because the operands are known
1039  ** to be non-constant.
1040  */
1041  topf = manager->perm[F->index];
1042  topg = manager->perm[G->index];
1043 
1044  /* Compute cofactors. */
1045  if (topf <= topg) {
1046  index = F->index;
1047  fv = cuddT(F);
1048  fnv = cuddE(F);
1049  if (Cudd_IsComplement(f)) {
1050  fv = Cudd_Not(fv);
1051  fnv = Cudd_Not(fnv);
1052  }
1053  } else {
1054  index = G->index;
1055  fv = fnv = f;
1056  }
1057 
1058  if (topg <= topf) {
1059  gv = cuddT(G);
1060  gnv = cuddE(G);
1061  if (Cudd_IsComplement(g)) {
1062  gv = Cudd_Not(gv);
1063  gnv = Cudd_Not(gnv);
1064  }
1065  } else {
1066  gv = gnv = g;
1067  }
1068 
1069  t = cuddBddAndRecur(manager, fv, gv);
1070  if (t == NULL) return(NULL);
1071  cuddRef(t);
1072 
1073  e = cuddBddAndRecur(manager, fnv, gnv);
1074  if (e == NULL) {
1075  Cudd_IterDerefBdd(manager, t);
1076  return(NULL);
1077  }
1078  cuddRef(e);
1079 
1080  if (t == e) {
1081  r = t;
1082  } else {
1083  if (Cudd_IsComplement(t)) {
1084  r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e));
1085  if (r == NULL) {
1086  Cudd_IterDerefBdd(manager, t);
1087  Cudd_IterDerefBdd(manager, e);
1088  return(NULL);
1089  }
1090  r = Cudd_Not(r);
1091  } else {
1092  r = cuddUniqueInter(manager,(int)index,t,e);
1093  if (r == NULL) {
1094  Cudd_IterDerefBdd(manager, t);
1095  Cudd_IterDerefBdd(manager, e);
1096  return(NULL);
1097  }
1098  }
1099  }
1100  cuddDeref(e);
1101  cuddDeref(t);
1102  if (F->ref != 1 || G->ref != 1)
1103  cuddCacheInsert2(manager, Cudd_bddAnd, f, g, r);
1104  return(r);
1105 
1106 } /* end of cuddBddAndRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:213
DdHalfWord ref
Definition: cudd.h:272
#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
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define cuddT(node)
Definition: cuddInt.h:609
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
#define cuddE(node)
Definition: cuddInt.h:625
DdNode * Cudd_bddAnd(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:350
#define DD_ONE(dd)
Definition: cuddInt.h:864
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995
int * perm
Definition: cuddInt.h:369
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1137

◆ cuddBddIntersectRecur()

DdNode* cuddBddIntersectRecur ( DdManager dd,
DdNode f,
DdNode g 
)

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

Synopsis [Implements the recursive step of Cudd_bddIntersect.]

Description []

SideEffects [None]

SeeAlso [Cudd_bddIntersect]

Definition at line 880 of file cuddBddIte.c.

884 {
885  DdNode *res;
886  DdNode *F, *G, *t, *e;
887  DdNode *fv, *fnv, *gv, *gnv;
888  DdNode *one, *zero;
889  unsigned int index, topf, topg;
890 
891  statLine(dd);
892  one = DD_ONE(dd);
893  zero = Cudd_Not(one);
894 
895  /* Terminal cases. */
896  if (f == zero || g == zero || f == Cudd_Not(g)) return(zero);
897  if (f == g || g == one) return(f);
898  if (f == one) return(g);
899 
900  /* At this point f and g are not constant. */
901  if (f > g) { DdNode *tmp = f; f = g; g = tmp; }
902  res = cuddCacheLookup2(dd,Cudd_bddIntersect,f,g);
903  if (res != NULL) return(res);
904 
905  /* Find splitting variable. Here we can skip the use of cuddI,
906  ** because the operands are known to be non-constant.
907  */
908  F = Cudd_Regular(f);
909  topf = dd->perm[F->index];
910  G = Cudd_Regular(g);
911  topg = dd->perm[G->index];
912 
913  /* Compute cofactors. */
914  if (topf <= topg) {
915  index = F->index;
916  fv = cuddT(F);
917  fnv = cuddE(F);
918  if (Cudd_IsComplement(f)) {
919  fv = Cudd_Not(fv);
920  fnv = Cudd_Not(fnv);
921  }
922  } else {
923  index = G->index;
924  fv = fnv = f;
925  }
926 
927  if (topg <= topf) {
928  gv = cuddT(G);
929  gnv = cuddE(G);
930  if (Cudd_IsComplement(g)) {
931  gv = Cudd_Not(gv);
932  gnv = Cudd_Not(gnv);
933  }
934  } else {
935  gv = gnv = g;
936  }
937 
938  /* Compute partial results. */
939  t = cuddBddIntersectRecur(dd,fv,gv);
940  if (t == NULL) return(NULL);
941  cuddRef(t);
942  if (t != zero) {
943  e = zero;
944  } else {
945  e = cuddBddIntersectRecur(dd,fnv,gnv);
946  if (e == NULL) {
947  Cudd_IterDerefBdd(dd, t);
948  return(NULL);
949  }
950  }
951  cuddRef(e);
952 
953  if (t == e) { /* both equal zero */
954  res = t;
955  } else if (Cudd_IsComplement(t)) {
956  res = cuddUniqueInter(dd,(int)index,Cudd_Not(t),Cudd_Not(e));
957  if (res == NULL) {
958  Cudd_IterDerefBdd(dd, t);
959  Cudd_IterDerefBdd(dd, e);
960  return(NULL);
961  }
962  res = Cudd_Not(res);
963  } else {
964  res = cuddUniqueInter(dd,(int)index,t,e);
965  if (res == NULL) {
966  Cudd_IterDerefBdd(dd, t);
967  Cudd_IterDerefBdd(dd, e);
968  return(NULL);
969  }
970  }
971  cuddDeref(e);
972  cuddDeref(t);
973 
975 
976  return(res);
977 
978 } /* end of cuddBddIntersectRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:213
DdNode * Cudd_bddIntersect(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:318
#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
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define cuddT(node)
Definition: cuddInt.h:609
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
DdNode * cuddBddIntersectRecur(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:880
static DdNode * zero
Definition: cuddSat.c:105
#define cuddE(node)
Definition: cuddInt.h:625
#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

◆ cuddBddIteRecur()

DdNode* cuddBddIteRecur ( DdManager dd,
DdNode f,
DdNode g,
DdNode h 
)

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

Synopsis [Implements the recursive step of Cudd_bddIte.]

Description [Implements the recursive step of Cudd_bddIte. Returns a pointer to the resulting BDD. NULL if the intermediate result blows up or if reordering occurs.]

SideEffects [None]

SeeAlso []

Definition at line 742 of file cuddBddIte.c.

747 {
748  DdNode *one, *zero, *res;
749  DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e;
750  unsigned int topf, topg, toph, v;
751  int index;
752  int comple;
753 
754  statLine(dd);
755  /* Terminal cases. */
756 
757  /* One variable cases. */
758  if (f == (one = DD_ONE(dd))) /* ITE(1,G,H) = G */
759  return(g);
760 
761  if (f == (zero = Cudd_Not(one))) /* ITE(0,G,H) = H */
762  return(h);
763 
764  /* From now on, f is known not to be a constant. */
765  if (g == one || f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */
766  if (h == zero) { /* ITE(F,1,0) = F */
767  return(f);
768  } else {
769  res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(h));
770  return(Cudd_NotCond(res,res != NULL));
771  }
772  } else if (g == zero || f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */
773  if (h == one) { /* ITE(F,0,1) = !F */
774  return(Cudd_Not(f));
775  } else {
776  res = cuddBddAndRecur(dd,Cudd_Not(f),h);
777  return(res);
778  }
779  }
780  if (h == zero || f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */
781  res = cuddBddAndRecur(dd,f,g);
782  return(res);
783  } else if (h == one || f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */
784  res = cuddBddAndRecur(dd,f,Cudd_Not(g));
785  return(Cudd_NotCond(res,res != NULL));
786  }
787 
788  /* Check remaining one variable case. */
789  if (g == h) { /* ITE(F,G,G) = G */
790  return(g);
791  } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = F <-> G */
792  res = cuddBddXorRecur(dd,f,h);
793  return(res);
794  }
795 
796  /* From here, there are no constants. */
797  comple = bddVarToCanonicalSimple(dd, &f, &g, &h, &topf, &topg, &toph);
798 
799  /* f & g are now regular pointers */
800 
801  v = ddMin(topg, toph);
802 
803  /* A shortcut: ITE(F,G,H) = (v,G,H) if F = (v,1,0), v < top(G,H). */
804  if (topf < v && cuddT(f) == one && cuddE(f) == zero) {
805  r = cuddUniqueInter(dd, (int) f->index, g, h);
806  return(Cudd_NotCond(r,comple && r != NULL));
807  }
808 
809  /* Check cache. */
810  r = cuddCacheLookup(dd, DD_BDD_ITE_TAG, f, g, h);
811  if (r != NULL) {
812  return(Cudd_NotCond(r,comple));
813  }
814 
815  /* Compute cofactors. */
816  if (topf <= v) {
817  v = ddMin(topf, v); /* v = top_var(F,G,H) */
818  index = f->index;
819  Fv = cuddT(f); Fnv = cuddE(f);
820  } else {
821  Fv = Fnv = f;
822  }
823  if (topg == v) {
824  index = g->index;
825  Gv = cuddT(g); Gnv = cuddE(g);
826  } else {
827  Gv = Gnv = g;
828  }
829  if (toph == v) {
830  H = Cudd_Regular(h);
831  index = H->index;
832  Hv = cuddT(H); Hnv = cuddE(H);
833  if (Cudd_IsComplement(h)) {
834  Hv = Cudd_Not(Hv);
835  Hnv = Cudd_Not(Hnv);
836  }
837  } else {
838  Hv = Hnv = h;
839  }
840 
841  /* Recursive step. */
842  t = cuddBddIteRecur(dd,Fv,Gv,Hv);
843  if (t == NULL) return(NULL);
844  cuddRef(t);
845 
846  e = cuddBddIteRecur(dd,Fnv,Gnv,Hnv);
847  if (e == NULL) {
848  Cudd_IterDerefBdd(dd,t);
849  return(NULL);
850  }
851  cuddRef(e);
852 
853  r = (t == e) ? t : cuddUniqueInter(dd,index,t,e);
854  if (r == NULL) {
855  Cudd_IterDerefBdd(dd,t);
856  Cudd_IterDerefBdd(dd,e);
857  return(NULL);
858  }
859  cuddDeref(t);
860  cuddDeref(e);
861 
862  cuddCacheInsert(dd, DD_BDD_ITE_TAG, f, g, h, r);
863  return(Cudd_NotCond(r,comple));
864 
865 } /* end of cuddBddIteRecur */
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
#define Cudd_Regular(node)
Definition: cudd.h:384
static int bddVarToCanonicalSimple(DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp)
Definition: cuddBddIte.c:1381
#define statLine(dd)
Definition: cuddInt.h:990
static DdNode * one
Definition: cuddSat.c:105
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define ddMin(x, y)
Definition: cuddInt.h:771
#define DD_BDD_ITE_TAG
Definition: cuddInt.h:176
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:347
DdHalfWord index
Definition: cudd.h:271
static DdNode * zero
Definition: cuddSat.c:105
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1123
#define cuddE(node)
Definition: cuddInt.h:625
#define Cudd_NotCond(node, c)
Definition: cudd.h:370
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
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1137
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:742

◆ cuddBddXorRecur()

DdNode* cuddBddXorRecur ( DdManager manager,
DdNode f,
DdNode g 
)

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

Synopsis [Implements the recursive step of Cudd_bddXor.]

Description [Implements the recursive step of Cudd_bddXor by taking the exclusive OR of two BDDs. Returns a pointer to the result is successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddXor]

Definition at line 1123 of file cuddBddIte.c.

1127 {
1128  DdNode *fv, *fnv, *G, *gv, *gnv;
1129  DdNode *one, *zero, *r, *t, *e;
1130  unsigned int topf, topg, index;
1131 
1132  statLine(manager);
1133  one = DD_ONE(manager);
1134  zero = Cudd_Not(one);
1135 
1136  /* Terminal cases. */
1137  if (f == g) return(zero);
1138  if (f == Cudd_Not(g)) return(one);
1139  if (f > g) { /* Try to increase cache efficiency and simplify tests. */
1140  DdNode *tmp = f;
1141  f = g;
1142  g = tmp;
1143  }
1144  if (g == zero) return(f);
1145  if (g == one) return(Cudd_Not(f));
1146  if (Cudd_IsComplement(f)) {
1147  f = Cudd_Not(f);
1148  g = Cudd_Not(g);
1149  }
1150  /* Now the first argument is regular. */
1151  if (f == one) return(Cudd_Not(g));
1152 
1153  /* At this point f and g are not constant. */
1154 
1155  /* Check cache. */
1156  r = cuddCacheLookup2(manager, Cudd_bddXor, f, g);
1157  if (r != NULL) return(r);
1158 
1159  /* Here we can skip the use of cuddI, because the operands are known
1160  ** to be non-constant.
1161  */
1162  topf = manager->perm[f->index];
1163  G = Cudd_Regular(g);
1164  topg = manager->perm[G->index];
1165 
1166  /* Compute cofactors. */
1167  if (topf <= topg) {
1168  index = f->index;
1169  fv = cuddT(f);
1170  fnv = cuddE(f);
1171  } else {
1172  index = G->index;
1173  fv = fnv = f;
1174  }
1175 
1176  if (topg <= topf) {
1177  gv = cuddT(G);
1178  gnv = cuddE(G);
1179  if (Cudd_IsComplement(g)) {
1180  gv = Cudd_Not(gv);
1181  gnv = Cudd_Not(gnv);
1182  }
1183  } else {
1184  gv = gnv = g;
1185  }
1186 
1187  t = cuddBddXorRecur(manager, fv, gv);
1188  if (t == NULL) return(NULL);
1189  cuddRef(t);
1190 
1191  e = cuddBddXorRecur(manager, fnv, gnv);
1192  if (e == NULL) {
1193  Cudd_IterDerefBdd(manager, t);
1194  return(NULL);
1195  }
1196  cuddRef(e);
1197 
1198  if (t == e) {
1199  r = t;
1200  } else {
1201  if (Cudd_IsComplement(t)) {
1202  r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e));
1203  if (r == NULL) {
1204  Cudd_IterDerefBdd(manager, t);
1205  Cudd_IterDerefBdd(manager, e);
1206  return(NULL);
1207  }
1208  r = Cudd_Not(r);
1209  } else {
1210  r = cuddUniqueInter(manager,(int)index,t,e);
1211  if (r == NULL) {
1212  Cudd_IterDerefBdd(manager, t);
1213  Cudd_IterDerefBdd(manager, e);
1214  return(NULL);
1215  }
1216  }
1217  }
1218  cuddDeref(e);
1219  cuddDeref(t);
1220  cuddCacheInsert2(manager, Cudd_bddXor, f, g, r);
1221  return(r);
1222 
1223 } /* end of cuddBddXorRecur */
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
static DdNode * one
Definition: cuddSat.c:105
#define Cudd_IsComplement(node)
Definition: cudd.h:412
DdNode * Cudd_bddXor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:549
#define cuddT(node)
Definition: cuddInt.h:609
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
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1123
#define cuddE(node)
Definition: cuddInt.h:625
#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: cuddBddIte.c,v 1.26 2012/02/05 01:07:18 fabio Exp $"
static

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

FileName [cuddBddIte.c]

PackageName [cudd]

Synopsis [BDD ITE function and satellites.]

Description [External procedures included in this module:

Internal procedures included in this module:

Static procedures included in this module:

]

SeeAlso []

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 102 of file cuddBddIte.c.