abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddSat.c
Go to the documentation of this file.
1 /**CFile***********************************************************************
2 
3  FileName [cuddSat.c]
4 
5  PackageName [cudd]
6 
7  Synopsis [Functions for the solution of satisfiability related
8  problems.]
9 
10  Description [External procedures included in this file:
11  <ul>
12  <li> Cudd_Eval()
13  <li> Cudd_ShortestPath()
14  <li> Cudd_LargestCube()
15  <li> Cudd_ShortestLength()
16  <li> Cudd_Decreasing()
17  <li> Cudd_Increasing()
18  <li> Cudd_EquivDC()
19  <li> Cudd_bddLeqUnless()
20  <li> Cudd_EqualSupNorm()
21  <li> Cudd_bddMakePrime()
22  </ul>
23  Internal procedures included in this module:
24  <ul>
25  <li> cuddBddMakePrime()
26  </ul>
27  Static procedures included in this module:
28  <ul>
29  <li> freePathPair()
30  <li> getShortest()
31  <li> getPath()
32  <li> getLargest()
33  <li> getCube()
34  </ul>]
35 
36  Author [Seh-Woong Jeong, Fabio Somenzi]
37 
38  Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
39 
40  All rights reserved.
41 
42  Redistribution and use in source and binary forms, with or without
43  modification, are permitted provided that the following conditions
44  are met:
45 
46  Redistributions of source code must retain the above copyright
47  notice, this list of conditions and the following disclaimer.
48 
49  Redistributions in binary form must reproduce the above copyright
50  notice, this list of conditions and the following disclaimer in the
51  documentation and/or other materials provided with the distribution.
52 
53  Neither the name of the University of Colorado nor the names of its
54  contributors may be used to endorse or promote products derived from
55  this software without specific prior written permission.
56 
57  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
58  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
59  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
60  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
61  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
62  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
63  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
65  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
67  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
68  POSSIBILITY OF SUCH DAMAGE.]
69 
70 ******************************************************************************/
71 
72 #include "misc/util/util_hack.h"
73 #include "cuddInt.h"
74 
76 
77 
78 
79 /*---------------------------------------------------------------------------*/
80 /* Constant declarations */
81 /*---------------------------------------------------------------------------*/
82 
83 #define DD_BIGGY 1000000
84 
85 /*---------------------------------------------------------------------------*/
86 /* Stucture declarations */
87 /*---------------------------------------------------------------------------*/
88 
89 /*---------------------------------------------------------------------------*/
90 /* Type declarations */
91 /*---------------------------------------------------------------------------*/
92 
93 typedef struct cuddPathPair {
94  int pos;
95  int neg;
96 } cuddPathPair;
97 
98 /*---------------------------------------------------------------------------*/
99 /* Variable declarations */
100 /*---------------------------------------------------------------------------*/
101 
102 #ifndef lint
103 static char rcsid[] DD_UNUSED = "$Id: cuddSat.c,v 1.36 2009/03/08 02:49:02 fabio Exp $";
104 #endif
105 
106 static DdNode *one, *zero;
107 
108 /*---------------------------------------------------------------------------*/
109 /* Macro declarations */
110 /*---------------------------------------------------------------------------*/
111 
112 #define WEIGHT(weight, col) ((weight) == NULL ? 1 : weight[col])
113 
114 #ifdef __cplusplus
115 extern "C" {
116 #endif
117 
118 /**AutomaticStart*************************************************************/
119 
120 /*---------------------------------------------------------------------------*/
121 /* Static function prototypes */
122 /*---------------------------------------------------------------------------*/
123 
124 static enum st__retval freePathPair (char *key, char *value, char *arg);
125 static cuddPathPair getShortest (DdNode *root, int *cost, int *support, st__table *visited);
126 static DdNode * getPath (DdManager *manager, st__table *visited, DdNode *f, int *weight, int cost);
127 static cuddPathPair getLargest (DdNode *root, st__table *visited);
128 static DdNode * getCube (DdManager *manager, st__table *visited, DdNode *f, int cost);
129 
130 /**AutomaticEnd***************************************************************/
131 
132 #ifdef __cplusplus
133 }
134 #endif
135 
136 /*---------------------------------------------------------------------------*/
137 /* Definition of exported functions */
138 /*---------------------------------------------------------------------------*/
139 
140 
141 /**Function********************************************************************
142 
143  Synopsis [Returns the value of a DD for a given variable assignment.]
144 
145  Description [Finds the value of a DD for a given variable
146  assignment. The variable assignment is passed in an array of int's,
147  that should specify a zero or a one for each variable in the support
148  of the function. Returns a pointer to a constant node. No new nodes
149  are produced.]
150 
151  SideEffects [None]
152 
153  SeeAlso [Cudd_bddLeq Cudd_addEvalConst]
154 
155 ******************************************************************************/
156 DdNode *
158  DdManager * dd,
159  DdNode * f,
160  int * inputs)
161 {
162  int comple;
163  DdNode *ptr;
164 
165  comple = Cudd_IsComplement(f);
166  ptr = Cudd_Regular(f);
167 
168  while (!cuddIsConstant(ptr)) {
169  if (inputs[ptr->index] == 1) {
170  ptr = cuddT(ptr);
171  } else {
172  comple ^= Cudd_IsComplement(cuddE(ptr));
173  ptr = Cudd_Regular(cuddE(ptr));
174  }
175  }
176  return(Cudd_NotCond(ptr,comple));
177 
178 } /* end of Cudd_Eval */
179 
180 
181 /**Function********************************************************************
182 
183  Synopsis [Finds a shortest path in a DD.]
184 
185  Description [Finds a shortest path in a DD. f is the DD we want to
186  get the shortest path for; weight\[i\] is the weight of the THEN arc
187  coming from the node whose index is i. If weight is NULL, then unit
188  weights are assumed for all THEN arcs. All ELSE arcs have 0 weight.
189  If non-NULL, both weight and support should point to arrays with at
190  least as many entries as there are variables in the manager.
191  Returns the shortest path as the BDD of a cube.]
192 
193  SideEffects [support contains on return the true support of f.
194  If support is NULL on entry, then Cudd_ShortestPath does not compute
195  the true support info. length contains the length of the path.]
196 
197  SeeAlso [Cudd_ShortestLength Cudd_LargestCube]
198 
199 ******************************************************************************/
200 DdNode *
202  DdManager * manager,
203  DdNode * f,
204  int * weight,
205  int * support,
206  int * length)
207 {
208  DdNode *F;
209  st__table *visited;
210  DdNode *sol;
211  cuddPathPair *rootPair;
212  int complement, cost;
213  int i;
214 
215  one = DD_ONE(manager);
216  zero = DD_ZERO(manager);
217 
218  /* Initialize support. Support does not depend on variable order.
219  ** Hence, it does not need to be reinitialized if reordering occurs.
220  */
221  if (support) {
222  for (i = 0; i < manager->size; i++) {
223  support[i] = 0;
224  }
225  }
226 
227  if (f == Cudd_Not(one) || f == zero) {
228  *length = DD_BIGGY;
229  return(Cudd_Not(one));
230  }
231  /* From this point on, a path exists. */
232 
233  do {
234  manager->reordered = 0;
235 
236  /* Initialize visited table. */
238 
239  /* Now get the length of the shortest path(s) from f to 1. */
240  (void) getShortest(f, weight, support, visited);
241 
242  complement = Cudd_IsComplement(f);
243 
244  F = Cudd_Regular(f);
245 
246  if (! st__lookup(visited, (const char *)F, (char **)&rootPair)) return(NULL);
247 
248  if (complement) {
249  cost = rootPair->neg;
250  } else {
251  cost = rootPair->pos;
252  }
253 
254  /* Recover an actual shortest path. */
255  sol = getPath(manager,visited,f,weight,cost);
256 
257  st__foreach(visited, freePathPair, NULL);
258  st__free_table(visited);
259 
260  } while (manager->reordered == 1);
261 
262  *length = cost;
263  return(sol);
264 
265 } /* end of Cudd_ShortestPath */
266 
267 
268 /**Function********************************************************************
269 
270  Synopsis [Finds a largest cube in a DD.]
271 
272  Description [Finds a largest cube in a DD. f is the DD we want to
273  get the largest cube for. The problem is translated into the one of
274  finding a shortest path in f, when both THEN and ELSE arcs are assumed to
275  have unit length. This yields a largest cube in the disjoint cover
276  corresponding to the DD. Therefore, it is not necessarily the largest
277  implicant of f. Returns the largest cube as a BDD.]
278 
279  SideEffects [The number of literals of the cube is returned in length.]
280 
281  SeeAlso [Cudd_ShortestPath]
282 
283 ******************************************************************************/
284 DdNode *
286  DdManager * manager,
287  DdNode * f,
288  int * length)
289 {
290  register DdNode *F;
291  st__table *visited;
292  DdNode *sol;
293  cuddPathPair *rootPair;
294  int complement, cost;
295 
296  one = DD_ONE(manager);
297  zero = DD_ZERO(manager);
298 
299  if (f == Cudd_Not(one) || f == zero) {
300  *length = DD_BIGGY;
301  return(Cudd_Not(one));
302  }
303  /* From this point on, a path exists. */
304 
305  do {
306  manager->reordered = 0;
307 
308  /* Initialize visited table. */
310 
311  /* Now get the length of the shortest path(s) from f to 1. */
312  (void) getLargest(f, visited);
313 
314  complement = Cudd_IsComplement(f);
315 
316  F = Cudd_Regular(f);
317 
318  if (! st__lookup(visited, (const char *)F, (char **)&rootPair)) return(NULL);
319 
320  if (complement) {
321  cost = rootPair->neg;
322  } else {
323  cost = rootPair->pos;
324  }
325 
326  /* Recover an actual shortest path. */
327  sol = getCube(manager,visited,f,cost);
328 
329  st__foreach(visited, freePathPair, NULL);
330  st__free_table(visited);
331 
332  } while (manager->reordered == 1);
333 
334  *length = cost;
335  return(sol);
336 
337 } /* end of Cudd_LargestCube */
338 
339 
340 /**Function********************************************************************
341 
342  Synopsis [Find the length of the shortest path(s) in a DD.]
343 
344  Description [Find the length of the shortest path(s) in a DD. f is
345  the DD we want to get the shortest path for; weight\[i\] is the
346  weight of the THEN edge coming from the node whose index is i. All
347  ELSE edges have 0 weight. Returns the length of the shortest
348  path(s) if such a path is found; a large number if the function is
349  identically 0, and CUDD_OUT_OF_MEM in case of failure.]
350 
351  SideEffects [None]
352 
353  SeeAlso [Cudd_ShortestPath]
354 
355 ******************************************************************************/
356 int
358  DdManager * manager,
359  DdNode * f,
360  int * weight)
361 {
362  register DdNode *F;
363  st__table *visited;
364  cuddPathPair *my_pair;
365  int complement, cost;
366 
367  one = DD_ONE(manager);
368  zero = DD_ZERO(manager);
369 
370  if (f == Cudd_Not(one) || f == zero) {
371  return(DD_BIGGY);
372  }
373 
374  /* From this point on, a path exists. */
375  /* Initialize visited table and support. */
377 
378  /* Now get the length of the shortest path(s) from f to 1. */
379  (void) getShortest(f, weight, NULL, visited);
380 
381  complement = Cudd_IsComplement(f);
382 
383  F = Cudd_Regular(f);
384 
385  if (! st__lookup(visited, (const char *)F, (char **)&my_pair)) return(CUDD_OUT_OF_MEM);
386 
387  if (complement) {
388  cost = my_pair->neg;
389  } else {
390  cost = my_pair->pos;
391  }
392 
393  st__foreach(visited, freePathPair, NULL);
394  st__free_table(visited);
395 
396  return(cost);
397 
398 } /* end of Cudd_ShortestLength */
399 
400 
401 /**Function********************************************************************
402 
403  Synopsis [Determines whether a BDD is negative unate in a
404  variable.]
405 
406  Description [Determines whether the function represented by BDD f is
407  negative unate (monotonic decreasing) in variable i. Returns the
408  constant one is f is unate and the (logical) constant zero if it is not.
409  This function does not generate any new nodes.]
410 
411  SideEffects [None]
412 
413  SeeAlso [Cudd_Increasing]
414 
415 ******************************************************************************/
416 DdNode *
418  DdManager * dd,
419  DdNode * f,
420  int i)
421 {
422  unsigned int topf, level;
423  DdNode *F, *fv, *fvn, *res;
424  DD_CTFP cacheOp;
425 
426  statLine(dd);
427 #ifdef DD_DEBUG
428  assert(0 <= i && i < dd->size);
429 #endif
430 
431  F = Cudd_Regular(f);
432  topf = cuddI(dd,F->index);
433 
434  /* Check terminal case. If topf > i, f does not depend on var.
435  ** Therefore, f is unate in i.
436  */
437  level = (unsigned) dd->perm[i];
438  if (topf > level) {
439  return(DD_ONE(dd));
440  }
441 
442  /* From now on, f is not constant. */
443 
444  /* Check cache. */
445  cacheOp = (DD_CTFP) Cudd_Decreasing;
446  res = cuddCacheLookup2(dd,cacheOp,f,dd->vars[i]);
447  if (res != NULL) {
448  return(res);
449  }
450 
451  /* Compute cofactors. */
452  fv = cuddT(F); fvn = cuddE(F);
453  if (F != f) {
454  fv = Cudd_Not(fv);
455  fvn = Cudd_Not(fvn);
456  }
457 
458  if (topf == (unsigned) level) {
459  /* Special case: if fv is regular, fv(1,...,1) = 1;
460  ** If in addition fvn is complemented, fvn(1,...,1) = 0.
461  ** But then f(1,1,...,1) > f(0,1,...,1). Hence f is not
462  ** monotonic decreasing in i.
463  */
464  if (!Cudd_IsComplement(fv) && Cudd_IsComplement(fvn)) {
465  return(Cudd_Not(DD_ONE(dd)));
466  }
467  res = Cudd_bddLeq(dd,fv,fvn) ? DD_ONE(dd) : Cudd_Not(DD_ONE(dd));
468  } else {
469  res = Cudd_Decreasing(dd,fv,i);
470  if (res == DD_ONE(dd)) {
471  res = Cudd_Decreasing(dd,fvn,i);
472  }
473  }
474 
475  cuddCacheInsert2(dd,cacheOp,f,dd->vars[i],res);
476  return(res);
477 
478 } /* end of Cudd_Decreasing */
479 
480 
481 /**Function********************************************************************
482 
483  Synopsis [Determines whether a BDD is positive unate in a
484  variable.]
485 
486  Description [Determines whether the function represented by BDD f is
487  positive unate (monotonic increasing) in variable i. It is based on
488  Cudd_Decreasing and the fact that f is monotonic increasing in i if
489  and only if its complement is monotonic decreasing in i.]
490 
491  SideEffects [None]
492 
493  SeeAlso [Cudd_Decreasing]
494 
495 ******************************************************************************/
496 DdNode *
498  DdManager * dd,
499  DdNode * f,
500  int i)
501 {
502  return(Cudd_Decreasing(dd,Cudd_Not(f),i));
503 
504 } /* end of Cudd_Increasing */
505 
506 
507 /**Function********************************************************************
508 
509  Synopsis [Tells whether F and G are identical wherever D is 0.]
510 
511  Description [Tells whether F and G are identical wherever D is 0. F
512  and G are either two ADDs or two BDDs. D is either a 0-1 ADD or a
513  BDD. The function returns 1 if F and G are equivalent, and 0
514  otherwise. No new nodes are created.]
515 
516  SideEffects [None]
517 
518  SeeAlso [Cudd_bddLeqUnless]
519 
520 ******************************************************************************/
521 int
523  DdManager * dd,
524  DdNode * F,
525  DdNode * G,
526  DdNode * D)
527 {
528  DdNode *tmp, *One, *Gr, *Dr;
529  DdNode *Fv, *Fvn, *Gv, *Gvn, *Dv, *Dvn;
530  int res;
531  unsigned int flevel, glevel, dlevel, top;
532 
533  One = DD_ONE(dd);
534 
535  statLine(dd);
536  /* Check terminal cases. */
537  if (D == One || F == G) return(1);
538  if (D == Cudd_Not(One) || D == DD_ZERO(dd) || F == Cudd_Not(G)) return(0);
539 
540  /* From now on, D is non-constant. */
541 
542  /* Normalize call to increase cache efficiency. */
543  if (F > G) {
544  tmp = F;
545  F = G;
546  G = tmp;
547  }
548  if (Cudd_IsComplement(F)) {
549  F = Cudd_Not(F);
550  G = Cudd_Not(G);
551  }
552 
553  /* From now on, F is regular. */
554 
555  /* Check cache. */
556  tmp = cuddCacheLookup(dd,DD_EQUIV_DC_TAG,F,G,D);
557  if (tmp != NULL) return(tmp == One);
558 
559  /* Find splitting variable. */
560  flevel = cuddI(dd,F->index);
561  Gr = Cudd_Regular(G);
562  glevel = cuddI(dd,Gr->index);
563  top = ddMin(flevel,glevel);
564  Dr = Cudd_Regular(D);
565  dlevel = dd->perm[Dr->index];
566  top = ddMin(top,dlevel);
567 
568  /* Compute cofactors. */
569  if (top == flevel) {
570  Fv = cuddT(F);
571  Fvn = cuddE(F);
572  } else {
573  Fv = Fvn = F;
574  }
575  if (top == glevel) {
576  Gv = cuddT(Gr);
577  Gvn = cuddE(Gr);
578  if (G != Gr) {
579  Gv = Cudd_Not(Gv);
580  Gvn = Cudd_Not(Gvn);
581  }
582  } else {
583  Gv = Gvn = G;
584  }
585  if (top == dlevel) {
586  Dv = cuddT(Dr);
587  Dvn = cuddE(Dr);
588  if (D != Dr) {
589  Dv = Cudd_Not(Dv);
590  Dvn = Cudd_Not(Dvn);
591  }
592  } else {
593  Dv = Dvn = D;
594  }
595 
596  /* Solve recursively. */
597  res = Cudd_EquivDC(dd,Fv,Gv,Dv);
598  if (res != 0) {
599  res = Cudd_EquivDC(dd,Fvn,Gvn,Dvn);
600  }
601  cuddCacheInsert(dd,DD_EQUIV_DC_TAG,F,G,D,(res) ? One : Cudd_Not(One));
602 
603  return(res);
604 
605 } /* end of Cudd_EquivDC */
606 
607 
608 /**Function********************************************************************
609 
610  Synopsis [Tells whether f is less than of equal to G unless D is 1.]
611 
612  Description [Tells whether f is less than of equal to G unless D is
613  1. f, g, and D are BDDs. The function returns 1 if f is less than
614  of equal to G, and 0 otherwise. No new nodes are created.]
615 
616  SideEffects [None]
617 
618  SeeAlso [Cudd_EquivDC Cudd_bddLeq Cudd_bddIteConstant]
619 
620 ******************************************************************************/
621 int
623  DdManager *dd,
624  DdNode *f,
625  DdNode *g,
626  DdNode *D)
627 {
628  DdNode *tmp, *One, *F, *G;
629  DdNode *Ft, *Fe, *Gt, *Ge, *Dt, *De;
630  int res;
631  unsigned int flevel, glevel, dlevel, top;
632 
633  statLine(dd);
634 
635  One = DD_ONE(dd);
636 
637  /* Check terminal cases. */
638  if (f == g || g == One || f == Cudd_Not(One) || D == One ||
639  D == f || D == Cudd_Not(g)) return(1);
640  /* Check for two-operand cases. */
641  if (D == Cudd_Not(One) || D == g || D == Cudd_Not(f))
642  return(Cudd_bddLeq(dd,f,g));
643  if (g == Cudd_Not(One) || g == Cudd_Not(f)) return(Cudd_bddLeq(dd,f,D));
644  if (f == One) return(Cudd_bddLeq(dd,Cudd_Not(g),D));
645 
646  /* From now on, f, g, and D are non-constant, distinct, and
647  ** non-complementary. */
648 
649  /* Normalize call to increase cache efficiency. We rely on the
650  ** fact that f <= g unless D is equivalent to not(g) <= not(f)
651  ** unless D and to f <= D unless g. We make sure that D is
652  ** regular, and that at most one of f and g is complemented. We also
653  ** ensure that when two operands can be swapped, the one with the
654  ** lowest address comes first. */
655 
656  if (Cudd_IsComplement(D)) {
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). If D(1,...,1) = 0, return 0.
660  */
661  if (!Cudd_IsComplement(f)) return(0);
662  /* !g <= D unless !f or !D <= g unless !f */
663  tmp = D;
664  D = Cudd_Not(f);
665  if (g < tmp) {
666  f = Cudd_Not(g);
667  g = tmp;
668  } else {
669  f = Cudd_Not(tmp);
670  }
671  } else {
672  if (Cudd_IsComplement(f)) {
673  /* !D <= !f unless g or !D <= g unless !f */
674  tmp = f;
675  f = Cudd_Not(D);
676  if (tmp < g) {
677  D = g;
678  g = Cudd_Not(tmp);
679  } else {
680  D = Cudd_Not(tmp);
681  }
682  } else {
683  /* f <= D unless g or !D <= !f unless g */
684  tmp = D;
685  D = g;
686  if (tmp < f) {
687  g = Cudd_Not(f);
688  f = Cudd_Not(tmp);
689  } else {
690  g = tmp;
691  }
692  }
693  }
694  } else {
695  if (Cudd_IsComplement(g)) {
696  if (Cudd_IsComplement(f)) {
697  /* !g <= !f unless D or !g <= D unless !f */
698  tmp = f;
699  f = Cudd_Not(g);
700  if (D < tmp) {
701  g = D;
702  D = Cudd_Not(tmp);
703  } else {
704  g = Cudd_Not(tmp);
705  }
706  } else {
707  /* f <= g unless D or !g <= !f unless D */
708  if (g < f) {
709  tmp = g;
710  g = Cudd_Not(f);
711  f = Cudd_Not(tmp);
712  }
713  }
714  } else {
715  /* f <= g unless D or f <= D unless g */
716  if (D < g) {
717  tmp = D;
718  D = g;
719  g = tmp;
720  }
721  }
722  }
723 
724  /* From now on, D is regular. */
725 
726  /* Check cache. */
727  tmp = cuddCacheLookup(dd,DD_BDD_LEQ_UNLESS_TAG,f,g,D);
728  if (tmp != NULL) return(tmp == One);
729 
730  /* Find splitting variable. */
731  F = Cudd_Regular(f);
732  flevel = dd->perm[F->index];
733  G = Cudd_Regular(g);
734  glevel = dd->perm[G->index];
735  top = ddMin(flevel,glevel);
736  dlevel = dd->perm[D->index];
737  top = ddMin(top,dlevel);
738 
739  /* Compute cofactors. */
740  if (top == flevel) {
741  Ft = cuddT(F);
742  Fe = cuddE(F);
743  if (F != f) {
744  Ft = Cudd_Not(Ft);
745  Fe = Cudd_Not(Fe);
746  }
747  } else {
748  Ft = Fe = f;
749  }
750  if (top == glevel) {
751  Gt = cuddT(G);
752  Ge = cuddE(G);
753  if (G != g) {
754  Gt = Cudd_Not(Gt);
755  Ge = Cudd_Not(Ge);
756  }
757  } else {
758  Gt = Ge = g;
759  }
760  if (top == dlevel) {
761  Dt = cuddT(D);
762  De = cuddE(D);
763  } else {
764  Dt = De = D;
765  }
766 
767  /* Solve recursively. */
768  res = Cudd_bddLeqUnless(dd,Ft,Gt,Dt);
769  if (res != 0) {
770  res = Cudd_bddLeqUnless(dd,Fe,Ge,De);
771  }
773 
774  return(res);
775 
776 } /* end of Cudd_bddLeqUnless */
777 
778 
779 /**Function********************************************************************
780 
781  Synopsis [Compares two ADDs for equality within tolerance.]
782 
783  Description [Compares two ADDs for equality within tolerance. Two
784  ADDs are reported to be equal if the maximum difference between them
785  (the sup norm of their difference) is less than or equal to the
786  tolerance parameter. Returns 1 if the two ADDs are equal (within
787  tolerance); 0 otherwise. If parameter <code>pr</code> is positive
788  the first failure is reported to the standard output.]
789 
790  SideEffects [None]
791 
792  SeeAlso []
793 
794 ******************************************************************************/
795 int
797  DdManager * dd /* manager */,
798  DdNode * f /* first ADD */,
799  DdNode * g /* second ADD */,
800  CUDD_VALUE_TYPE tolerance /* maximum allowed difference */,
801  int pr /* verbosity level */)
802 {
803  DdNode *fv, *fvn, *gv, *gvn, *r;
804  unsigned int topf, topg;
805 
806  statLine(dd);
807  /* Check terminal cases. */
808  if (f == g) return(1);
809  if (Cudd_IsConstant(f) && Cudd_IsConstant(g)) {
810  if (ddEqualVal(cuddV(f),cuddV(g),tolerance)) {
811  return(1);
812  } else {
813  if (pr>0) {
814  (void) fprintf(dd->out,"Offending nodes:\n");
815  (void) fprintf(dd->out,
816  "f: address = %p\t value = %40.30f\n",
817  (void *) f, cuddV(f));
818  (void) fprintf(dd->out,
819  "g: address = %p\t value = %40.30f\n",
820  (void *) g, cuddV(g));
821  }
822  return(0);
823  }
824  }
825 
826  /* We only insert the result in the cache if the comparison is
827  ** successful. Therefore, if we hit we return 1. */
829  if (r != NULL) {
830  return(1);
831  }
832 
833  /* Compute the cofactors and solve the recursive subproblems. */
834  topf = cuddI(dd,f->index);
835  topg = cuddI(dd,g->index);
836 
837  if (topf <= topg) {fv = cuddT(f); fvn = cuddE(f);} else {fv = fvn = f;}
838  if (topg <= topf) {gv = cuddT(g); gvn = cuddE(g);} else {gv = gvn = g;}
839 
840  if (!Cudd_EqualSupNorm(dd,fv,gv,tolerance,pr)) return(0);
841  if (!Cudd_EqualSupNorm(dd,fvn,gvn,tolerance,pr)) return(0);
842 
843  cuddCacheInsert2(dd,(DD_CTFP)Cudd_EqualSupNorm,f,g,DD_ONE(dd));
844 
845  return(1);
846 
847 } /* end of Cudd_EqualSupNorm */
848 
849 
850 /**Function********************************************************************
851 
852  Synopsis [Expands cube to a prime implicant of f.]
853 
854  Description [Expands cube to a prime implicant of f. Returns the prime
855  if successful; NULL otherwise. In particular, NULL is returned if cube
856  is not a real cube or is not an implicant of f.]
857 
858  SideEffects [None]
859 
860  SeeAlso []
861 
862 ******************************************************************************/
863 DdNode *
865  DdManager *dd /* manager */,
866  DdNode *cube /* cube to be expanded */,
867  DdNode *f /* function of which the cube is to be made a prime */)
868 {
869  DdNode *res;
870 
871  if (!Cudd_bddLeq(dd,cube,f)) return(NULL);
872 
873  do {
874  dd->reordered = 0;
875  res = cuddBddMakePrime(dd,cube,f);
876  } while (dd->reordered == 1);
877  return(res);
878 
879 } /* end of Cudd_bddMakePrime */
880 
881 
882 /*---------------------------------------------------------------------------*/
883 /* Definition of internal functions */
884 /*---------------------------------------------------------------------------*/
885 
886 
887 /**Function********************************************************************
888 
889  Synopsis [Performs the recursive step of Cudd_bddMakePrime.]
890 
891  Description [Performs the recursive step of Cudd_bddMakePrime.
892  Returns the prime if successful; NULL otherwise.]
893 
894  SideEffects [None]
895 
896  SeeAlso []
897 
898 ******************************************************************************/
899 DdNode *
901  DdManager *dd /* manager */,
902  DdNode *cube /* cube to be expanded */,
903  DdNode *f /* function of which the cube is to be made a prime */)
904 {
905  DdNode *scan;
906  DdNode *t, *e;
907  DdNode *res = cube;
908  DdNode *zero = Cudd_Not(DD_ONE(dd));
909 
910  Cudd_Ref(res);
911  scan = cube;
912  while (!Cudd_IsConstant(scan)) {
913  DdNode *reg = Cudd_Regular(scan);
914  DdNode *var = dd->vars[reg->index];
915  DdNode *expanded = Cudd_bddExistAbstract(dd,res,var);
916  if (expanded == NULL) {
917  return(NULL);
918  }
919  Cudd_Ref(expanded);
920  if (Cudd_bddLeq(dd,expanded,f)) {
921  Cudd_RecursiveDeref(dd,res);
922  res = expanded;
923  } else {
924  Cudd_RecursiveDeref(dd,expanded);
925  }
926  cuddGetBranches(scan,&t,&e);
927  if (t == zero) {
928  scan = e;
929  } else if (e == zero) {
930  scan = t;
931  } else {
932  Cudd_RecursiveDeref(dd,res);
933  return(NULL); /* cube is not a cube */
934  }
935  }
936 
937  if (scan == DD_ONE(dd)) {
938  Cudd_Deref(res);
939  return(res);
940  } else {
941  Cudd_RecursiveDeref(dd,res);
942  return(NULL);
943  }
944 
945 } /* end of cuddBddMakePrime */
946 
947 
948 /*---------------------------------------------------------------------------*/
949 /* Definition of static functions */
950 /*---------------------------------------------------------------------------*/
951 
952 
953 /**Function********************************************************************
954 
955  Synopsis [Frees the entries of the visited symbol table.]
956 
957  Description [Frees the entries of the visited symbol table. Returns
958  st__CONTINUE.]
959 
960  SideEffects [None]
961 
962 ******************************************************************************/
963 static enum st__retval
965  char * key,
966  char * value,
967  char * arg)
968 {
969  cuddPathPair *pair;
970 
971  pair = (cuddPathPair *) value;
972  ABC_FREE(pair);
973  return( st__CONTINUE);
974 
975 } /* end of freePathPair */
976 
977 
978 /**Function********************************************************************
979 
980  Synopsis [Finds the length of the shortest path(s) in a DD.]
981 
982  Description [Finds the length of the shortest path(s) in a DD.
983  Uses a local symbol table to store the lengths for each
984  node. Only the lengths for the regular nodes are entered in the table,
985  because those for the complement nodes are simply obtained by swapping
986  the two lenghts.
987  Returns a pair of lengths: the length of the shortest path to 1;
988  and the length of the shortest path to 0. This is done so as to take
989  complement arcs into account.]
990 
991  SideEffects [Accumulates the support of the DD in support.]
992 
993  SeeAlso []
994 
995 ******************************************************************************/
996 static cuddPathPair
998  DdNode * root,
999  int * cost,
1000  int * support,
1001  st__table * visited)
1002 {
1003  cuddPathPair *my_pair, res_pair, pair_T, pair_E;
1004  DdNode *my_root, *T, *E;
1005  int weight;
1006 
1007  my_root = Cudd_Regular(root);
1008 
1009  if ( st__lookup(visited, (const char *)my_root, (char **)&my_pair)) {
1010  if (Cudd_IsComplement(root)) {
1011  res_pair.pos = my_pair->neg;
1012  res_pair.neg = my_pair->pos;
1013  } else {
1014  res_pair.pos = my_pair->pos;
1015  res_pair.neg = my_pair->neg;
1016  }
1017  return(res_pair);
1018  }
1019 
1020  /* In the case of a BDD the following test is equivalent to
1021  ** testing whether the BDD is the constant 1. This formulation,
1022  ** however, works for ADDs as well, by assuming the usual
1023  ** dichotomy of 0 and != 0.
1024  */
1025  if (cuddIsConstant(my_root)) {
1026  if (my_root != zero) {
1027  res_pair.pos = 0;
1028  res_pair.neg = DD_BIGGY;
1029  } else {
1030  res_pair.pos = DD_BIGGY;
1031  res_pair.neg = 0;
1032  }
1033  } else {
1034  T = cuddT(my_root);
1035  E = cuddE(my_root);
1036 
1037  pair_T = getShortest(T, cost, support, visited);
1038  pair_E = getShortest(E, cost, support, visited);
1039  weight = WEIGHT(cost, my_root->index);
1040  res_pair.pos = ddMin(pair_T.pos+weight, pair_E.pos);
1041  res_pair.neg = ddMin(pair_T.neg+weight, pair_E.neg);
1042 
1043  /* Update support. */
1044  if (support != NULL) {
1045  support[my_root->index] = 1;
1046  }
1047  }
1048 
1049  my_pair = ABC_ALLOC(cuddPathPair, 1);
1050  if (my_pair == NULL) {
1051  if (Cudd_IsComplement(root)) {
1052  int tmp = res_pair.pos;
1053  res_pair.pos = res_pair.neg;
1054  res_pair.neg = tmp;
1055  }
1056  return(res_pair);
1057  }
1058  my_pair->pos = res_pair.pos;
1059  my_pair->neg = res_pair.neg;
1060 
1061  st__insert(visited, (char *)my_root, (char *)my_pair);
1062  if (Cudd_IsComplement(root)) {
1063  res_pair.pos = my_pair->neg;
1064  res_pair.neg = my_pair->pos;
1065  } else {
1066  res_pair.pos = my_pair->pos;
1067  res_pair.neg = my_pair->neg;
1068  }
1069  return(res_pair);
1070 
1071 } /* end of getShortest */
1072 
1073 
1074 /**Function********************************************************************
1075 
1076  Synopsis [Build a BDD for a shortest path of f.]
1077 
1078  Description [Build a BDD for a shortest path of f.
1079  Given the minimum length from the root, and the minimum
1080  lengths for each node (in visited), apply triangulation at each node.
1081  Of the two children of each node on a shortest path, at least one is
1082  on a shortest path. In case of ties the procedure chooses the THEN
1083  children.
1084  Returns a pointer to the cube BDD representing the path if
1085  successful; NULL otherwise.]
1086 
1087  SideEffects [None]
1088 
1089  SeeAlso []
1090 
1091 ******************************************************************************/
1092 static DdNode *
1094  DdManager * manager,
1095  st__table * visited,
1096  DdNode * f,
1097  int * weight,
1098  int cost)
1099 {
1100  DdNode *sol, *tmp;
1101  DdNode *my_dd, *T, *E;
1102  cuddPathPair *T_pair, *E_pair;
1103  int Tcost, Ecost;
1104  int complement;
1105 
1106  my_dd = Cudd_Regular(f);
1107  complement = Cudd_IsComplement(f);
1108 
1109  sol = one;
1110  cuddRef(sol);
1111 
1112  while (!cuddIsConstant(my_dd)) {
1113  Tcost = cost - WEIGHT(weight, my_dd->index);
1114  Ecost = cost;
1115 
1116  T = cuddT(my_dd);
1117  E = cuddE(my_dd);
1118 
1119  if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);}
1120 
1121  st__lookup(visited, (const char *)Cudd_Regular(T), (char **)&T_pair);
1122  if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) ||
1123  (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) {
1124  tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol);
1125  if (tmp == NULL) {
1126  Cudd_RecursiveDeref(manager,sol);
1127  return(NULL);
1128  }
1129  cuddRef(tmp);
1130  Cudd_RecursiveDeref(manager,sol);
1131  sol = tmp;
1132 
1133  complement = Cudd_IsComplement(T);
1134  my_dd = Cudd_Regular(T);
1135  cost = Tcost;
1136  continue;
1137  }
1138  st__lookup(visited, (const char *)Cudd_Regular(E), (char **)&E_pair);
1139  if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) ||
1140  (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) {
1141  tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol);
1142  if (tmp == NULL) {
1143  Cudd_RecursiveDeref(manager,sol);
1144  return(NULL);
1145  }
1146  cuddRef(tmp);
1147  Cudd_RecursiveDeref(manager,sol);
1148  sol = tmp;
1149  complement = Cudd_IsComplement(E);
1150  my_dd = Cudd_Regular(E);
1151  cost = Ecost;
1152  continue;
1153  }
1154  (void) fprintf(manager->err,"We shouldn't be here!!\n");
1155  manager->errorCode = CUDD_INTERNAL_ERROR;
1156  return(NULL);
1157  }
1158 
1159  cuddDeref(sol);
1160  return(sol);
1161 
1162 } /* end of getPath */
1163 
1164 
1165 /**Function********************************************************************
1166 
1167  Synopsis [Finds the size of the largest cube(s) in a DD.]
1168 
1169  Description [Finds the size of the largest cube(s) in a DD.
1170  This problem is translated into finding the shortest paths from a node
1171  when both THEN and ELSE arcs have unit lengths.
1172  Uses a local symbol table to store the lengths for each
1173  node. Only the lengths for the regular nodes are entered in the table,
1174  because those for the complement nodes are simply obtained by swapping
1175  the two lenghts.
1176  Returns a pair of lengths: the length of the shortest path to 1;
1177  and the length of the shortest path to 0. This is done so as to take
1178  complement arcs into account.]
1179 
1180  SideEffects [none]
1181 
1182  SeeAlso []
1183 
1184 ******************************************************************************/
1185 static cuddPathPair
1187  DdNode * root,
1188  st__table * visited)
1189 {
1190  cuddPathPair *my_pair, res_pair, pair_T, pair_E;
1191  DdNode *my_root, *T, *E;
1192 
1193  my_root = Cudd_Regular(root);
1194 
1195  if ( st__lookup(visited, (const char *)my_root, (char **)&my_pair)) {
1196  if (Cudd_IsComplement(root)) {
1197  res_pair.pos = my_pair->neg;
1198  res_pair.neg = my_pair->pos;
1199  } else {
1200  res_pair.pos = my_pair->pos;
1201  res_pair.neg = my_pair->neg;
1202  }
1203  return(res_pair);
1204  }
1205 
1206  /* In the case of a BDD the following test is equivalent to
1207  ** testing whether the BDD is the constant 1. This formulation,
1208  ** however, works for ADDs as well, by assuming the usual
1209  ** dichotomy of 0 and != 0.
1210  */
1211  if (cuddIsConstant(my_root)) {
1212  if (my_root != zero) {
1213  res_pair.pos = 0;
1214  res_pair.neg = DD_BIGGY;
1215  } else {
1216  res_pair.pos = DD_BIGGY;
1217  res_pair.neg = 0;
1218  }
1219  } else {
1220  T = cuddT(my_root);
1221  E = cuddE(my_root);
1222 
1223  pair_T = getLargest(T, visited);
1224  pair_E = getLargest(E, visited);
1225  res_pair.pos = ddMin(pair_T.pos, pair_E.pos) + 1;
1226  res_pair.neg = ddMin(pair_T.neg, pair_E.neg) + 1;
1227  }
1228 
1229  my_pair = ABC_ALLOC(cuddPathPair, 1);
1230  if (my_pair == NULL) { /* simply do not cache this result */
1231  if (Cudd_IsComplement(root)) {
1232  int tmp = res_pair.pos;
1233  res_pair.pos = res_pair.neg;
1234  res_pair.neg = tmp;
1235  }
1236  return(res_pair);
1237  }
1238  my_pair->pos = res_pair.pos;
1239  my_pair->neg = res_pair.neg;
1240 
1241  /* Caching may fail without affecting correctness. */
1242  st__insert(visited, (char *)my_root, (char *)my_pair);
1243  if (Cudd_IsComplement(root)) {
1244  res_pair.pos = my_pair->neg;
1245  res_pair.neg = my_pair->pos;
1246  } else {
1247  res_pair.pos = my_pair->pos;
1248  res_pair.neg = my_pair->neg;
1249  }
1250  return(res_pair);
1251 
1252 } /* end of getLargest */
1253 
1254 
1255 /**Function********************************************************************
1256 
1257  Synopsis [Build a BDD for a largest cube of f.]
1258 
1259  Description [Build a BDD for a largest cube of f.
1260  Given the minimum length from the root, and the minimum
1261  lengths for each node (in visited), apply triangulation at each node.
1262  Of the two children of each node on a shortest path, at least one is
1263  on a shortest path. In case of ties the procedure chooses the THEN
1264  children.
1265  Returns a pointer to the cube BDD representing the path if
1266  successful; NULL otherwise.]
1267 
1268  SideEffects [None]
1269 
1270  SeeAlso []
1271 
1272 ******************************************************************************/
1273 static DdNode *
1275  DdManager * manager,
1276  st__table * visited,
1277  DdNode * f,
1278  int cost)
1279 {
1280  DdNode *sol, *tmp;
1281  DdNode *my_dd, *T, *E;
1282  cuddPathPair *T_pair, *E_pair;
1283  int Tcost, Ecost;
1284  int complement;
1285 
1286  my_dd = Cudd_Regular(f);
1287  complement = Cudd_IsComplement(f);
1288 
1289  sol = one;
1290  cuddRef(sol);
1291 
1292  while (!cuddIsConstant(my_dd)) {
1293  Tcost = cost - 1;
1294  Ecost = cost - 1;
1295 
1296  T = cuddT(my_dd);
1297  E = cuddE(my_dd);
1298 
1299  if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);}
1300 
1301  if (! st__lookup(visited, (const char *)Cudd_Regular(T), (char **)&T_pair)) return(NULL);
1302  if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) ||
1303  (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) {
1304  tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol);
1305  if (tmp == NULL) {
1306  Cudd_RecursiveDeref(manager,sol);
1307  return(NULL);
1308  }
1309  cuddRef(tmp);
1310  Cudd_RecursiveDeref(manager,sol);
1311  sol = tmp;
1312 
1313  complement = Cudd_IsComplement(T);
1314  my_dd = Cudd_Regular(T);
1315  cost = Tcost;
1316  continue;
1317  }
1318  if (! st__lookup(visited, (const char *)Cudd_Regular(E), (char **)&E_pair)) return(NULL);
1319  if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) ||
1320  (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) {
1321  tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol);
1322  if (tmp == NULL) {
1323  Cudd_RecursiveDeref(manager,sol);
1324  return(NULL);
1325  }
1326  cuddRef(tmp);
1327  Cudd_RecursiveDeref(manager,sol);
1328  sol = tmp;
1329  complement = Cudd_IsComplement(E);
1330  my_dd = Cudd_Regular(E);
1331  cost = Ecost;
1332  continue;
1333  }
1334  (void) fprintf(manager->err,"We shouldn't be here!\n");
1335  manager->errorCode = CUDD_INTERNAL_ERROR;
1336  return(NULL);
1337  }
1338 
1339  cuddDeref(sol);
1340  return(sol);
1341 
1342 } /* end of getCube */
1343 
1344 
1346 
static char rcsid[] DD_UNUSED
Definition: cuddSat.c:103
void st__free_table(st__table *table)
Definition: st.c:81
#define cuddRef(n)
Definition: cuddInt.h:584
DdNode * Cudd_LargestCube(DdManager *manager, DdNode *f, int *length)
Definition: cuddSat.c:285
#define CUDD_OUT_OF_MEM
Definition: cudd.h:95
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
static DdNode * getPath(DdManager *manager, st__table *visited, DdNode *f, int *weight, int cost)
Definition: cuddSat.c:1093
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
int st__insert(st__table *table, const char *key, char *value)
Definition: st.c:171
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:438
static enum st__retval freePathPair(char *key, char *value, char *arg)
Definition: cuddSat.c:964
int size
Definition: cuddInt.h:361
int var(Lit p)
Definition: SolverTypes.h:62
int Cudd_EquivDC(DdManager *dd, DdNode *F, DdNode *G, DdNode *D)
Definition: cuddSat.c:522
#define Cudd_IsConstant(node)
Definition: cudd.h:352
#define Cudd_Regular(node)
Definition: cudd.h:397
DdNode * Cudd_bddExistAbstract(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:130
DdNode * Cudd_Eval(DdManager *dd, DdNode *f, int *inputs)
Definition: cuddSat.c:157
int Cudd_EqualSupNorm(DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE tolerance, int pr)
Definition: cuddSat.c:796
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:222
int st__ptrcmp(const char *, const char *)
Definition: st.c:480
FILE * err
Definition: cuddInt.h:442
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:321
void cuddGetBranches(DdNode *g, DdNode **g1, DdNode **g0)
Definition: cuddCof.c:162
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
pcover complement(pcube *T)
Definition: compl.c:49
DdNode * Cudd_ShortestPath(DdManager *manager, DdNode *f, int *weight, int *support, int *length)
Definition: cuddSat.c:201
#define statLine(dd)
Definition: cuddInt.h:1037
#define cuddV(node)
Definition: cuddInt.h:668
DdNode * cuddBddMakePrime(DdManager *dd, DdNode *cube, DdNode *f)
Definition: cuddSat.c:900
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
st__retval
Definition: st.h:73
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition: st.c:72
int reordered
Definition: cuddInt.h:409
static DdNode * one
Definition: cuddSat.c:106
#define Cudd_IsComplement(node)
Definition: cudd.h:425
FILE * out
Definition: cuddInt.h:441
Definition: st.h:52
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
#define cuddIsConstant(node)
Definition: cuddInt.h:620
if(last==0)
Definition: sparse_int.h:34
DdNode * Cudd_Increasing(DdManager *dd, DdNode *f, int i)
Definition: cuddSat.c:497
static int size
Definition: cuddSign.c:86
#define ddMin(x, y)
Definition: cuddInt.h:818
int st__foreach(st__table *table, enum st__retval(*func)(char *, char *, char *), char *arg)
Definition: st.c:421
#define cuddT(node)
Definition: cuddInt.h:636
static DdNode * getCube(DdManager *manager, st__table *visited, DdNode *f, int cost)
Definition: cuddSat.c:1274
int Cudd_ShortestLength(DdManager *manager, DdNode *f, int *weight)
Definition: cuddSat.c:357
#define WEIGHT(weight, col)
Definition: cuddSat.c:112
#define DD_BDD_LEQ_UNLESS_TAG
Definition: cuddInt.h:188
#define ddEqualVal(x, y, e)
Definition: cuddInt.h:861
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
struct cuddPathPair cuddPathPair
#define cuddI(dd, index)
Definition: cuddInt.h:686
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:536
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
#define CUDD_VALUE_TYPE
Definition: cudd.h:94
#define DD_EQUIV_DC_TAG
Definition: cuddInt.h:182
DdNode * Cudd_Decreasing(DdManager *dd, DdNode *f, int i)
Definition: cuddSat.c:417
DdHalfWord index
Definition: cudd.h:279
DdNode * Cudd_bddMakePrime(DdManager *dd, DdNode *cube, DdNode *f)
Definition: cuddSat.c:864
#define ABC_FREE(obj)
Definition: abc_global.h:232
DdNode ** vars
Definition: cuddInt.h:390
enum keys key
static DdNode * zero
Definition: cuddSat.c:106
#define cuddE(node)
Definition: cuddInt.h:652
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
int value
static cuddPathPair getLargest(DdNode *root, st__table *visited)
Definition: cuddSat.c:1186
#define assert(ex)
Definition: util_old.h:213
#define DD_BIGGY
Definition: cuddSat.c:83
static cuddPathPair getShortest(DdNode *root, int *cost, int *support, st__table *visited)
Definition: cuddSat.c:997
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
#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
int Cudd_bddLeqUnless(DdManager *dd, DdNode *f, DdNode *g, DdNode *D)
Definition: cuddSat.c:622
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
int st__ptrhash(const char *, int)
Definition: st.c:468
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:369
#define DD_ZERO(dd)
Definition: cuddInt.h:927