abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddBddIte.c File Reference
#include "misc/util/util_hack.h"
#include "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_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_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)
 
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
ABC_NAMESPACE_IMPL_START char
rcsid[] 
DD_UNUSED = "$Id: cuddBddIte.c,v 1.24 2004/08/13 18:04:46 fabio Exp $"
 

Function Documentation

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

1181 {
1182  register DdNode *F, *G, *H, *r, *f, *g, *h;
1183  register unsigned int topf, topg, toph;
1184  DdNode *one = dd->one;
1185  int comple, change;
1186 
1187  f = *fp;
1188  g = *gp;
1189  h = *hp;
1190  F = Cudd_Regular(f);
1191  G = Cudd_Regular(g);
1192  H = Cudd_Regular(h);
1193  topf = cuddI(dd,F->index);
1194  topg = cuddI(dd,G->index);
1195  toph = cuddI(dd,H->index);
1196 
1197  change = 0;
1198 
1199  if (G == one) { /* ITE(F,c,H) */
1200  if ((topf > toph) || (topf == toph && cuddF2L(f) > cuddF2L(h))) {
1201  r = h;
1202  h = f;
1203  f = r; /* ITE(F,1,H) = ITE(H,1,F) */
1204  if (g != one) { /* g == zero */
1205  f = Cudd_Not(f); /* ITE(F,0,H) = ITE(!H,0,!F) */
1206  h = Cudd_Not(h);
1207  }
1208  change = 1;
1209  }
1210  } else if (H == one) { /* ITE(F,G,c) */
1211  if ((topf > topg) || (topf == topg && cuddF2L(f) > cuddF2L(g))) {
1212  r = g;
1213  g = f;
1214  f = r; /* ITE(F,G,0) = ITE(G,F,0) */
1215  if (h == one) {
1216  f = Cudd_Not(f); /* ITE(F,G,1) = ITE(!G,!F,1) */
1217  g = Cudd_Not(g);
1218  }
1219  change = 1;
1220  }
1221  } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = ITE(G,F,!F) */
1222  if ((topf > topg) || (topf == topg && cuddF2L(f) > cuddF2L(g))) {
1223  r = f;
1224  f = g;
1225  g = r;
1226  h = Cudd_Not(r);
1227  change = 1;
1228  }
1229  }
1230  /* adjust pointers so that the first 2 arguments to ITE are regular */
1231  if (Cudd_IsComplement(f) != 0) { /* ITE(!F,G,H) = ITE(F,H,G) */
1232  f = Cudd_Not(f);
1233  r = g;
1234  g = h;
1235  h = r;
1236  change = 1;
1237  }
1238  comple = 0;
1239  if (Cudd_IsComplement(g) != 0) { /* ITE(F,!G,H) = !ITE(F,G,!H) */
1240  g = Cudd_Not(g);
1241  h = Cudd_Not(h);
1242  change = 1;
1243  comple = 1;
1244  }
1245  if (change != 0) {
1246  *fp = f;
1247  *gp = g;
1248  *hp = h;
1249  }
1250  *topfp = cuddI(dd,f->index);
1251  *topgp = cuddI(dd,g->index);
1252  *tophp = cuddI(dd,Cudd_Regular(h)->index);
1253 
1254  return(comple);
1255 
1256 } /* end of bddVarToCanonical */
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
#define Cudd_Regular(node)
Definition: cudd.h:397
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
#define cuddF2L(f)
Definition: cuddInt.h:718
#define cuddI(dd, index)
Definition: cuddInt.h:686
DdHalfWord index
Definition: cudd.h:279
DdNode * one
Definition: cuddInt.h:345
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 1275 of file cuddBddIte.c.

1283 {
1284  register DdNode *r, *f, *g, *h;
1285  int comple, change;
1286 
1287  f = *fp;
1288  g = *gp;
1289  h = *hp;
1290 
1291  change = 0;
1292 
1293  /* adjust pointers so that the first 2 arguments to ITE are regular */
1294  if (Cudd_IsComplement(f)) { /* ITE(!F,G,H) = ITE(F,H,G) */
1295  f = Cudd_Not(f);
1296  r = g;
1297  g = h;
1298  h = r;
1299  change = 1;
1300  }
1301  comple = 0;
1302  if (Cudd_IsComplement(g)) { /* ITE(F,!G,H) = !ITE(F,G,!H) */
1303  g = Cudd_Not(g);
1304  h = Cudd_Not(h);
1305  change = 1;
1306  comple = 1;
1307  }
1308  if (change) {
1309  *fp = f;
1310  *gp = g;
1311  *hp = h;
1312  }
1313 
1314  /* Here we can skip the use of cuddI, because the operands are known
1315  ** to be non-constant.
1316  */
1317  *topfp = dd->perm[f->index];
1318  *topgp = dd->perm[g->index];
1319  *tophp = dd->perm[Cudd_Regular(h)->index];
1320 
1321  return(comple);
1322 
1323 } /* end of bddVarToCanonicalSimple */
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
#define Cudd_Regular(node)
Definition: cudd.h:397
#define Cudd_IsComplement(node)
Definition: cudd.h:425
DdHalfWord index
Definition: cudd.h:279
int * perm
Definition: cuddInt.h:386
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 1138 of file cuddBddIte.c.

1143 {
1144  DdNode *g = *gp;
1145  DdNode *h = *hp;
1146 
1147  if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */
1148  *gp = one;
1149  } else if (f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */
1150  *gp = Cudd_Not(one);
1151  }
1152  if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */
1153  *hp = Cudd_Not(one);
1154  } else if (f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */
1155  *hp = one;
1156  }
1157 
1158 } /* end of bddVarToConst */
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
static DdNode * one
Definition: cuddDecomp.c:112
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 314 of file cuddBddIte.c.

318 {
319  DdNode *res;
320 
321  do {
322  dd->reordered = 0;
323  res = cuddBddAndRecur(dd,f,g);
324  } while (dd->reordered == 1);
325  return(res);
326 
327 } /* end of Cudd_bddAnd */
Definition: cudd.h:278
int reordered
Definition: cuddInt.h:409
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
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 346 of file cuddBddIte.c.

351 {
352  DdNode *res;
353  unsigned int saveLimit = dd->maxLive;
354 
355  dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit;
356  do {
357  dd->reordered = 0;
358  res = cuddBddAndRecur(dd,f,g);
359  } while (dd->reordered == 1);
360  dd->maxLive = saveLimit;
361  return(res);
362 
363 } /* end of Cudd_bddAndLimit */
Definition: cudd.h:278
unsigned int deadZ
Definition: cuddInt.h:372
int reordered
Definition: cuddInt.h:409
unsigned int dead
Definition: cuddInt.h:371
unsigned int maxLive
Definition: cuddInt.h:373
unsigned int keys
Definition: cuddInt.h:369
unsigned int keysZ
Definition: cuddInt.h:370
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
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 282 of file cuddBddIte.c.

286 {
287  DdNode *res;
288 
289  do {
290  dd->reordered = 0;
291  res = cuddBddIntersectRecur(dd,f,g);
292  } while (dd->reordered == 1);
293 
294  return(res);
295 
296 } /* end of Cudd_bddIntersect */
Definition: cudd.h:278
int reordered
Definition: cuddInt.h:409
DdNode * cuddBddIntersectRecur(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:771
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 143 of file cuddBddIte.c.

148 {
149  DdNode *res;
150 
151  do {
152  dd->reordered = 0;
153  res = cuddBddIteRecur(dd,f,g,h);
154  } while (dd->reordered == 1);
155  return(res);
156 
157 } /* end of Cudd_bddIte */
Definition: cudd.h:278
int reordered
Definition: cuddInt.h:409
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:633
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 174 of file cuddBddIte.c.

179 {
180  DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e;
181  DdNode *one = DD_ONE(dd);
182  DdNode *zero = Cudd_Not(one);
183  int comple;
184  unsigned int topf, topg, toph, v;
185 
186  statLine(dd);
187  /* Trivial cases. */
188  if (f == one) /* ITE(1,G,H) => G */
189  return(g);
190 
191  if (f == zero) /* ITE(0,G,H) => H */
192  return(h);
193 
194  /* f now not a constant. */
195  bddVarToConst(f, &g, &h, one); /* possibly convert g or h */
196  /* to constants */
197 
198  if (g == h) /* ITE(F,G,G) => G */
199  return(g);
200 
201  if (Cudd_IsConstant(g) && Cudd_IsConstant(h))
202  return(DD_NON_CONSTANT); /* ITE(F,1,0) or ITE(F,0,1) */
203  /* => DD_NON_CONSTANT */
204 
205  if (g == Cudd_Not(h))
206  return(DD_NON_CONSTANT); /* ITE(F,G,G') => DD_NON_CONSTANT */
207  /* if F != G and F != G' */
208 
209  comple = bddVarToCanonical(dd, &f, &g, &h, &topf, &topg, &toph);
210 
211  /* Cache lookup. */
213  if (r != NULL) {
214  return(Cudd_NotCond(r,comple && r != DD_NON_CONSTANT));
215  }
216 
217  v = ddMin(topg, toph);
218 
219  /* ITE(F,G,H) = (v,G,H) (non constant) if F = (v,1,0), v < top(G,H). */
220  if (topf < v && cuddT(f) == one && cuddE(f) == zero) {
221  return(DD_NON_CONSTANT);
222  }
223 
224  /* Compute cofactors. */
225  if (topf <= v) {
226  v = ddMin(topf, v); /* v = top_var(F,G,H) */
227  Fv = cuddT(f); Fnv = cuddE(f);
228  } else {
229  Fv = Fnv = f;
230  }
231 
232  if (topg == v) {
233  Gv = cuddT(g); Gnv = cuddE(g);
234  } else {
235  Gv = Gnv = g;
236  }
237 
238  if (toph == v) {
239  H = Cudd_Regular(h);
240  Hv = cuddT(H); Hnv = cuddE(H);
241  if (Cudd_IsComplement(h)) {
242  Hv = Cudd_Not(Hv);
243  Hnv = Cudd_Not(Hnv);
244  }
245  } else {
246  Hv = Hnv = h;
247  }
248 
249  /* Recursion. */
250  t = Cudd_bddIteConstant(dd, Fv, Gv, Hv);
251  if (t == DD_NON_CONSTANT || !Cudd_IsConstant(t)) {
253  return(DD_NON_CONSTANT);
254  }
255  e = Cudd_bddIteConstant(dd, Fnv, Gnv, Hnv);
256  if (e == DD_NON_CONSTANT || !Cudd_IsConstant(e) || t != e) {
258  return(DD_NON_CONSTANT);
259  }
260  cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, t);
261  return(Cudd_NotCond(t,comple));
262 
263 } /* 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:1173
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
#define DD_BDD_ITE_CONSTANT_TAG
Definition: cuddInt.h:186
#define Cudd_IsConstant(node)
Definition: cudd.h:352
#define Cudd_Regular(node)
Definition: cudd.h:397
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:222
DdNode * Cudd_bddIteConstant(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:174
#define statLine(dd)
Definition: cuddInt.h:1037
static void bddVarToConst(DdNode *f, DdNode **gp, DdNode **hp, DdNode *one)
Definition: cuddBddIte.c:1138
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
#define ddMin(x, y)
Definition: cuddInt.h:818
DdNode * cuddConstantLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:721
#define cuddT(node)
Definition: cuddInt.h:636
#define cuddE(node)
Definition: cuddInt.h:652
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
#define DD_ONE(dd)
Definition: cuddInt.h:911
static DdNode * zero
Definition: cuddApa.c:100
#define DD_NON_CONSTANT
Definition: cuddInt.h:123
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 536 of file cuddBddIte.c.

540 {
541  DdNode *one, *zero, *tmp, *F, *fv, *fvn, *gv, *gvn;
542  unsigned int topf, topg, res;
543 
544  statLine(dd);
545  /* Terminal cases and normalization. */
546  if (f == g) return(1);
547 
548  if (Cudd_IsComplement(g)) {
549  /* Special case: if f is regular and g is complemented,
550  ** f(1,...,1) = 1 > 0 = g(1,...,1).
551  */
552  if (!Cudd_IsComplement(f)) return(0);
553  /* Both are complemented: Swap and complement because
554  ** f <= g <=> g' <= f' and we want the second argument to be regular.
555  */
556  tmp = g;
557  g = Cudd_Not(f);
558  f = Cudd_Not(tmp);
559  } else if (Cudd_IsComplement(f) && cuddF2L(g) < cuddF2L(f)) {
560  tmp = g;
561  g = Cudd_Not(f);
562  f = Cudd_Not(tmp);
563  }
564 
565  /* Now g is regular and, if f is not regular, f < g. */
566  one = DD_ONE(dd);
567  if (g == one) return(1); /* no need to test against zero */
568  if (f == one) return(0); /* since at this point g != one */
569  if (Cudd_Not(f) == g) return(0); /* because neither is constant */
570  zero = Cudd_Not(one);
571  if (f == zero) return(1);
572 
573  /* Here neither f nor g is constant. */
574 
575  /* Check cache. */
576  tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_bddLeq,f,g);
577  if (tmp != NULL) {
578  return(tmp == one);
579  }
580 
581  /* Compute cofactors. */
582  F = Cudd_Regular(f);
583  topf = dd->perm[F->index];
584  topg = dd->perm[g->index];
585  if (topf <= topg) {
586  fv = cuddT(F); fvn = cuddE(F);
587  if (f != F) {
588  fv = Cudd_Not(fv);
589  fvn = Cudd_Not(fvn);
590  }
591  } else {
592  fv = fvn = f;
593  }
594  if (topg <= topf) {
595  gv = cuddT(g); gvn = cuddE(g);
596  } else {
597  gv = gvn = g;
598  }
599 
600  /* Recursive calls. Since we want to maximize the probability of
601  ** the special case f(1,...,1) > g(1,...,1), we consider the negative
602  ** cofactors first. Indeed, the complementation parity of the positive
603  ** cofactors is the same as the one of the parent functions.
604  */
605  res = Cudd_bddLeq(dd,fvn,gvn) && Cudd_bddLeq(dd,fv,gv);
606 
607  /* Store result in cache and return. */
608  cuddCacheInsert2(dd,(DD_CTFP)Cudd_bddLeq,f,g,(res ? one : zero));
609  return(res);
610 
611 } /* end of Cudd_bddLeq */
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define Cudd_Regular(node)
Definition: cudd.h:397
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:321
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
#define cuddF2L(f)
Definition: cuddInt.h:718
#define cuddT(node)
Definition: cuddInt.h:636
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:536
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#define DD_ONE(dd)
Definition: cuddInt.h:911
int * perm
Definition: cuddInt.h:386
static DdNode * zero
Definition: cuddApa.c:100
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 413 of file cuddBddIte.c.

417 {
418  DdNode *res;
419 
420  do {
421  dd->reordered = 0;
422  res = cuddBddAndRecur(dd,f,g);
423  } while (dd->reordered == 1);
424  res = Cudd_NotCond(res,res != NULL);
425  return(res);
426 
427 } /* end of Cudd_bddNand */
Definition: cudd.h:278
int reordered
Definition: cuddInt.h:409
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
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 445 of file cuddBddIte.c.

449 {
450  DdNode *res;
451 
452  do {
453  dd->reordered = 0;
454  res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g));
455  } while (dd->reordered == 1);
456  return(res);
457 
458 } /* end of Cudd_bddNor */
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
int reordered
Definition: cuddInt.h:409
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
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 381 of file cuddBddIte.c.

385 {
386  DdNode *res;
387 
388  do {
389  dd->reordered = 0;
390  res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g));
391  } while (dd->reordered == 1);
392  res = Cudd_NotCond(res,res != NULL);
393  return(res);
394 
395 } /* end of Cudd_bddOr */
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
int reordered
Definition: cuddInt.h:409
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
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 507 of file cuddBddIte.c.

511 {
512  DdNode *res;
513 
514  do {
515  dd->reordered = 0;
516  res = cuddBddXorRecur(dd,f,Cudd_Not(g));
517  } while (dd->reordered == 1);
518  return(res);
519 
520 } /* end of Cudd_bddXnor */
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
int reordered
Definition: cuddInt.h:409
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1017
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 476 of file cuddBddIte.c.

480 {
481  DdNode *res;
482 
483  do {
484  dd->reordered = 0;
485  res = cuddBddXorRecur(dd,f,g);
486  } while (dd->reordered == 1);
487  return(res);
488 
489 } /* end of Cudd_bddXor */
Definition: cudd.h:278
int reordered
Definition: cuddInt.h:409
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1017
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 886 of file cuddBddIte.c.

890 {
891  DdNode *F, *fv, *fnv, *G, *gv, *gnv;
892  DdNode *one, *r, *t, *e;
893  unsigned int topf, topg, index;
894 
895  statLine(manager);
896  one = DD_ONE(manager);
897 
898  /* Terminal cases. */
899  F = Cudd_Regular(f);
900  G = Cudd_Regular(g);
901  if (F == G) {
902  if (f == g) return(f);
903  else return(Cudd_Not(one));
904  }
905  if (F == one) {
906  if (f == one) return(g);
907  else return(f);
908  }
909  if (G == one) {
910  if (g == one) return(f);
911  else return(g);
912  }
913 
914  /* At this point f and g are not constant. */
915  if (cuddF2L(f) > cuddF2L(g)) { /* Try to increase cache efficiency. */
916  DdNode *tmp = f;
917  f = g;
918  g = tmp;
919  F = Cudd_Regular(f);
920  G = Cudd_Regular(g);
921  }
922 
923  /* Check cache. */
924  if (F->ref != 1 || G->ref != 1) {
925  r = cuddCacheLookup2(manager, Cudd_bddAnd, f, g);
926  if (r != NULL) return(r);
927  }
928 
929  if ( manager->TimeStop && Abc_Clock() > manager->TimeStop )
930  return NULL;
931 
932  /* Here we can skip the use of cuddI, because the operands are known
933  ** to be non-constant.
934  */
935  topf = manager->perm[F->index];
936  topg = manager->perm[G->index];
937 
938  /* Compute cofactors. */
939  if (topf <= topg) {
940  index = F->index;
941  fv = cuddT(F);
942  fnv = cuddE(F);
943  if (Cudd_IsComplement(f)) {
944  fv = Cudd_Not(fv);
945  fnv = Cudd_Not(fnv);
946  }
947  } else {
948  index = G->index;
949  fv = fnv = f;
950  }
951 
952  if (topg <= topf) {
953  gv = cuddT(G);
954  gnv = cuddE(G);
955  if (Cudd_IsComplement(g)) {
956  gv = Cudd_Not(gv);
957  gnv = Cudd_Not(gnv);
958  }
959  } else {
960  gv = gnv = g;
961  }
962 
963  t = cuddBddAndRecur(manager, fv, gv);
964  if (t == NULL) return(NULL);
965  cuddRef(t);
966 
967  e = cuddBddAndRecur(manager, fnv, gnv);
968  if (e == NULL) {
969  Cudd_IterDerefBdd(manager, t);
970  return(NULL);
971  }
972  cuddRef(e);
973 
974  if (t == e) {
975  r = t;
976  } else {
977  if (Cudd_IsComplement(t)) {
978  r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e));
979  if (r == NULL) {
980  Cudd_IterDerefBdd(manager, t);
981  Cudd_IterDerefBdd(manager, e);
982  return(NULL);
983  }
984  r = Cudd_Not(r);
985  } else {
986  r = cuddUniqueInter(manager,(int)index,t,e);
987  if (r == NULL) {
988  Cudd_IterDerefBdd(manager, t);
989  Cudd_IterDerefBdd(manager, e);
990  return(NULL);
991  }
992  }
993  }
994  cuddDeref(e);
995  cuddDeref(t);
996  if (F->ref != 1 || G->ref != 1)
997  cuddCacheInsert2(manager, Cudd_bddAnd, f, g, r);
998  return(r);
999 
1000 } /* end of cuddBddAndRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
DdHalfWord ref
Definition: cudd.h:280
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
abctime TimeStop
Definition: cuddInt.h:489
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define Cudd_Regular(node)
Definition: cudd.h:397
static abctime Abc_Clock()
Definition: abc_global.h:279
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
#define cuddF2L(f)
Definition: cuddInt.h:718
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
DdNode * Cudd_bddAnd(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:314
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
int * perm
Definition: cuddInt.h:386
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
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 771 of file cuddBddIte.c.

775 {
776  DdNode *res;
777  DdNode *F, *G, *t, *e;
778  DdNode *fv, *fnv, *gv, *gnv;
779  DdNode *one, *zero;
780  unsigned int index, topf, topg;
781 
782  statLine(dd);
783  one = DD_ONE(dd);
784  zero = Cudd_Not(one);
785 
786  /* Terminal cases. */
787  if (f == zero || g == zero || f == Cudd_Not(g)) return(zero);
788  if (f == g || g == one) return(f);
789  if (f == one) return(g);
790 
791  /* At this point f and g are not constant. */
792  if (cuddF2L(f) > cuddF2L(g)) { DdNode *tmp = f; f = g; g = tmp; }
793  res = cuddCacheLookup2(dd,Cudd_bddIntersect,f,g);
794  if (res != NULL) return(res);
795 
796  /* Find splitting variable. Here we can skip the use of cuddI,
797  ** because the operands are known to be non-constant.
798  */
799  F = Cudd_Regular(f);
800  topf = dd->perm[F->index];
801  G = Cudd_Regular(g);
802  topg = dd->perm[G->index];
803 
804  /* Compute cofactors. */
805  if (topf <= topg) {
806  index = F->index;
807  fv = cuddT(F);
808  fnv = cuddE(F);
809  if (Cudd_IsComplement(f)) {
810  fv = Cudd_Not(fv);
811  fnv = Cudd_Not(fnv);
812  }
813  } else {
814  index = G->index;
815  fv = fnv = f;
816  }
817 
818  if (topg <= topf) {
819  gv = cuddT(G);
820  gnv = cuddE(G);
821  if (Cudd_IsComplement(g)) {
822  gv = Cudd_Not(gv);
823  gnv = Cudd_Not(gnv);
824  }
825  } else {
826  gv = gnv = g;
827  }
828 
829  /* Compute partial results. */
830  t = cuddBddIntersectRecur(dd,fv,gv);
831  if (t == NULL) return(NULL);
832  cuddRef(t);
833  if (t != zero) {
834  e = zero;
835  } else {
836  e = cuddBddIntersectRecur(dd,fnv,gnv);
837  if (e == NULL) {
838  Cudd_IterDerefBdd(dd, t);
839  return(NULL);
840  }
841  }
842  cuddRef(e);
843 
844  if (t == e) { /* both equal zero */
845  res = t;
846  } else if (Cudd_IsComplement(t)) {
847  res = cuddUniqueInter(dd,(int)index,Cudd_Not(t),Cudd_Not(e));
848  if (res == NULL) {
849  Cudd_IterDerefBdd(dd, t);
850  Cudd_IterDerefBdd(dd, e);
851  return(NULL);
852  }
853  res = Cudd_Not(res);
854  } else {
855  res = cuddUniqueInter(dd,(int)index,t,e);
856  if (res == NULL) {
857  Cudd_IterDerefBdd(dd, t);
858  Cudd_IterDerefBdd(dd, e);
859  return(NULL);
860  }
861  }
862  cuddDeref(e);
863  cuddDeref(t);
864 
866 
867  return(res);
868 
869 } /* end of cuddBddIntersectRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
DdNode * Cudd_bddIntersect(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:282
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define Cudd_Regular(node)
Definition: cudd.h:397
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
#define cuddF2L(f)
Definition: cuddInt.h:718
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
DdNode * cuddBddIntersectRecur(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:771
#define cuddE(node)
Definition: cuddInt.h:652
#define DD_ONE(dd)
Definition: cuddInt.h:911
int * perm
Definition: cuddInt.h:386
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
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 633 of file cuddBddIte.c.

638 {
639  DdNode *one, *zero, *res;
640  DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e;
641  unsigned int topf, topg, toph, v;
642  int index = -1;
643  int comple;
644 
645  statLine(dd);
646  /* Terminal cases. */
647 
648  /* One variable cases. */
649  if (f == (one = DD_ONE(dd))) /* ITE(1,G,H) = G */
650  return(g);
651 
652  if (f == (zero = Cudd_Not(one))) /* ITE(0,G,H) = H */
653  return(h);
654 
655  /* From now on, f is known not to be a constant. */
656  if (g == one || f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */
657  if (h == zero) { /* ITE(F,1,0) = F */
658  return(f);
659  } else {
660  res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(h));
661  return(Cudd_NotCond(res,res != NULL));
662  }
663  } else if (g == zero || f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */
664  if (h == one) { /* ITE(F,0,1) = !F */
665  return(Cudd_Not(f));
666  } else {
667  res = cuddBddAndRecur(dd,Cudd_Not(f),h);
668  return(res);
669  }
670  }
671  if (h == zero || f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */
672  res = cuddBddAndRecur(dd,f,g);
673  return(res);
674  } else if (h == one || f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */
675  res = cuddBddAndRecur(dd,f,Cudd_Not(g));
676  return(Cudd_NotCond(res,res != NULL));
677  }
678 
679  /* Check remaining one variable case. */
680  if (g == h) { /* ITE(F,G,G) = G */
681  return(g);
682  } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = F <-> G */
683  res = cuddBddXorRecur(dd,f,h);
684  return(res);
685  }
686 
687  /* From here, there are no constants. */
688  comple = bddVarToCanonicalSimple(dd, &f, &g, &h, &topf, &topg, &toph);
689 
690  /* f & g are now regular pointers */
691 
692  v = ddMin(topg, toph);
693 
694  /* A shortcut: ITE(F,G,H) = (v,G,H) if F = (v,1,0), v < top(G,H). */
695  if (topf < v && cuddT(f) == one && cuddE(f) == zero) {
696  r = cuddUniqueInter(dd, (int) f->index, g, h);
697  return(Cudd_NotCond(r,comple && r != NULL));
698  }
699 
700  /* Check cache. */
701  r = cuddCacheLookup(dd, DD_BDD_ITE_TAG, f, g, h);
702  if (r != NULL) {
703  return(Cudd_NotCond(r,comple));
704  }
705 
706  /* Compute cofactors. */
707  if (topf <= v) {
708  v = ddMin(topf, v); /* v = top_var(F,G,H) */
709  index = f->index;
710  Fv = cuddT(f); Fnv = cuddE(f);
711  } else {
712  Fv = Fnv = f;
713  }
714  if (topg == v) {
715  index = g->index;
716  Gv = cuddT(g); Gnv = cuddE(g);
717  } else {
718  Gv = Gnv = g;
719  }
720  if (toph == v) {
721  H = Cudd_Regular(h);
722  index = H->index;
723  Hv = cuddT(H); Hnv = cuddE(H);
724  if (Cudd_IsComplement(h)) {
725  Hv = Cudd_Not(Hv);
726  Hnv = Cudd_Not(Hnv);
727  }
728  } else {
729  Hv = Hnv = h;
730  }
731 
732  /* Recursive step. */
733  t = cuddBddIteRecur(dd,Fv,Gv,Hv);
734  if (t == NULL) return(NULL);
735  cuddRef(t);
736 
737  e = cuddBddIteRecur(dd,Fnv,Gnv,Hnv);
738  if (e == NULL) {
739  Cudd_IterDerefBdd(dd,t);
740  return(NULL);
741  }
742  cuddRef(e);
743 
744  r = (t == e) ? t : cuddUniqueInter(dd,index,t,e);
745  if (r == NULL) {
746  Cudd_IterDerefBdd(dd,t);
747  Cudd_IterDerefBdd(dd,e);
748  return(NULL);
749  }
750  cuddDeref(t);
751  cuddDeref(e);
752 
753  cuddCacheInsert(dd, DD_BDD_ITE_TAG, f, g, h, r);
754  return(Cudd_NotCond(r,comple));
755 
756 } /* end of cuddBddIteRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
#define Cudd_Regular(node)
Definition: cudd.h:397
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:222
static int bddVarToCanonicalSimple(DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp)
Definition: cuddBddIte.c:1275
#define statLine(dd)
Definition: cuddInt.h:1037
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
#define ddMin(x, y)
Definition: cuddInt.h:818
#define DD_BDD_ITE_TAG
Definition: cuddInt.h:175
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1017
#define cuddE(node)
Definition: cuddInt.h:652
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:369
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:633
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 1017 of file cuddBddIte.c.

1021 {
1022  DdNode *fv, *fnv, *G, *gv, *gnv;
1023  DdNode *one, *zero, *r, *t, *e;
1024  unsigned int topf, topg, index;
1025 
1026  statLine(manager);
1027  one = DD_ONE(manager);
1028  zero = Cudd_Not(one);
1029 
1030  /* Terminal cases. */
1031  if (f == g) return(zero);
1032  if (f == Cudd_Not(g)) return(one);
1033  if (cuddF2L(f) > cuddF2L(g)) { /* Try to increase cache efficiency and simplify tests. */
1034  DdNode *tmp = f;
1035  f = g;
1036  g = tmp;
1037  }
1038  if (g == zero) return(f);
1039  if (g == one) return(Cudd_Not(f));
1040  if (Cudd_IsComplement(f)) {
1041  f = Cudd_Not(f);
1042  g = Cudd_Not(g);
1043  }
1044  /* Now the first argument is regular. */
1045  if (f == one) return(Cudd_Not(g));
1046 
1047  /* At this point f and g are not constant. */
1048 
1049  /* Check cache. */
1050  r = cuddCacheLookup2(manager, Cudd_bddXor, f, g);
1051  if (r != NULL) return(r);
1052 
1053  /* Here we can skip the use of cuddI, because the operands are known
1054  ** to be non-constant.
1055  */
1056  topf = manager->perm[f->index];
1057  G = Cudd_Regular(g);
1058  topg = manager->perm[G->index];
1059 
1060  /* Compute cofactors. */
1061  if (topf <= topg) {
1062  index = f->index;
1063  fv = cuddT(f);
1064  fnv = cuddE(f);
1065  } else {
1066  index = G->index;
1067  fv = fnv = f;
1068  }
1069 
1070  if (topg <= topf) {
1071  gv = cuddT(G);
1072  gnv = cuddE(G);
1073  if (Cudd_IsComplement(g)) {
1074  gv = Cudd_Not(gv);
1075  gnv = Cudd_Not(gnv);
1076  }
1077  } else {
1078  gv = gnv = g;
1079  }
1080 
1081  t = cuddBddXorRecur(manager, fv, gv);
1082  if (t == NULL) return(NULL);
1083  cuddRef(t);
1084 
1085  e = cuddBddXorRecur(manager, fnv, gnv);
1086  if (e == NULL) {
1087  Cudd_IterDerefBdd(manager, t);
1088  return(NULL);
1089  }
1090  cuddRef(e);
1091 
1092  if (t == e) {
1093  r = t;
1094  } else {
1095  if (Cudd_IsComplement(t)) {
1096  r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e));
1097  if (r == NULL) {
1098  Cudd_IterDerefBdd(manager, t);
1099  Cudd_IterDerefBdd(manager, e);
1100  return(NULL);
1101  }
1102  r = Cudd_Not(r);
1103  } else {
1104  r = cuddUniqueInter(manager,(int)index,t,e);
1105  if (r == NULL) {
1106  Cudd_IterDerefBdd(manager, t);
1107  Cudd_IterDerefBdd(manager, e);
1108  return(NULL);
1109  }
1110  }
1111  }
1112  cuddDeref(e);
1113  cuddDeref(t);
1114  cuddCacheInsert2(manager, Cudd_bddXor, f, g, r);
1115  return(r);
1116 
1117 } /* end of cuddBddXorRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define Cudd_Regular(node)
Definition: cudd.h:397
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
DdNode * Cudd_bddXor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:476
#define cuddF2L(f)
Definition: cuddInt.h:718
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1017
#define cuddE(node)
Definition: cuddInt.h:652
#define DD_ONE(dd)
Definition: cuddInt.h:911
int * perm
Definition: cuddInt.h:386
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100

Variable Documentation

ABC_NAMESPACE_IMPL_START char rcsid [] DD_UNUSED = "$Id: cuddBddIte.c,v 1.24 2004/08/13 18:04:46 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-2004, 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 103 of file cuddBddIte.c.