abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddBddIte.c
Go to the documentation of this file.
1 /**CFile***********************************************************************
2 
3  FileName [cuddBddIte.c]
4 
5  PackageName [cudd]
6 
7  Synopsis [BDD ITE function and satellites.]
8 
9  Description [External procedures included in this module:
10  <ul>
11  <li> Cudd_bddIte()
12  <li> Cudd_bddIteConstant()
13  <li> Cudd_bddIntersect()
14  <li> Cudd_bddAnd()
15  <li> Cudd_bddAndLimit()
16  <li> Cudd_bddOr()
17  <li> Cudd_bddNand()
18  <li> Cudd_bddNor()
19  <li> Cudd_bddXor()
20  <li> Cudd_bddXnor()
21  <li> Cudd_bddLeq()
22  </ul>
23  Internal procedures included in this module:
24  <ul>
25  <li> cuddBddIteRecur()
26  <li> cuddBddIntersectRecur()
27  <li> cuddBddAndRecur()
28  <li> cuddBddXorRecur()
29  </ul>
30  Static procedures included in this module:
31  <ul>
32  <li> bddVarToConst()
33  <li> bddVarToCanonical()
34  <li> bddVarToCanonicalSimple()
35  </ul>]
36 
37  SeeAlso []
38 
39  Author [Fabio Somenzi]
40 
41  Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
42 
43  All rights reserved.
44 
45  Redistribution and use in source and binary forms, with or without
46  modification, are permitted provided that the following conditions
47  are met:
48 
49  Redistributions of source code must retain the above copyright
50  notice, this list of conditions and the following disclaimer.
51 
52  Redistributions in binary form must reproduce the above copyright
53  notice, this list of conditions and the following disclaimer in the
54  documentation and/or other materials provided with the distribution.
55 
56  Neither the name of the University of Colorado nor the names of its
57  contributors may be used to endorse or promote products derived from
58  this software without specific prior written permission.
59 
60  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
61  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
62  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
63  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
64  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
65  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
66  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
67  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
68  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
69  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
70  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
71  POSSIBILITY OF SUCH DAMAGE.]
72 
73 ******************************************************************************/
74 
75 #include "misc/util/util_hack.h"
76 #include "cuddInt.h"
77 
79 
80 
81 
82 
83 /*---------------------------------------------------------------------------*/
84 /* Constant declarations */
85 /*---------------------------------------------------------------------------*/
86 
87 
88 /*---------------------------------------------------------------------------*/
89 /* Stucture declarations */
90 /*---------------------------------------------------------------------------*/
91 
92 
93 /*---------------------------------------------------------------------------*/
94 /* Type declarations */
95 /*---------------------------------------------------------------------------*/
96 
97 
98 /*---------------------------------------------------------------------------*/
99 /* Variable declarations */
100 /*---------------------------------------------------------------------------*/
101 
102 #ifndef lint
103 static char rcsid[] DD_UNUSED = "$Id: cuddBddIte.c,v 1.24 2004/08/13 18:04:46 fabio Exp $";
104 #endif
105 
106 /*---------------------------------------------------------------------------*/
107 /* Macro declarations */
108 /*---------------------------------------------------------------------------*/
109 
110 
111 /**AutomaticStart*************************************************************/
112 
113 /*---------------------------------------------------------------------------*/
114 /* Static function prototypes */
115 /*---------------------------------------------------------------------------*/
116 
117 static void bddVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *one);
118 static int bddVarToCanonical (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp);
119 static int bddVarToCanonicalSimple (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp);
120 
121 /**AutomaticEnd***************************************************************/
122 
123 
124 /*---------------------------------------------------------------------------*/
125 /* Definition of exported functions */
126 /*---------------------------------------------------------------------------*/
127 
128 
129 /**Function********************************************************************
130 
131  Synopsis [Implements ITE(f,g,h).]
132 
133  Description [Implements ITE(f,g,h). Returns a pointer to the
134  resulting BDD if successful; NULL if the intermediate result blows
135  up.]
136 
137  SideEffects [None]
138 
139  SeeAlso [Cudd_addIte Cudd_bddIteConstant Cudd_bddIntersect]
140 
141 ******************************************************************************/
142 DdNode *
144  DdManager * dd,
145  DdNode * f,
146  DdNode * g,
147  DdNode * h)
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 */
158 
159 
160 /**Function********************************************************************
161 
162  Synopsis [Implements ITEconstant(f,g,h).]
163 
164  Description [Implements ITEconstant(f,g,h). Returns a pointer to the
165  resulting BDD (which may or may not be constant) or DD_NON_CONSTANT.
166  No new nodes are created.]
167 
168  SideEffects [None]
169 
170  SeeAlso [Cudd_bddIte Cudd_bddIntersect Cudd_bddLeq Cudd_addIteConstant]
171 
172 ******************************************************************************/
173 DdNode *
175  DdManager * dd,
176  DdNode * f,
177  DdNode * g,
178  DdNode * h)
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 */
264 
265 
266 /**Function********************************************************************
267 
268  Synopsis [Returns a function included in the intersection of f and g.]
269 
270  Description [Computes a function included in the intersection of f and
271  g. (That is, a witness that the intersection is not empty.)
272  Cudd_bddIntersect tries to build as few new nodes as possible. If the
273  only result of interest is whether f and g intersect,
274  Cudd_bddLeq should be used instead.]
275 
276  SideEffects [None]
277 
278  SeeAlso [Cudd_bddLeq Cudd_bddIteConstant]
279 
280 ******************************************************************************/
281 DdNode *
283  DdManager * dd /* manager */,
284  DdNode * f /* first operand */,
285  DdNode * g /* second operand */)
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 */
297 
298 
299 /**Function********************************************************************
300 
301  Synopsis [Computes the conjunction of two BDDs f and g.]
302 
303  Description [Computes the conjunction of two BDDs f and g. Returns a
304  pointer to the resulting BDD if successful; NULL if the intermediate
305  result blows up.]
306 
307  SideEffects [None]
308 
309  SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAndAbstract Cudd_bddIntersect
310  Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXor Cudd_bddXnor]
311 
312 ******************************************************************************/
313 DdNode *
315  DdManager * dd,
316  DdNode * f,
317  DdNode * g)
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 */
328 
329 
330 /**Function********************************************************************
331 
332  Synopsis [Computes the conjunction of two BDDs f and g. Returns
333  NULL if too many nodes are required.]
334 
335  Description [Computes the conjunction of two BDDs f and g. Returns a
336  pointer to the resulting BDD if successful; NULL if the intermediate
337  result blows up or more new nodes than <code>limit</code> are
338  required.]
339 
340  SideEffects [None]
341 
342  SeeAlso [Cudd_bddAnd]
343 
344 ******************************************************************************/
345 DdNode *
347  DdManager * dd,
348  DdNode * f,
349  DdNode * g,
350  unsigned int limit)
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 */
364 
365 
366 /**Function********************************************************************
367 
368  Synopsis [Computes the disjunction of two BDDs f and g.]
369 
370  Description [Computes the disjunction of two BDDs f and g. Returns a
371  pointer to the resulting BDD if successful; NULL if the intermediate
372  result blows up.]
373 
374  SideEffects [None]
375 
376  SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddNand Cudd_bddNor
377  Cudd_bddXor Cudd_bddXnor]
378 
379 ******************************************************************************/
380 DdNode *
382  DdManager * dd,
383  DdNode * f,
384  DdNode * g)
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 */
396 
397 
398 /**Function********************************************************************
399 
400  Synopsis [Computes the NAND of two BDDs f and g.]
401 
402  Description [Computes the NAND of two BDDs f and g. Returns a
403  pointer to the resulting BDD if successful; NULL if the intermediate
404  result blows up.]
405 
406  SideEffects [None]
407 
408  SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNor
409  Cudd_bddXor Cudd_bddXnor]
410 
411 ******************************************************************************/
412 DdNode *
414  DdManager * dd,
415  DdNode * f,
416  DdNode * g)
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 */
428 
429 
430 /**Function********************************************************************
431 
432  Synopsis [Computes the NOR of two BDDs f and g.]
433 
434  Description [Computes the NOR of two BDDs f and g. Returns a
435  pointer to the resulting BDD if successful; NULL if the intermediate
436  result blows up.]
437 
438  SideEffects [None]
439 
440  SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNand
441  Cudd_bddXor Cudd_bddXnor]
442 
443 ******************************************************************************/
444 DdNode *
446  DdManager * dd,
447  DdNode * f,
448  DdNode * g)
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 */
459 
460 
461 /**Function********************************************************************
462 
463  Synopsis [Computes the exclusive OR of two BDDs f and g.]
464 
465  Description [Computes the exclusive OR of two BDDs f and g. Returns a
466  pointer to the resulting BDD if successful; NULL if the intermediate
467  result blows up.]
468 
469  SideEffects [None]
470 
471  SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr
472  Cudd_bddNand Cudd_bddNor Cudd_bddXnor]
473 
474 ******************************************************************************/
475 DdNode *
477  DdManager * dd,
478  DdNode * f,
479  DdNode * g)
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 */
490 
491 
492 /**Function********************************************************************
493 
494  Synopsis [Computes the exclusive NOR of two BDDs f and g.]
495 
496  Description [Computes the exclusive NOR of two BDDs f and g. Returns a
497  pointer to the resulting BDD if successful; NULL if the intermediate
498  result blows up.]
499 
500  SideEffects [None]
501 
502  SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr
503  Cudd_bddNand Cudd_bddNor Cudd_bddXor]
504 
505 ******************************************************************************/
506 DdNode *
508  DdManager * dd,
509  DdNode * f,
510  DdNode * g)
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 */
521 
522 
523 /**Function********************************************************************
524 
525  Synopsis [Determines whether f is less than or equal to g.]
526 
527  Description [Returns 1 if f is less than or equal to g; 0 otherwise.
528  No new nodes are created.]
529 
530  SideEffects [None]
531 
532  SeeAlso [Cudd_bddIteConstant Cudd_addEvalConst]
533 
534 ******************************************************************************/
535 int
537  DdManager * dd,
538  DdNode * f,
539  DdNode * g)
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 */
612 
613 
614 /*---------------------------------------------------------------------------*/
615 /* Definition of internal functions */
616 /*---------------------------------------------------------------------------*/
617 
618 
619 /**Function********************************************************************
620 
621  Synopsis [Implements the recursive step of Cudd_bddIte.]
622 
623  Description [Implements the recursive step of Cudd_bddIte. Returns a
624  pointer to the resulting BDD. NULL if the intermediate result blows
625  up or if reordering occurs.]
626 
627  SideEffects [None]
628 
629  SeeAlso []
630 
631 ******************************************************************************/
632 DdNode *
634  DdManager * dd,
635  DdNode * f,
636  DdNode * g,
637  DdNode * h)
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 */
757 
758 
759 /**Function********************************************************************
760 
761  Synopsis [Implements the recursive step of Cudd_bddIntersect.]
762 
763  Description []
764 
765  SideEffects [None]
766 
767  SeeAlso [Cudd_bddIntersect]
768 
769 ******************************************************************************/
770 DdNode *
772  DdManager * dd,
773  DdNode * f,
774  DdNode * g)
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 */
870 
871 
872 /**Function********************************************************************
873 
874  Synopsis [Implements the recursive step of Cudd_bddAnd.]
875 
876  Description [Implements the recursive step of Cudd_bddAnd by taking
877  the conjunction of two BDDs. Returns a pointer to the result is
878  successful; NULL otherwise.]
879 
880  SideEffects [None]
881 
882  SeeAlso [Cudd_bddAnd]
883 
884 ******************************************************************************/
885 DdNode *
887  DdManager * manager,
888  DdNode * f,
889  DdNode * g)
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 */
1001 
1002 
1003 /**Function********************************************************************
1004 
1005  Synopsis [Implements the recursive step of Cudd_bddXor.]
1006 
1007  Description [Implements the recursive step of Cudd_bddXor by taking
1008  the exclusive OR of two BDDs. Returns a pointer to the result is
1009  successful; NULL otherwise.]
1010 
1011  SideEffects [None]
1012 
1013  SeeAlso [Cudd_bddXor]
1014 
1015 ******************************************************************************/
1016 DdNode *
1018  DdManager * manager,
1019  DdNode * f,
1020  DdNode * g)
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 */
1118 
1119 
1120 /*---------------------------------------------------------------------------*/
1121 /* Definition of static functions */
1122 /*---------------------------------------------------------------------------*/
1123 
1124 
1125 /**Function********************************************************************
1126 
1127  Synopsis [Replaces variables with constants if possible.]
1128 
1129  Description [This function performs part of the transformation to
1130  standard form by replacing variables with constants if possible.]
1131 
1132  SideEffects [None]
1133 
1134  SeeAlso [bddVarToCanonical bddVarToCanonicalSimple]
1135 
1136 ******************************************************************************/
1137 static void
1139  DdNode * f,
1140  DdNode ** gp,
1141  DdNode ** hp,
1142  DdNode * one)
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 */
1159 
1160 
1161 /**Function********************************************************************
1162 
1163  Synopsis [Picks unique member from equiv expressions.]
1164 
1165  Description [Reduces 2 variable expressions to canonical form.]
1166 
1167  SideEffects [None]
1168 
1169  SeeAlso [bddVarToConst bddVarToCanonicalSimple]
1170 
1171 ******************************************************************************/
1172 static int
1174  DdManager * dd,
1175  DdNode ** fp,
1176  DdNode ** gp,
1177  DdNode ** hp,
1178  unsigned int * topfp,
1179  unsigned int * topgp,
1180  unsigned int * tophp)
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 */
1257 
1258 
1259 /**Function********************************************************************
1260 
1261  Synopsis [Picks unique member from equiv expressions.]
1262 
1263  Description [Makes sure the first two pointers are regular. This
1264  mat require the complementation of the result, which is signaled by
1265  returning 1 instead of 0. This function is simpler than the general
1266  case because it assumes that no two arguments are the same or
1267  complementary, and no argument is constant.]
1268 
1269  SideEffects [None]
1270 
1271  SeeAlso [bddVarToConst bddVarToCanonical]
1272 
1273 ******************************************************************************/
1274 static int
1276  DdManager * dd,
1277  DdNode ** fp,
1278  DdNode ** gp,
1279  DdNode ** hp,
1280  unsigned int * topfp,
1281  unsigned int * topgp,
1282  unsigned int * tophp)
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 */
1324 
1325 
1327 
1328 
static ABC_NAMESPACE_IMPL_START char rcsid[] DD_UNUSED
Definition: cuddBddIte.c:103
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
DdHalfWord ref
Definition: cudd.h:280
DdNode * Cudd_bddIntersect(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:282
#define cuddRef(n)
Definition: cuddInt.h:584
static int bddVarToCanonical(DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp)
Definition: cuddBddIte.c:1173
DdNode * Cudd_bddOr(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:381
#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
unsigned int deadZ
Definition: cuddInt.h:372
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#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
static int bddVarToCanonicalSimple(DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp)
Definition: cuddBddIte.c:1275
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:321
DdNode * Cudd_bddAndLimit(DdManager *dd, DdNode *f, DdNode *g, unsigned int limit)
Definition: cuddBddIte.c:346
DdNode * Cudd_bddIteConstant(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:174
DdNode * Cudd_bddNor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:445
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
int reordered
Definition: cuddInt.h:409
unsigned int dead
Definition: cuddInt.h:371
static void bddVarToConst(DdNode *f, DdNode **gp, DdNode **hp, DdNode *one)
Definition: cuddBddIte.c:1138
#define Cudd_IsComplement(node)
Definition: cudd.h:425
unsigned int maxLive
Definition: cuddInt.h:373
unsigned int keys
Definition: cuddInt.h:369
static DdNode * one
Definition: cuddDecomp.c:112
DdNode * Cudd_bddXnor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:507
DdNode * Cudd_bddXor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:476
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
#define cuddF2L(f)
Definition: cuddInt.h:718
#define ddMin(x, y)
Definition: cuddInt.h:818
#define DD_BDD_ITE_TAG
Definition: cuddInt.h:175
DdNode * cuddConstantLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:721
#define cuddT(node)
Definition: cuddInt.h:636
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:536
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
#define cuddI(dd, index)
Definition: cuddInt.h:686
DdHalfWord index
Definition: cudd.h:279
DdNode * cuddBddIntersectRecur(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:771
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1017
DdNode * one
Definition: cuddInt.h:345
DdNode * Cudd_bddNand(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:413
#define cuddE(node)
Definition: cuddInt.h:652
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
DdNode * Cudd_bddAnd(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:314
#define DD_ONE(dd)
Definition: cuddInt.h:911
unsigned int keysZ
Definition: cuddInt.h:370
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
int * perm
Definition: cuddInt.h:386
DdNode * Cudd_bddIte(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:143
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
#define DD_NON_CONSTANT
Definition: cuddInt.h:123
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:633