abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddGenCof.c File Reference
#include "misc/util/util_hack.h"
#include "cuddInt.h"

Go to the source code of this file.

Data Structures

struct  MarkCacheKey
 

Macros

#define DD_LIC_DC   0
 
#define DD_LIC_1   1
 
#define DD_LIC_0   2
 
#define DD_LIC_NL   3
 

Typedefs

typedef struct MarkCacheKey MarkCacheKey
 

Functions

static int cuddBddConstrainDecomp (DdManager *dd, DdNode *f, DdNode **decomp)
 
static DdNodecuddBddCharToVect (DdManager *dd, DdNode *f, DdNode *x)
 
static int cuddBddLICMarkEdges (DdManager *dd, DdNode *f, DdNode *c, st__table *table, st__table *cache)
 
static DdNodecuddBddLICBuildResult (DdManager *dd, DdNode *f, st__table *cache, st__table *table)
 
static int MarkCacheHash (const char *ptr, int modulus)
 
static int MarkCacheCompare (const char *ptr1, const char *ptr2)
 
static enum st__retval MarkCacheCleanUp (char *key, char *value, char *arg)
 
static DdNodecuddBddSqueeze (DdManager *dd, DdNode *l, DdNode *u)
 
DdNodeCudd_bddConstrain (DdManager *dd, DdNode *f, DdNode *c)
 
DdNodeCudd_bddRestrict (DdManager *dd, DdNode *f, DdNode *c)
 
DdNodeCudd_bddNPAnd (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodeCudd_addConstrain (DdManager *dd, DdNode *f, DdNode *c)
 
DdNode ** Cudd_bddConstrainDecomp (DdManager *dd, DdNode *f)
 
DdNodeCudd_addRestrict (DdManager *dd, DdNode *f, DdNode *c)
 
DdNode ** Cudd_bddCharToVect (DdManager *dd, DdNode *f)
 
DdNodeCudd_bddLICompaction (DdManager *dd, DdNode *f, DdNode *c)
 
DdNodeCudd_bddSqueeze (DdManager *dd, DdNode *l, DdNode *u)
 
DdNodeCudd_bddMinimize (DdManager *dd, DdNode *f, DdNode *c)
 
DdNodeCudd_SubsetCompress (DdManager *dd, DdNode *f, int nvars, int threshold)
 
DdNodeCudd_SupersetCompress (DdManager *dd, DdNode *f, int nvars, int threshold)
 
DdNodecuddBddConstrainRecur (DdManager *dd, DdNode *f, DdNode *c)
 
DdNodecuddBddRestrictRecur (DdManager *dd, DdNode *f, DdNode *c)
 
DdNodecuddBddNPAndRecur (DdManager *manager, DdNode *f, DdNode *g)
 
DdNodecuddAddConstrainRecur (DdManager *dd, DdNode *f, DdNode *c)
 
DdNodecuddAddRestrictRecur (DdManager *dd, DdNode *f, DdNode *c)
 
DdNodecuddBddLICompaction (DdManager *dd, DdNode *f, DdNode *c)
 

Variables

static char rcsid[] DD_UNUSED = "$Id: cuddGenCof.c,v 1.38 2005/05/14 17:27:11 fabio Exp $"
 

Macro Definition Documentation

#define DD_LIC_0   2

Definition at line 95 of file cuddGenCof.c.

#define DD_LIC_1   1

Definition at line 94 of file cuddGenCof.c.

#define DD_LIC_DC   0

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

FileName [cuddGenCof.c]

PackageName [cudd]

Synopsis [Generalized cofactors for BDDs and ADDs.]

Description [External procedures included in this module:

Internal procedures included in this module:

Static procedures included in this module:

]

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-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 93 of file cuddGenCof.c.

#define DD_LIC_NL   3

Definition at line 96 of file cuddGenCof.c.

Typedef Documentation

typedef struct MarkCacheKey MarkCacheKey

Function Documentation

DdNode* Cudd_addConstrain ( DdManager dd,
DdNode f,
DdNode c 
)

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

Synopsis [Computes f constrain c for ADDs.]

Description [Computes f constrain c (f @ c), for f an ADD and c a 0-1 ADD. List of special cases:

  • F @ 0 = 0
  • F @ 1 = F
  • 0 @ c = 0
  • 1 @ c = 1
  • F @ F = 1

Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddConstrain]

Definition at line 336 of file cuddGenCof.c.

340 {
341  DdNode *res;
342 
343  do {
344  dd->reordered = 0;
345  res = cuddAddConstrainRecur(dd,f,c);
346  } while (dd->reordered == 1);
347  return(res);
348 
349 } /* end of Cudd_addConstrain */
Definition: cudd.h:278
int reordered
Definition: cuddInt.h:409
DdNode * cuddAddConstrainRecur(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:1203
DdNode* Cudd_addRestrict ( DdManager dd,
DdNode f,
DdNode c 
)

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

Synopsis [ADD restrict according to Coudert and Madre's algorithm (ICCAD90).]

Description [ADD restrict according to Coudert and Madre's algorithm (ICCAD90). Returns the restricted ADD if successful; otherwise NULL. If application of restrict results in an ADD larger than the input ADD, the input ADD is returned.]

SideEffects [None]

SeeAlso [Cudd_addConstrain Cudd_bddRestrict]

Definition at line 431 of file cuddGenCof.c.

435 {
436  DdNode *supp_f, *supp_c;
437  DdNode *res, *commonSupport;
438  int intersection;
439  int sizeF, sizeRes;
440 
441  /* Check if supports intersect. */
442  supp_f = Cudd_Support(dd, f);
443  if (supp_f == NULL) {
444  return(NULL);
445  }
446  cuddRef(supp_f);
447  supp_c = Cudd_Support(dd, c);
448  if (supp_c == NULL) {
449  Cudd_RecursiveDeref(dd,supp_f);
450  return(NULL);
451  }
452  cuddRef(supp_c);
453  commonSupport = Cudd_bddLiteralSetIntersection(dd, supp_f, supp_c);
454  if (commonSupport == NULL) {
455  Cudd_RecursiveDeref(dd,supp_f);
456  Cudd_RecursiveDeref(dd,supp_c);
457  return(NULL);
458  }
459  cuddRef(commonSupport);
460  Cudd_RecursiveDeref(dd,supp_f);
461  Cudd_RecursiveDeref(dd,supp_c);
462  intersection = commonSupport != DD_ONE(dd);
463  Cudd_RecursiveDeref(dd,commonSupport);
464 
465  if (intersection) {
466  do {
467  dd->reordered = 0;
468  res = cuddAddRestrictRecur(dd, f, c);
469  } while (dd->reordered == 1);
470  sizeF = Cudd_DagSize(f);
471  sizeRes = Cudd_DagSize(res);
472  if (sizeF <= sizeRes) {
473  cuddRef(res);
474  Cudd_RecursiveDeref(dd, res);
475  return(f);
476  } else {
477  return(res);
478  }
479  } else {
480  return(f);
481  }
482 
483 } /* end of Cudd_addRestrict */
#define cuddRef(n)
Definition: cuddInt.h:584
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
DdNode * Cudd_Support(DdManager *dd, DdNode *f)
Definition: cuddUtil.c:740
int reordered
Definition: cuddInt.h:409
DdNode * Cudd_bddLiteralSetIntersection(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddLiteral.c:118
DdNode * cuddAddRestrictRecur(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:1307
#define DD_ONE(dd)
Definition: cuddInt.h:911
int Cudd_DagSize(DdNode *node)
Definition: cuddUtil.c:442
DdNode** Cudd_bddCharToVect ( DdManager dd,
DdNode f 
)

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

Synopsis [Computes a vector whose image equals a non-zero function.]

Description [Computes a vector of BDDs whose image equals a non-zero function. The result depends on the variable order. The i-th component of the vector depends only on the first i variables in the order. Each BDD in the vector is not larger than the BDD of the given characteristic function. This function is based on the description of char-to-vect in "Verification of Sequential Machines Using Boolean Functional Vectors" by O. Coudert, C. Berthet and J. C. Madre. Returns a pointer to an array containing the result if successful; NULL otherwise. The size of the array equals the number of variables in the manager. The components of the solution have their reference counts already incremented (unlike the results of most other functions in the package).]

SideEffects [None]

SeeAlso [Cudd_bddConstrain]

Definition at line 510 of file cuddGenCof.c.

513 {
514  int i, j;
515  DdNode **vect;
516  DdNode *res = NULL;
517 
518  if (f == Cudd_Not(DD_ONE(dd))) return(NULL);
519 
520  vect = ABC_ALLOC(DdNode *, dd->size);
521  if (vect == NULL) {
523  return(NULL);
524  }
525 
526  do {
527  dd->reordered = 0;
528  for (i = 0; i < dd->size; i++) {
529  res = cuddBddCharToVect(dd,f,dd->vars[dd->invperm[i]]);
530  if (res == NULL) {
531  /* Clean up the vector array in case reordering took place. */
532  for (j = 0; j < i; j++) {
533  Cudd_IterDerefBdd(dd, vect[dd->invperm[j]]);
534  }
535  break;
536  }
537  cuddRef(res);
538  vect[dd->invperm[i]] = res;
539  }
540  } while (dd->reordered == 1);
541  if (res == NULL) {
542  ABC_FREE(vect);
543  return(NULL);
544  }
545  return(vect);
546 
547 } /* end of Cudd_bddCharToVect */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
#define cuddRef(n)
Definition: cuddInt.h:584
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
int size
Definition: cuddInt.h:361
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
static DdNode * cuddBddCharToVect(DdManager *dd, DdNode *f, DdNode *x)
Definition: cuddGenCof.c:1566
int reordered
Definition: cuddInt.h:409
#define ABC_FREE(obj)
Definition: abc_global.h:232
DdNode ** vars
Definition: cuddInt.h:390
int * invperm
Definition: cuddInt.h:388
#define DD_ONE(dd)
Definition: cuddInt.h:911
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
DdNode* Cudd_bddConstrain ( DdManager dd,
DdNode f,
DdNode c 
)

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

Synopsis [Computes f constrain c.]

Description [Computes f constrain c (f @ c). Uses a canonical form: (f' @ c) = ( f @ c)'. (Note: this is not true for c.) List of special cases:

  • f @ 0 = 0
  • f @ 1 = f
  • 0 @ c = 0
  • 1 @ c = 1
  • f @ f = 1
  • f @ f'= 0

Returns a pointer to the result if successful; NULL otherwise. Note that if F=(f1,...,fn) and reordering takes place while computing F @ c, then the image restriction property (Img(F,c) = Img(F @ c)) is lost.]

SideEffects [None]

SeeAlso [Cudd_bddRestrict Cudd_addConstrain]

Definition at line 180 of file cuddGenCof.c.

184 {
185  DdNode *res;
186 
187  do {
188  dd->reordered = 0;
189  res = cuddBddConstrainRecur(dd,f,c);
190  } while (dd->reordered == 1);
191  return(res);
192 
193 } /* end of Cudd_bddConstrain */
DdNode * cuddBddConstrainRecur(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:783
Definition: cudd.h:278
int reordered
Definition: cuddInt.h:409
DdNode** Cudd_bddConstrainDecomp ( DdManager dd,
DdNode f 
)

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

Synopsis [BDD conjunctive decomposition as in McMillan's CAV96 paper.]

Description [BDD conjunctive decomposition as in McMillan's CAV96 paper. The decomposition is canonical only for a given variable order. If canonicity is required, variable ordering must be disabled after the decomposition has been computed. Returns an array with one entry for each BDD variable in the manager if successful; otherwise NULL. The components of the solution have their reference counts already incremented (unlike the results of most other functions in the package.]

SideEffects [None]

SeeAlso [Cudd_bddConstrain Cudd_bddExistAbstract]

Definition at line 371 of file cuddGenCof.c.

374 {
375  DdNode **decomp;
376  int res;
377  int i;
378 
379  /* Create an initialize decomposition array. */
380  decomp = ABC_ALLOC(DdNode *,dd->size);
381  if (decomp == NULL) {
383  return(NULL);
384  }
385  for (i = 0; i < dd->size; i++) {
386  decomp[i] = NULL;
387  }
388  do {
389  dd->reordered = 0;
390  /* Clean up the decomposition array in case reordering took place. */
391  for (i = 0; i < dd->size; i++) {
392  if (decomp[i] != NULL) {
393  Cudd_IterDerefBdd(dd, decomp[i]);
394  decomp[i] = NULL;
395  }
396  }
397  res = cuddBddConstrainDecomp(dd,f,decomp);
398  } while (dd->reordered == 1);
399  if (res == 0) {
400  ABC_FREE(decomp);
401  return(NULL);
402  }
403  /* Missing components are constant ones. */
404  for (i = 0; i < dd->size; i++) {
405  if (decomp[i] == NULL) {
406  decomp[i] = DD_ONE(dd);
407  cuddRef(decomp[i]);
408  }
409  }
410  return(decomp);
411 
412 } /* end of Cudd_bddConstrainDecomp */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
#define cuddRef(n)
Definition: cuddInt.h:584
Definition: cudd.h:278
int size
Definition: cuddInt.h:361
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
static int cuddBddConstrainDecomp(DdManager *dd, DdNode *f, DdNode **decomp)
Definition: cuddGenCof.c:1504
int reordered
Definition: cuddInt.h:409
#define ABC_FREE(obj)
Definition: abc_global.h:232
#define DD_ONE(dd)
Definition: cuddInt.h:911
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
DdNode* Cudd_bddLICompaction ( DdManager dd,
DdNode f,
DdNode c 
)

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

Synopsis [Performs safe minimization of a BDD.]

Description [Performs safe minimization of a BDD. Given the BDD f of a function to be minimized and a BDD c representing the care set, Cudd_bddLICompaction produces the BDD of a function that agrees with f wherever c is 1. Safe minimization means that the size of the result is guaranteed not to exceed the size of f. This function is based on the DAC97 paper by Hong et al.. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddRestrict]

Definition at line 570 of file cuddGenCof.c.

574 {
575  DdNode *res;
576 
577  do {
578  dd->reordered = 0;
579  res = cuddBddLICompaction(dd,f,c);
580  } while (dd->reordered == 1);
581  return(res);
582 
583 } /* end of Cudd_bddLICompaction */
Definition: cudd.h:278
int reordered
Definition: cuddInt.h:409
DdNode * cuddBddLICompaction(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:1434
DdNode* Cudd_bddMinimize ( DdManager dd,
DdNode f,
DdNode c 
)

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

Synopsis [Finds a small BDD that agrees with f over c.]

Description [Finds a small BDD that agrees with f over c. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddRestrict Cudd_bddLICompaction Cudd_bddSqueeze]

Definition at line 653 of file cuddGenCof.c.

657 {
658  DdNode *cplus, *res;
659 
660  if (c == Cudd_Not(DD_ONE(dd))) return(c);
661  if (Cudd_IsConstant(f)) return(f);
662  if (f == c) return(DD_ONE(dd));
663  if (f == Cudd_Not(c)) return(Cudd_Not(DD_ONE(dd)));
664 
665  cplus = Cudd_RemapOverApprox(dd,c,0,0,1.0);
666  if (cplus == NULL) return(NULL);
667  cuddRef(cplus);
668  res = Cudd_bddLICompaction(dd,f,cplus);
669  if (res == NULL) {
670  Cudd_IterDerefBdd(dd,cplus);
671  return(NULL);
672  }
673  cuddRef(res);
674  Cudd_IterDerefBdd(dd,cplus);
675  cuddDeref(res);
676  return(res);
677 
678 } /* end of Cudd_bddMinimize */
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
DdNode * Cudd_bddLICompaction(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:570
#define Cudd_Not(node)
Definition: cudd.h:367
#define Cudd_IsConstant(node)
Definition: cudd.h:352
DdNode * Cudd_RemapOverApprox(DdManager *dd, DdNode *f, int numVars, int threshold, double quality)
Definition: cuddApprox.c:366
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode* Cudd_bddNPAnd ( DdManager dd,
DdNode f,
DdNode g 
)

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

Synopsis [Computes f non-polluting-and g.]

Description [Computes f non-polluting-and g. The non-polluting AND of f and g is a hybrid of AND and Restrict. From Restrict, this operation takes the idea of existentially quantifying the top variable of the second operand if it does not appear in the first. Therefore, the variables that appear in the result also appear in f. For the rest, the function behaves like AND. Since the two operands play different roles, non-polluting AND is not commutative.

Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddConstrain Cudd_bddRestrict]

Definition at line 299 of file cuddGenCof.c.

303 {
304  DdNode *res;
305 
306  do {
307  dd->reordered = 0;
308  res = cuddBddNPAndRecur(dd,f,g);
309  } while (dd->reordered == 1);
310  return(res);
311 
312 } /* end of Cudd_bddNPAnd */
Definition: cudd.h:278
int reordered
Definition: cuddInt.h:409
DdNode * cuddBddNPAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddGenCof.c:1062
DdNode* Cudd_bddRestrict ( DdManager dd,
DdNode f,
DdNode c 
)

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

Synopsis [BDD restrict according to Coudert and Madre's algorithm (ICCAD90).]

Description [BDD restrict according to Coudert and Madre's algorithm (ICCAD90). Returns the restricted BDD if successful; otherwise NULL. If application of restrict results in a BDD larger than the input BDD, the input BDD is returned.]

SideEffects [None]

SeeAlso [Cudd_bddConstrain Cudd_addRestrict]

Definition at line 212 of file cuddGenCof.c.

216 {
217  DdNode *suppF, *suppC, *commonSupport;
218  DdNode *cplus, *res;
219  int retval;
220  int sizeF, sizeRes;
221 
222  /* Check terminal cases here to avoid computing supports in trivial cases.
223  ** This also allows us notto check later for the case c == 0, in which
224  ** there is no common support. */
225  if (c == Cudd_Not(DD_ONE(dd))) return(Cudd_Not(DD_ONE(dd)));
226  if (Cudd_IsConstant(f)) return(f);
227  if (f == c) return(DD_ONE(dd));
228  if (f == Cudd_Not(c)) return(Cudd_Not(DD_ONE(dd)));
229 
230  /* Check if supports intersect. */
231  retval = Cudd_ClassifySupport(dd,f,c,&commonSupport,&suppF,&suppC);
232  if (retval == 0) {
233  return(NULL);
234  }
235  cuddRef(commonSupport); cuddRef(suppF); cuddRef(suppC);
236  Cudd_IterDerefBdd(dd,suppF);
237 
238  if (commonSupport == DD_ONE(dd)) {
239  Cudd_IterDerefBdd(dd,commonSupport);
240  Cudd_IterDerefBdd(dd,suppC);
241  return(f);
242  }
243  Cudd_IterDerefBdd(dd,commonSupport);
244 
245  /* Abstract from c the variables that do not appear in f. */
246  cplus = Cudd_bddExistAbstract(dd, c, suppC);
247  if (cplus == NULL) {
248  Cudd_IterDerefBdd(dd,suppC);
249  return(NULL);
250  }
251  cuddRef(cplus);
252  Cudd_IterDerefBdd(dd,suppC);
253 
254  do {
255  dd->reordered = 0;
256  res = cuddBddRestrictRecur(dd, f, cplus);
257  } while (dd->reordered == 1);
258  if (res == NULL) {
259  Cudd_IterDerefBdd(dd,cplus);
260  return(NULL);
261  }
262  cuddRef(res);
263  Cudd_IterDerefBdd(dd,cplus);
264  /* Make restric safe by returning the smaller of the input and the
265  ** result. */
266  sizeF = Cudd_DagSize(f);
267  sizeRes = Cudd_DagSize(res);
268  if (sizeF <= sizeRes) {
269  Cudd_IterDerefBdd(dd, res);
270  return(f);
271  } else {
272  cuddDeref(res);
273  return(res);
274  }
275 
276 } /* end of Cudd_bddRestrict */
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_IsConstant(node)
Definition: cudd.h:352
DdNode * Cudd_bddExistAbstract(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:130
int reordered
Definition: cuddInt.h:409
int Cudd_ClassifySupport(DdManager *dd, DdNode *f, DdNode *g, DdNode **common, DdNode **onlyF, DdNode **onlyG)
Definition: cuddUtil.c:1085
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * cuddBddRestrictRecur(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:912
int Cudd_DagSize(DdNode *node)
Definition: cuddUtil.c:442
DdNode* Cudd_bddSqueeze ( DdManager dd,
DdNode l,
DdNode u 
)

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

Synopsis [Finds a small BDD in a function interval.]

Description [Finds a small BDD in a function interval. Given BDDs l and u, representing the lower bound and upper bound of a function interval, Cudd_bddSqueeze produces the BDD of a function within the interval with a small BDD. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddRestrict Cudd_bddLICompaction]

Definition at line 602 of file cuddGenCof.c.

606 {
607  DdNode *res;
608  int sizeRes, sizeL, sizeU;
609 
610  do {
611  dd->reordered = 0;
612  res = cuddBddSqueeze(dd,l,u);
613  } while (dd->reordered == 1);
614  if (res == NULL) return(NULL);
615  /* We now compare the result with the bounds and return the smallest.
616  ** We first compare to u, so that in case l == 0 and u == 1, we return
617  ** 0 as in other minimization algorithms. */
618  sizeRes = Cudd_DagSize(res);
619  sizeU = Cudd_DagSize(u);
620  if (sizeU <= sizeRes) {
621  cuddRef(res);
622  Cudd_IterDerefBdd(dd,res);
623  res = u;
624  sizeRes = sizeU;
625  }
626  sizeL = Cudd_DagSize(l);
627  if (sizeL <= sizeRes) {
628  cuddRef(res);
629  Cudd_IterDerefBdd(dd,res);
630  res = l;
631  sizeRes = sizeL;
632  }
633  return(res);
634 
635 } /* end of Cudd_bddSqueeze */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
#define cuddRef(n)
Definition: cuddInt.h:584
Definition: cudd.h:278
static DdNode * cuddBddSqueeze(DdManager *dd, DdNode *l, DdNode *u)
Definition: cuddGenCof.c:1967
int reordered
Definition: cuddInt.h:409
int Cudd_DagSize(DdNode *node)
Definition: cuddUtil.c:442
DdNode* Cudd_SubsetCompress ( DdManager dd,
DdNode f,
int  nvars,
int  threshold 
)

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

Synopsis [Find a dense subset of BDD f.]

Description [Finds a dense subset of BDD f. Density is the ratio of number of minterms to number of nodes. Uses several techniques in series. It is more expensive than other subsetting procedures, but often produces better results. See Cudd_SubsetShortPaths for a description of the threshold and nvars parameters. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_SubsetRemap Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_bddSqueeze]

Definition at line 700 of file cuddGenCof.c.

705 {
706  DdNode *res, *tmp1, *tmp2;
707 
708  tmp1 = Cudd_SubsetShortPaths(dd, f, nvars, threshold, 0);
709  if (tmp1 == NULL) return(NULL);
710  cuddRef(tmp1);
711  tmp2 = Cudd_RemapUnderApprox(dd,tmp1,nvars,0,1.0);
712  if (tmp2 == NULL) {
713  Cudd_IterDerefBdd(dd,tmp1);
714  return(NULL);
715  }
716  cuddRef(tmp2);
717  Cudd_IterDerefBdd(dd,tmp1);
718  res = Cudd_bddSqueeze(dd,tmp2,f);
719  if (res == NULL) {
720  Cudd_IterDerefBdd(dd,tmp2);
721  return(NULL);
722  }
723  cuddRef(res);
724  Cudd_IterDerefBdd(dd,tmp2);
725  cuddDeref(res);
726  return(res);
727 
728 } /* end of Cudd_SubsetCompress */
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
DdNode * Cudd_bddSqueeze(DdManager *dd, DdNode *l, DdNode *u)
Definition: cuddGenCof.c:602
DdNode * Cudd_RemapUnderApprox(DdManager *dd, DdNode *f, int numVars, int threshold, double quality)
Definition: cuddApprox.c:320
DdNode * Cudd_SubsetShortPaths(DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit)
Definition: cuddSubsetSP.c:220
DdNode* Cudd_SupersetCompress ( DdManager dd,
DdNode f,
int  nvars,
int  threshold 
)

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

Synopsis [Find a dense superset of BDD f.]

Description [Finds a dense superset of BDD f. Density is the ratio of number of minterms to number of nodes. Uses several techniques in series. It is more expensive than other supersetting procedures, but often produces better results. See Cudd_SupersetShortPaths for a description of the threshold and nvars parameters. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_SubsetCompress Cudd_SupersetRemap Cudd_SupersetShortPaths Cudd_SupersetHeavyBranch Cudd_bddSqueeze]

Definition at line 750 of file cuddGenCof.c.

755 {
756  DdNode *subset;
757 
758  subset = Cudd_SubsetCompress(dd, Cudd_Not(f),nvars,threshold);
759 
760  return(Cudd_NotCond(subset, (subset != NULL)));
761 
762 } /* end of Cudd_SupersetCompress */
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
DdNode * Cudd_SubsetCompress(DdManager *dd, DdNode *f, int nvars, int threshold)
Definition: cuddGenCof.c:700
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
DdNode* cuddAddConstrainRecur ( DdManager dd,
DdNode f,
DdNode c 
)

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

Synopsis [Performs the recursive step of Cudd_addConstrain.]

Description [Performs the recursive step of Cudd_addConstrain. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addConstrain]

Definition at line 1203 of file cuddGenCof.c.

1207 {
1208  DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r;
1209  DdNode *one, *zero;
1210  unsigned int topf, topc;
1211  int index;
1212 
1213  statLine(dd);
1214  one = DD_ONE(dd);
1215  zero = DD_ZERO(dd);
1216 
1217  /* Trivial cases. */
1218  if (c == one) return(f);
1219  if (c == zero) return(zero);
1220  if (Cudd_IsConstant(f)) return(f);
1221  if (f == c) return(one);
1222 
1223  /* Now f and c are non-constant. */
1224 
1225  /* Check the cache. */
1226  r = cuddCacheLookup2(dd, Cudd_addConstrain, f, c);
1227  if (r != NULL) {
1228  return(r);
1229  }
1230 
1231  /* Recursive step. */
1232  topf = dd->perm[f->index];
1233  topc = dd->perm[c->index];
1234  if (topf <= topc) {
1235  index = f->index;
1236  Fv = cuddT(f); Fnv = cuddE(f);
1237  } else {
1238  index = c->index;
1239  Fv = Fnv = f;
1240  }
1241  if (topc <= topf) {
1242  Cv = cuddT(c); Cnv = cuddE(c);
1243  } else {
1244  Cv = Cnv = c;
1245  }
1246 
1247  if (!Cudd_IsConstant(Cv)) {
1248  t = cuddAddConstrainRecur(dd, Fv, Cv);
1249  if (t == NULL)
1250  return(NULL);
1251  } else if (Cv == one) {
1252  t = Fv;
1253  } else { /* Cv == zero: return Fnv @ Cnv */
1254  if (Cnv == one) {
1255  r = Fnv;
1256  } else {
1257  r = cuddAddConstrainRecur(dd, Fnv, Cnv);
1258  if (r == NULL)
1259  return(NULL);
1260  }
1261  return(r);
1262  }
1263  cuddRef(t);
1264 
1265  if (!Cudd_IsConstant(Cnv)) {
1266  e = cuddAddConstrainRecur(dd, Fnv, Cnv);
1267  if (e == NULL) {
1268  Cudd_RecursiveDeref(dd, t);
1269  return(NULL);
1270  }
1271  } else if (Cnv == one) {
1272  e = Fnv;
1273  } else { /* Cnv == zero: return Fv @ Cv previously computed */
1274  cuddDeref(t);
1275  return(t);
1276  }
1277  cuddRef(e);
1278 
1279  r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
1280  if (r == NULL) {
1281  Cudd_RecursiveDeref(dd, e);
1282  Cudd_RecursiveDeref(dd, t);
1283  return(NULL);
1284  }
1285  cuddDeref(t);
1286  cuddDeref(e);
1287 
1288  cuddCacheInsert2(dd, Cudd_addConstrain, f, c, r);
1289  return(r);
1290 
1291 } /* end of cuddAddConstrainRecur */
DdNode * Cudd_addConstrain(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:336
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define Cudd_IsConstant(node)
Definition: cudd.h:352
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
static DdNode * one
Definition: cuddDecomp.c:112
DdNode * cuddAddConstrainRecur(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:1203
#define cuddT(node)
Definition: cuddInt.h:636
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
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
#define DD_ZERO(dd)
Definition: cuddInt.h:927
DdNode* cuddAddRestrictRecur ( DdManager dd,
DdNode f,
DdNode c 
)

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

Synopsis [Performs the recursive step of Cudd_addRestrict.]

Description [Performs the recursive step of Cudd_addRestrict. Returns the restricted ADD if successful; otherwise NULL.]

SideEffects [None]

SeeAlso [Cudd_addRestrict]

Definition at line 1307 of file cuddGenCof.c.

1311 {
1312  DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r, *one, *zero;
1313  unsigned int topf, topc;
1314  int index;
1315 
1316  statLine(dd);
1317  one = DD_ONE(dd);
1318  zero = DD_ZERO(dd);
1319 
1320  /* Trivial cases */
1321  if (c == one) return(f);
1322  if (c == zero) return(zero);
1323  if (Cudd_IsConstant(f)) return(f);
1324  if (f == c) return(one);
1325 
1326  /* Now f and c are non-constant. */
1327 
1328  /* Check the cache. */
1329  r = cuddCacheLookup2(dd, Cudd_addRestrict, f, c);
1330  if (r != NULL) {
1331  return(r);
1332  }
1333 
1334  topf = dd->perm[f->index];
1335  topc = dd->perm[c->index];
1336 
1337  if (topc < topf) { /* abstract top variable from c */
1338  DdNode *d, *s1, *s2;
1339 
1340  /* Find cofactors of c. */
1341  s1 = cuddT(c);
1342  s2 = cuddE(c);
1343  /* Take the OR by applying DeMorgan. */
1344  d = cuddAddApplyRecur(dd, Cudd_addOr, s1, s2);
1345  if (d == NULL) return(NULL);
1346  cuddRef(d);
1347  r = cuddAddRestrictRecur(dd, f, d);
1348  if (r == NULL) {
1349  Cudd_RecursiveDeref(dd, d);
1350  return(NULL);
1351  }
1352  cuddRef(r);
1353  Cudd_RecursiveDeref(dd, d);
1354  cuddCacheInsert2(dd, Cudd_addRestrict, f, c, r);
1355  cuddDeref(r);
1356  return(r);
1357  }
1358 
1359  /* Recursive step. Here topf <= topc. */
1360  index = f->index;
1361  Fv = cuddT(f); Fnv = cuddE(f);
1362  if (topc == topf) {
1363  Cv = cuddT(c); Cnv = cuddE(c);
1364  } else {
1365  Cv = Cnv = c;
1366  }
1367 
1368  if (!Cudd_IsConstant(Cv)) {
1369  t = cuddAddRestrictRecur(dd, Fv, Cv);
1370  if (t == NULL) return(NULL);
1371  } else if (Cv == one) {
1372  t = Fv;
1373  } else { /* Cv == zero: return(Fnv @ Cnv) */
1374  if (Cnv == one) {
1375  r = Fnv;
1376  } else {
1377  r = cuddAddRestrictRecur(dd, Fnv, Cnv);
1378  if (r == NULL) return(NULL);
1379  }
1380  return(r);
1381  }
1382  cuddRef(t);
1383 
1384  if (!Cudd_IsConstant(Cnv)) {
1385  e = cuddAddRestrictRecur(dd, Fnv, Cnv);
1386  if (e == NULL) {
1387  Cudd_RecursiveDeref(dd, t);
1388  return(NULL);
1389  }
1390  } else if (Cnv == one) {
1391  e = Fnv;
1392  } else { /* Cnv == zero: return (Fv @ Cv) previously computed */
1393  cuddDeref(t);
1394  return(t);
1395  }
1396  cuddRef(e);
1397 
1398  r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
1399  if (r == NULL) {
1400  Cudd_RecursiveDeref(dd, e);
1401  Cudd_RecursiveDeref(dd, t);
1402  return(NULL);
1403  }
1404  cuddDeref(t);
1405  cuddDeref(e);
1406 
1407  cuddCacheInsert2(dd, Cudd_addRestrict, f, c, r);
1408  return(r);
1409 
1410 } /* end of cuddAddRestrictRecur */
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
DdNode * Cudd_addOr(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:581
#define Cudd_IsConstant(node)
Definition: cudd.h:352
DdNode * cuddAddApplyRecur(DdManager *dd, DD_AOP op, DdNode *f, DdNode *g)
Definition: cuddAddApply.c:809
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
static DdNode * one
Definition: cuddDecomp.c:112
static char s1[largest_string]
Definition: set.c:514
#define cuddT(node)
Definition: cuddInt.h:636
DdNode * Cudd_addRestrict(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:431
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
DdNode * cuddAddRestrictRecur(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:1307
#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
#define DD_ZERO(dd)
Definition: cuddInt.h:927
static DdNode * cuddBddCharToVect ( DdManager dd,
DdNode f,
DdNode x 
)
static

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

Synopsis [Performs the recursive step of Cudd_bddCharToVect.]

Description [Performs the recursive step of Cudd_bddCharToVect. This function maintains the invariant that f is non-zero. Returns the i-th component of the vector if successful; otherwise NULL.]

SideEffects [None]

SeeAlso [Cudd_bddCharToVect]

Definition at line 1566 of file cuddGenCof.c.

1570 {
1571  unsigned int topf;
1572  unsigned int level;
1573  int comple;
1574 
1575  DdNode *one, *zero, *res, *F, *fT, *fE, *T, *E;
1576 
1577  statLine(dd);
1578  /* Check the cache. */
1579  res = cuddCacheLookup2(dd, cuddBddCharToVect, f, x);
1580  if (res != NULL) {
1581  return(res);
1582  }
1583 
1584  F = Cudd_Regular(f);
1585 
1586  topf = cuddI(dd,F->index);
1587  level = dd->perm[x->index];
1588 
1589  if (topf > level) return(x);
1590 
1591  one = DD_ONE(dd);
1592  zero = Cudd_Not(one);
1593 
1594  comple = F != f;
1595  fT = Cudd_NotCond(cuddT(F),comple);
1596  fE = Cudd_NotCond(cuddE(F),comple);
1597 
1598  if (topf == level) {
1599  if (fT == zero) return(zero);
1600  if (fE == zero) return(one);
1601  return(x);
1602  }
1603 
1604  /* Here topf < level. */
1605  if (fT == zero) return(cuddBddCharToVect(dd, fE, x));
1606  if (fE == zero) return(cuddBddCharToVect(dd, fT, x));
1607 
1608  T = cuddBddCharToVect(dd, fT, x);
1609  if (T == NULL) {
1610  return(NULL);
1611  }
1612  cuddRef(T);
1613  E = cuddBddCharToVect(dd, fE, x);
1614  if (E == NULL) {
1615  Cudd_IterDerefBdd(dd,T);
1616  return(NULL);
1617  }
1618  cuddRef(E);
1619  res = cuddBddIteRecur(dd, dd->vars[F->index], T, E);
1620  if (res == NULL) {
1621  Cudd_IterDerefBdd(dd,T);
1622  Cudd_IterDerefBdd(dd,E);
1623  return(NULL);
1624  }
1625  cuddDeref(T);
1626  cuddDeref(E);
1627  cuddCacheInsert2(dd, cuddBddCharToVect, f, x, res);
1628  return(res);
1629 
1630 } /* end of cuddBddCharToVect */
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
static DdNode * cuddBddCharToVect(DdManager *dd, DdNode *f, DdNode *x)
Definition: cuddGenCof.c:1566
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
static DdNode * one
Definition: cuddDecomp.c:112
#define cuddT(node)
Definition: cuddInt.h:636
#define cuddI(dd, index)
Definition: cuddInt.h:686
DdHalfWord index
Definition: cudd.h:279
DdNode ** vars
Definition: cuddInt.h:390
#define cuddE(node)
Definition: cuddInt.h:652
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
#define DD_ONE(dd)
Definition: cuddInt.h:911
int * perm
Definition: cuddInt.h:386
static DdNode * zero
Definition: cuddApa.c:100
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:633
static int cuddBddConstrainDecomp ( DdManager dd,
DdNode f,
DdNode **  decomp 
)
static

AutomaticStart

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

Synopsis [Performs the recursive step of Cudd_bddConstrainDecomp.]

Description [Performs the recursive step of Cudd_bddConstrainDecomp. Returns f super (i) if successful; otherwise NULL.]

SideEffects [None]

SeeAlso [Cudd_bddConstrainDecomp]

Definition at line 1504 of file cuddGenCof.c.

1508 {
1509  DdNode *F, *fv, *fvn;
1510  DdNode *fAbs;
1511  DdNode *result;
1512  int ok;
1513 
1514  if (Cudd_IsConstant(f)) return(1);
1515  /* Compute complements of cofactors. */
1516  F = Cudd_Regular(f);
1517  fv = cuddT(F);
1518  fvn = cuddE(F);
1519  if (F == f) {
1520  fv = Cudd_Not(fv);
1521  fvn = Cudd_Not(fvn);
1522  }
1523  /* Compute abstraction of top variable. */
1524  fAbs = cuddBddAndRecur(dd, fv, fvn);
1525  if (fAbs == NULL) {
1526  return(0);
1527  }
1528  cuddRef(fAbs);
1529  fAbs = Cudd_Not(fAbs);
1530  /* Recursively find the next abstraction and the components of the
1531  ** decomposition. */
1532  ok = cuddBddConstrainDecomp(dd, fAbs, decomp);
1533  if (ok == 0) {
1534  Cudd_IterDerefBdd(dd,fAbs);
1535  return(0);
1536  }
1537  /* Compute the component of the decomposition corresponding to the
1538  ** top variable and store it in the decomposition array. */
1539  result = cuddBddConstrainRecur(dd, f, fAbs);
1540  if (result == NULL) {
1541  Cudd_IterDerefBdd(dd,fAbs);
1542  return(0);
1543  }
1544  cuddRef(result);
1545  decomp[F->index] = result;
1546  Cudd_IterDerefBdd(dd, fAbs);
1547  return(1);
1548 
1549 } /* end of cuddBddConstrainDecomp */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
#define cuddRef(n)
Definition: cuddInt.h:584
DdNode * cuddBddConstrainRecur(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:783
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
#define Cudd_IsConstant(node)
Definition: cudd.h:352
#define Cudd_Regular(node)
Definition: cudd.h:397
static int cuddBddConstrainDecomp(DdManager *dd, DdNode *f, DdNode **decomp)
Definition: cuddGenCof.c:1504
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
static int result
Definition: cuddGenetic.c:125
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
DdNode* cuddBddConstrainRecur ( DdManager dd,
DdNode f,
DdNode c 
)

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

Synopsis [Performs the recursive step of Cudd_bddConstrain.]

Description [Performs the recursive step of Cudd_bddConstrain. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddConstrain]

Definition at line 783 of file cuddGenCof.c.

787 {
788  DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r;
789  DdNode *one, *zero;
790  unsigned int topf, topc;
791  int index;
792  int comple = 0;
793 
794  statLine(dd);
795  one = DD_ONE(dd);
796  zero = Cudd_Not(one);
797 
798  /* Trivial cases. */
799  if (c == one) return(f);
800  if (c == zero) return(zero);
801  if (Cudd_IsConstant(f)) return(f);
802  if (f == c) return(one);
803  if (f == Cudd_Not(c)) return(zero);
804 
805  /* Make canonical to increase the utilization of the cache. */
806  if (Cudd_IsComplement(f)) {
807  f = Cudd_Not(f);
808  comple = 1;
809  }
810  /* Now f is a regular pointer to a non-constant node; c is also
811  ** non-constant, but may be complemented.
812  */
813 
814  /* Check the cache. */
815  r = cuddCacheLookup2(dd, Cudd_bddConstrain, f, c);
816  if (r != NULL) {
817  return(Cudd_NotCond(r,comple));
818  }
819 
820  /* Recursive step. */
821  topf = dd->perm[f->index];
822  topc = dd->perm[Cudd_Regular(c)->index];
823  if (topf <= topc) {
824  index = f->index;
825  Fv = cuddT(f); Fnv = cuddE(f);
826  } else {
827  index = Cudd_Regular(c)->index;
828  Fv = Fnv = f;
829  }
830  if (topc <= topf) {
831  Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c));
832  if (Cudd_IsComplement(c)) {
833  Cv = Cudd_Not(Cv);
834  Cnv = Cudd_Not(Cnv);
835  }
836  } else {
837  Cv = Cnv = c;
838  }
839 
840  if (!Cudd_IsConstant(Cv)) {
841  t = cuddBddConstrainRecur(dd, Fv, Cv);
842  if (t == NULL)
843  return(NULL);
844  } else if (Cv == one) {
845  t = Fv;
846  } else { /* Cv == zero: return Fnv @ Cnv */
847  if (Cnv == one) {
848  r = Fnv;
849  } else {
850  r = cuddBddConstrainRecur(dd, Fnv, Cnv);
851  if (r == NULL)
852  return(NULL);
853  }
854  return(Cudd_NotCond(r,comple));
855  }
856  cuddRef(t);
857 
858  if (!Cudd_IsConstant(Cnv)) {
859  e = cuddBddConstrainRecur(dd, Fnv, Cnv);
860  if (e == NULL) {
861  Cudd_IterDerefBdd(dd, t);
862  return(NULL);
863  }
864  } else if (Cnv == one) {
865  e = Fnv;
866  } else { /* Cnv == zero: return Fv @ Cv previously computed */
867  cuddDeref(t);
868  return(Cudd_NotCond(t,comple));
869  }
870  cuddRef(e);
871 
872  if (Cudd_IsComplement(t)) {
873  t = Cudd_Not(t);
874  e = Cudd_Not(e);
875  r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
876  if (r == NULL) {
877  Cudd_IterDerefBdd(dd, e);
878  Cudd_IterDerefBdd(dd, t);
879  return(NULL);
880  }
881  r = Cudd_Not(r);
882  } else {
883  r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
884  if (r == NULL) {
885  Cudd_IterDerefBdd(dd, e);
886  Cudd_IterDerefBdd(dd, t);
887  return(NULL);
888  }
889  }
890  cuddDeref(t);
891  cuddDeref(e);
892 
893  cuddCacheInsert2(dd, Cudd_bddConstrain, f, c, r);
894  return(Cudd_NotCond(r,comple));
895 
896 } /* end of cuddBddConstrainRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
#define cuddRef(n)
Definition: cuddInt.h:584
DdNode * cuddBddConstrainRecur(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:783
#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_IsConstant(node)
Definition: cudd.h:352
#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 cuddT(node)
Definition: cuddInt.h:636
DdNode * Cudd_bddConstrain(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:180
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
#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
static DdNode * cuddBddLICBuildResult ( DdManager dd,
DdNode f,
st__table cache,
st__table table 
)
static

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

Synopsis [Builds the result of Cudd_bddLICompaction.]

Description [Builds the results of Cudd_bddLICompaction. Returns a pointer to the minimized BDD if successful; otherwise NULL.]

SideEffects [None]

SeeAlso [Cudd_bddLICompaction cuddBddLICMarkEdges]

Definition at line 1766 of file cuddGenCof.c.

1771 {
1772  DdNode *Fv, *Fnv, *r, *t, *e;
1773  DdNode *one, *zero;
1774  int index;
1775  int comple;
1776  int markT, markE, markings;
1777 
1778  one = DD_ONE(dd);
1779  zero = Cudd_Not(one);
1780 
1781  if (Cudd_IsConstant(f)) return(f);
1782  /* Make canonical to increase the utilization of the cache. */
1783  comple = Cudd_IsComplement(f);
1784  f = Cudd_Regular(f);
1785 
1786  /* Check the cache. */
1787  if ( st__lookup(cache, (const char *)f, (char **)&r)) {
1788  return(Cudd_NotCond(r,comple));
1789  }
1790 
1791  /* Retrieve the edge markings. */
1792  if ( st__lookup_int(table, (char *)f, &markings) == 0)
1793  return(NULL);
1794  markT = markings >> 2;
1795  markE = markings & 3;
1796 
1797  index = f->index;
1798  Fv = cuddT(f); Fnv = cuddE(f);
1799 
1800  if (markT == DD_LIC_NL) {
1801  t = cuddBddLICBuildResult(dd,Fv,cache,table);
1802  if (t == NULL) {
1803  return(NULL);
1804  }
1805  } else if (markT == DD_LIC_1) {
1806  t = one;
1807  } else {
1808  t = zero;
1809  }
1810  cuddRef(t);
1811  if (markE == DD_LIC_NL) {
1812  e = cuddBddLICBuildResult(dd,Fnv,cache,table);
1813  if (e == NULL) {
1814  Cudd_IterDerefBdd(dd,t);
1815  return(NULL);
1816  }
1817  } else if (markE == DD_LIC_1) {
1818  e = one;
1819  } else {
1820  e = zero;
1821  }
1822  cuddRef(e);
1823 
1824  if (markT == DD_LIC_DC && markE != DD_LIC_DC) {
1825  r = e;
1826  } else if (markT != DD_LIC_DC && markE == DD_LIC_DC) {
1827  r = t;
1828  } else {
1829  if (Cudd_IsComplement(t)) {
1830  t = Cudd_Not(t);
1831  e = Cudd_Not(e);
1832  r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
1833  if (r == NULL) {
1834  Cudd_IterDerefBdd(dd, e);
1835  Cudd_IterDerefBdd(dd, t);
1836  return(NULL);
1837  }
1838  r = Cudd_Not(r);
1839  } else {
1840  r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
1841  if (r == NULL) {
1842  Cudd_IterDerefBdd(dd, e);
1843  Cudd_IterDerefBdd(dd, t);
1844  return(NULL);
1845  }
1846  }
1847  }
1848  cuddDeref(t);
1849  cuddDeref(e);
1850 
1851  if ( st__insert(cache, (char *)f, (char *)r) == st__OUT_OF_MEM) {
1852  cuddRef(r);
1853  Cudd_IterDerefBdd(dd,r);
1854  return(NULL);
1855  }
1856 
1857  return(Cudd_NotCond(r,comple));
1858 
1859 } /* end of cuddBddLICBuildResult */
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
int st__insert(st__table *table, const char *key, char *value)
Definition: st.c:171
#define Cudd_IsConstant(node)
Definition: cudd.h:352
#define Cudd_Regular(node)
Definition: cudd.h:397
int st__lookup_int(st__table *table, char *key, int *value)
Definition: st.c:134
static DdNode * cuddBddLICBuildResult(DdManager *dd, DdNode *f, st__table *cache, st__table *table)
Definition: cuddGenCof.c:1766
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
#define DD_LIC_DC
Definition: cuddGenCof.c:93
#define cuddT(node)
Definition: cuddInt.h:636
#define st__OUT_OF_MEM
Definition: st.h:113
#define DD_LIC_NL
Definition: cuddGenCof.c:96
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
#define DD_ONE(dd)
Definition: cuddInt.h:911
#define DD_LIC_1
Definition: cuddGenCof.c:94
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
static int cuddBddLICMarkEdges ( DdManager dd,
DdNode f,
DdNode c,
st__table table,
st__table cache 
)
static

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

Synopsis [Performs the edge marking step of Cudd_bddLICompaction.]

Description [Performs the edge marking step of Cudd_bddLICompaction. Returns the LUB of the markings of the two outgoing edges of f if successful; otherwise CUDD_OUT_OF_MEM.]

SideEffects [None]

SeeAlso [Cudd_bddLICompaction cuddBddLICBuildResult]

Definition at line 1647 of file cuddGenCof.c.

1653 {
1654  DdNode *Fv, *Fnv, *Cv, *Cnv;
1655  DdNode *one, *zero;
1656  unsigned int topf, topc;
1657  int comple;
1658  int resT, resE, res, retval;
1659  char **slot;
1660  MarkCacheKey *key;
1661 
1662  one = DD_ONE(dd);
1663  zero = Cudd_Not(one);
1664 
1665  /* Terminal cases. */
1666  if (c == zero) return(DD_LIC_DC);
1667  if (f == one) return(DD_LIC_1);
1668  if (f == zero) return(DD_LIC_0);
1669 
1670  /* Make canonical to increase the utilization of the cache. */
1671  comple = Cudd_IsComplement(f);
1672  f = Cudd_Regular(f);
1673  /* Now f is a regular pointer to a non-constant node; c may be
1674  ** constant, or it may be complemented.
1675  */
1676 
1677  /* Check the cache. */
1678  key = ABC_ALLOC(MarkCacheKey, 1);
1679  if (key == NULL) {
1680  dd->errorCode = CUDD_MEMORY_OUT;
1681  return(CUDD_OUT_OF_MEM);
1682  }
1683  key->f = f; key->c = c;
1684  if ( st__lookup_int(cache, (char *)key, &res)) {
1685  ABC_FREE(key);
1686  if (comple) {
1687  if (res == DD_LIC_0) res = DD_LIC_1;
1688  else if (res == DD_LIC_1) res = DD_LIC_0;
1689  }
1690  return(res);
1691  }
1692 
1693  /* Recursive step. */
1694  topf = dd->perm[f->index];
1695  topc = cuddI(dd,Cudd_Regular(c)->index);
1696  if (topf <= topc) {
1697  Fv = cuddT(f); Fnv = cuddE(f);
1698  } else {
1699  Fv = Fnv = f;
1700  }
1701  if (topc <= topf) {
1702  /* We know that c is not constant because f is not. */
1703  Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c));
1704  if (Cudd_IsComplement(c)) {
1705  Cv = Cudd_Not(Cv);
1706  Cnv = Cudd_Not(Cnv);
1707  }
1708  } else {
1709  Cv = Cnv = c;
1710  }
1711 
1712  resT = cuddBddLICMarkEdges(dd, Fv, Cv, table, cache);
1713  if (resT == CUDD_OUT_OF_MEM) {
1714  ABC_FREE(key);
1715  return(CUDD_OUT_OF_MEM);
1716  }
1717  resE = cuddBddLICMarkEdges(dd, Fnv, Cnv, table, cache);
1718  if (resE == CUDD_OUT_OF_MEM) {
1719  ABC_FREE(key);
1720  return(CUDD_OUT_OF_MEM);
1721  }
1722 
1723  /* Update edge markings. */
1724  if (topf <= topc) {
1725  retval = st__find_or_add(table, (char *)f, (char ***)&slot);
1726  if (retval == 0) {
1727  *slot = (char *) (ptrint)((resT << 2) | resE);
1728  } else if (retval == 1) {
1729  *slot = (char *) (ptrint)((int)((ptrint) *slot) | (resT << 2) | resE);
1730  } else {
1731  ABC_FREE(key);
1732  return(CUDD_OUT_OF_MEM);
1733  }
1734  }
1735 
1736  /* Cache result. */
1737  res = resT | resE;
1738  if ( st__insert(cache, (char *)key, (char *)(ptrint)res) == st__OUT_OF_MEM) {
1739  ABC_FREE(key);
1740  return(CUDD_OUT_OF_MEM);
1741  }
1742 
1743  /* Take into account possible complementation. */
1744  if (comple) {
1745  if (res == DD_LIC_0) res = DD_LIC_1;
1746  else if (res == DD_LIC_1) res = DD_LIC_0;
1747  }
1748  return(res);
1749 
1750 } /* end of cuddBddLICMarkEdges */
#define CUDD_OUT_OF_MEM
Definition: cudd.h:95
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
int st__insert(st__table *table, const char *key, char *value)
Definition: st.c:171
DdNode * c
Definition: cuddGenCof.c:110
#define Cudd_Regular(node)
Definition: cudd.h:397
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int st__lookup_int(st__table *table, char *key, int *value)
Definition: st.c:134
#define Cudd_IsComplement(node)
Definition: cudd.h:425
int st__find_or_add(st__table *table, char *key, char ***slot)
Definition: st.c:230
static DdNode * one
Definition: cuddDecomp.c:112
ABC_PTRINT_T ptrint
Definition: cuddInt.h:260
#define DD_LIC_DC
Definition: cuddGenCof.c:93
DdNode * f
Definition: cuddGenCof.c:109
#define cuddT(node)
Definition: cuddInt.h:636
#define st__OUT_OF_MEM
Definition: st.h:113
#define cuddI(dd, index)
Definition: cuddInt.h:686
#define DD_LIC_0
Definition: cuddGenCof.c:95
DdHalfWord index
Definition: cudd.h:279
#define ABC_FREE(obj)
Definition: abc_global.h:232
enum keys key
#define cuddE(node)
Definition: cuddInt.h:652
static int cuddBddLICMarkEdges(DdManager *dd, DdNode *f, DdNode *c, st__table *table, st__table *cache)
Definition: cuddGenCof.c:1647
#define DD_ONE(dd)
Definition: cuddInt.h:911
#define DD_LIC_1
Definition: cuddGenCof.c:94
int * perm
Definition: cuddInt.h:386
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
static DdNode * zero
Definition: cuddApa.c:100
DdNode* cuddBddLICompaction ( DdManager dd,
DdNode f,
DdNode c 
)

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

Synopsis [Performs safe minimization of a BDD.]

Description [Performs safe minimization of a BDD. Given the BDD f of a function to be minimized and a BDD c representing the care set, Cudd_bddLICompaction produces the BDD of a function that agrees with f wherever c is 1. Safe minimization means that the size of the result is guaranteed not to exceed the size of f. This function is based on the DAC97 paper by Hong et al.. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddLICompaction]

Definition at line 1434 of file cuddGenCof.c.

1438 {
1439  st__table *marktable, *markcache, *buildcache;
1440  DdNode *res, *zero;
1441 
1442  zero = Cudd_Not(DD_ONE(dd));
1443  if (c == zero) return(zero);
1444 
1445  /* We need to use local caches for both steps of this operation.
1446  ** The results of the edge marking step are only valid as long as the
1447  ** edge markings themselves are available. However, the edge markings
1448  ** are lost at the end of one invocation of Cudd_bddLICompaction.
1449  ** Hence, the cache entries for the edge marking step must be
1450  ** invalidated at the end of this function.
1451  ** For the result of the building step we argue as follows. The result
1452  ** for a node and a given constrain depends on the BDD in which the node
1453  ** appears. Hence, the same node and constrain may give different results
1454  ** in successive invocations.
1455  */
1456  marktable = st__init_table( st__ptrcmp, st__ptrhash);
1457  if (marktable == NULL) {
1458  return(NULL);
1459  }
1461  if (markcache == NULL) {
1462  st__free_table(marktable);
1463  return(NULL);
1464  }
1465  if (cuddBddLICMarkEdges(dd,f,c,marktable,markcache) == CUDD_OUT_OF_MEM) {
1466  st__foreach(markcache, MarkCacheCleanUp, NULL);
1467  st__free_table(marktable);
1468  st__free_table(markcache);
1469  return(NULL);
1470  }
1471  st__foreach(markcache, MarkCacheCleanUp, NULL);
1472  st__free_table(markcache);
1473  buildcache = st__init_table( st__ptrcmp, st__ptrhash);
1474  if (buildcache == NULL) {
1475  st__free_table(marktable);
1476  return(NULL);
1477  }
1478  res = cuddBddLICBuildResult(dd,f,buildcache,marktable);
1479  st__free_table(buildcache);
1480  st__free_table(marktable);
1481  return(res);
1482 
1483 } /* end of cuddBddLICompaction */
void st__free_table(st__table *table)
Definition: st.c:81
#define CUDD_OUT_OF_MEM
Definition: cudd.h:95
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
int st__ptrcmp(const char *, const char *)
Definition: st.c:480
static enum st__retval MarkCacheCleanUp(char *key, char *value, char *arg)
Definition: cuddGenCof.c:1936
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition: st.c:72
static DdNode * cuddBddLICBuildResult(DdManager *dd, DdNode *f, st__table *cache, st__table *table)
Definition: cuddGenCof.c:1766
Definition: st.h:52
static int MarkCacheHash(const char *ptr, int modulus)
Definition: cuddGenCof.c:1875
int st__foreach(st__table *table, enum st__retval(*func)(char *, char *, char *), char *arg)
Definition: st.c:421
static int cuddBddLICMarkEdges(DdManager *dd, DdNode *f, DdNode *c, st__table *table, st__table *cache)
Definition: cuddGenCof.c:1647
#define DD_ONE(dd)
Definition: cuddInt.h:911
int st__ptrhash(const char *, int)
Definition: st.c:468
static DdNode * zero
Definition: cuddApa.c:100
static int MarkCacheCompare(const char *ptr1, const char *ptr2)
Definition: cuddGenCof.c:1907
DdNode* cuddBddNPAndRecur ( DdManager manager,
DdNode f,
DdNode g 
)

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

Synopsis [Implements the recursive step of Cudd_bddAnd.]

Description [Implements the recursive step of Cudd_bddNPAnd. Returns a pointer to the result is successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddNPAnd]

Definition at line 1062 of file cuddGenCof.c.

1066 {
1067  DdNode *F, *ft, *fe, *G, *gt, *ge;
1068  DdNode *one, *r, *t, *e;
1069  unsigned int topf, topg, index;
1070 
1071  statLine(manager);
1072  one = DD_ONE(manager);
1073 
1074  /* Terminal cases. */
1075  F = Cudd_Regular(f);
1076  G = Cudd_Regular(g);
1077  if (F == G) {
1078  if (f == g) return(one);
1079  else return(Cudd_Not(one));
1080  }
1081  if (G == one) {
1082  if (g == one) return(f);
1083  else return(g);
1084  }
1085  if (F == one) {
1086  return(f);
1087  }
1088 
1089  /* At this point f and g are not constant. */
1090  /* Check cache. */
1091  if (F->ref != 1 || G->ref != 1) {
1092  r = cuddCacheLookup2(manager, Cudd_bddNPAnd, f, g);
1093  if (r != NULL) return(r);
1094  }
1095 
1096  /* Here we can skip the use of cuddI, because the operands are known
1097  ** to be non-constant.
1098  */
1099  topf = manager->perm[F->index];
1100  topg = manager->perm[G->index];
1101 
1102  if (topg < topf) { /* abstract top variable from g */
1103  DdNode *d;
1104 
1105  /* Find complements of cofactors of g. */
1106  if (Cudd_IsComplement(g)) {
1107  gt = cuddT(G);
1108  ge = cuddE(G);
1109  } else {
1110  gt = Cudd_Not(cuddT(g));
1111  ge = Cudd_Not(cuddE(g));
1112  }
1113  /* Take the OR by applying DeMorgan. */
1114  d = cuddBddAndRecur(manager, gt, ge);
1115  if (d == NULL) return(NULL);
1116  d = Cudd_Not(d);
1117  cuddRef(d);
1118  r = cuddBddNPAndRecur(manager, f, d);
1119  if (r == NULL) {
1120  Cudd_IterDerefBdd(manager, d);
1121  return(NULL);
1122  }
1123  cuddRef(r);
1124  Cudd_IterDerefBdd(manager, d);
1125  cuddCacheInsert2(manager, Cudd_bddNPAnd, f, g, r);
1126  cuddDeref(r);
1127  return(r);
1128  }
1129 
1130  /* Compute cofactors. */
1131  index = F->index;
1132  ft = cuddT(F);
1133  fe = cuddE(F);
1134  if (Cudd_IsComplement(f)) {
1135  ft = Cudd_Not(ft);
1136  fe = Cudd_Not(fe);
1137  }
1138 
1139  if (topg == topf) {
1140  gt = cuddT(G);
1141  ge = cuddE(G);
1142  if (Cudd_IsComplement(g)) {
1143  gt = Cudd_Not(gt);
1144  ge = Cudd_Not(ge);
1145  }
1146  } else {
1147  gt = ge = g;
1148  }
1149 
1150  t = cuddBddAndRecur(manager, ft, gt);
1151  if (t == NULL) return(NULL);
1152  cuddRef(t);
1153 
1154  e = cuddBddAndRecur(manager, fe, ge);
1155  if (e == NULL) {
1156  Cudd_IterDerefBdd(manager, t);
1157  return(NULL);
1158  }
1159  cuddRef(e);
1160 
1161  if (t == e) {
1162  r = t;
1163  } else {
1164  if (Cudd_IsComplement(t)) {
1165  r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e));
1166  if (r == NULL) {
1167  Cudd_IterDerefBdd(manager, t);
1168  Cudd_IterDerefBdd(manager, e);
1169  return(NULL);
1170  }
1171  r = Cudd_Not(r);
1172  } else {
1173  r = cuddUniqueInter(manager,(int)index,t,e);
1174  if (r == NULL) {
1175  Cudd_IterDerefBdd(manager, t);
1176  Cudd_IterDerefBdd(manager, e);
1177  return(NULL);
1178  }
1179  }
1180  }
1181  cuddDeref(e);
1182  cuddDeref(t);
1183  if (F->ref != 1 || G->ref != 1)
1184  cuddCacheInsert2(manager, Cudd_bddNPAnd, f, g, r);
1185  return(r);
1186 
1187 } /* end of cuddBddNPAndRecur */
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
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 cuddT(node)
Definition: cuddInt.h:636
DdNode * cuddBddNPAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddGenCof.c:1062
DdNode * Cudd_bddNPAnd(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddGenCof.c:299
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#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* cuddBddRestrictRecur ( DdManager dd,
DdNode f,
DdNode c 
)

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

Synopsis [Performs the recursive step of Cudd_bddRestrict.]

Description [Performs the recursive step of Cudd_bddRestrict. Returns the restricted BDD if successful; otherwise NULL.]

SideEffects [None]

SeeAlso [Cudd_bddRestrict]

Definition at line 912 of file cuddGenCof.c.

916 {
917  DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r, *one, *zero;
918  unsigned int topf, topc;
919  int index;
920  int comple = 0;
921 
922  statLine(dd);
923  one = DD_ONE(dd);
924  zero = Cudd_Not(one);
925 
926  /* Trivial cases */
927  if (c == one) return(f);
928  if (c == zero) return(zero);
929  if (Cudd_IsConstant(f)) return(f);
930  if (f == c) return(one);
931  if (f == Cudd_Not(c)) return(zero);
932 
933  /* Make canonical to increase the utilization of the cache. */
934  if (Cudd_IsComplement(f)) {
935  f = Cudd_Not(f);
936  comple = 1;
937  }
938  /* Now f is a regular pointer to a non-constant node; c is also
939  ** non-constant, but may be complemented.
940  */
941 
942  /* Check the cache. */
943  r = cuddCacheLookup2(dd, Cudd_bddRestrict, f, c);
944  if (r != NULL) {
945  return(Cudd_NotCond(r,comple));
946  }
947 
948  topf = dd->perm[f->index];
949  topc = dd->perm[Cudd_Regular(c)->index];
950 
951  if (topc < topf) { /* abstract top variable from c */
952  DdNode *d, *s1, *s2;
953 
954  /* Find complements of cofactors of c. */
955  if (Cudd_IsComplement(c)) {
956  s1 = cuddT(Cudd_Regular(c));
957  s2 = cuddE(Cudd_Regular(c));
958  } else {
959  s1 = Cudd_Not(cuddT(c));
960  s2 = Cudd_Not(cuddE(c));
961  }
962  /* Take the OR by applying DeMorgan. */
963  d = cuddBddAndRecur(dd, s1, s2);
964  if (d == NULL) return(NULL);
965  d = Cudd_Not(d);
966  cuddRef(d);
967  r = cuddBddRestrictRecur(dd, f, d);
968  if (r == NULL) {
969  Cudd_IterDerefBdd(dd, d);
970  return(NULL);
971  }
972  cuddRef(r);
973  Cudd_IterDerefBdd(dd, d);
974  cuddCacheInsert2(dd, Cudd_bddRestrict, f, c, r);
975  cuddDeref(r);
976  return(Cudd_NotCond(r,comple));
977  }
978 
979  /* Recursive step. Here topf <= topc. */
980  index = f->index;
981  Fv = cuddT(f); Fnv = cuddE(f);
982  if (topc == topf) {
983  Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c));
984  if (Cudd_IsComplement(c)) {
985  Cv = Cudd_Not(Cv);
986  Cnv = Cudd_Not(Cnv);
987  }
988  } else {
989  Cv = Cnv = c;
990  }
991 
992  if (!Cudd_IsConstant(Cv)) {
993  t = cuddBddRestrictRecur(dd, Fv, Cv);
994  if (t == NULL) return(NULL);
995  } else if (Cv == one) {
996  t = Fv;
997  } else { /* Cv == zero: return(Fnv @ Cnv) */
998  if (Cnv == one) {
999  r = Fnv;
1000  } else {
1001  r = cuddBddRestrictRecur(dd, Fnv, Cnv);
1002  if (r == NULL) return(NULL);
1003  }
1004  return(Cudd_NotCond(r,comple));
1005  }
1006  cuddRef(t);
1007 
1008  if (!Cudd_IsConstant(Cnv)) {
1009  e = cuddBddRestrictRecur(dd, Fnv, Cnv);
1010  if (e == NULL) {
1011  Cudd_IterDerefBdd(dd, t);
1012  return(NULL);
1013  }
1014  } else if (Cnv == one) {
1015  e = Fnv;
1016  } else { /* Cnv == zero: return (Fv @ Cv) previously computed */
1017  cuddDeref(t);
1018  return(Cudd_NotCond(t,comple));
1019  }
1020  cuddRef(e);
1021 
1022  if (Cudd_IsComplement(t)) {
1023  t = Cudd_Not(t);
1024  e = Cudd_Not(e);
1025  r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
1026  if (r == NULL) {
1027  Cudd_IterDerefBdd(dd, e);
1028  Cudd_IterDerefBdd(dd, t);
1029  return(NULL);
1030  }
1031  r = Cudd_Not(r);
1032  } else {
1033  r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
1034  if (r == NULL) {
1035  Cudd_IterDerefBdd(dd, e);
1036  Cudd_IterDerefBdd(dd, t);
1037  return(NULL);
1038  }
1039  }
1040  cuddDeref(t);
1041  cuddDeref(e);
1042 
1043  cuddCacheInsert2(dd, Cudd_bddRestrict, f, c, r);
1044  return(Cudd_NotCond(r,comple));
1045 
1046 } /* end of cuddBddRestrictRecur */
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_IsConstant(node)
Definition: cudd.h:352
#define Cudd_Regular(node)
Definition: cudd.h:397
DdNode * Cudd_bddRestrict(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:212
#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
static char s1[largest_string]
Definition: set.c:514
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
#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
int * perm
Definition: cuddInt.h:386
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
DdNode * cuddBddRestrictRecur(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:912
static DdNode * zero
Definition: cuddApa.c:100
static DdNode * cuddBddSqueeze ( DdManager dd,
DdNode l,
DdNode u 
)
static

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

Synopsis [Performs the recursive step of Cudd_bddSqueeze.]

Description [Performs the recursive step of Cudd_bddSqueeze. This procedure exploits the fact that if we complement and swap the bounds of the interval we obtain a valid solution by taking the complement of the solution to the original problem. Therefore, we can enforce the condition that the upper bound is always regular. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddSqueeze]

Definition at line 1967 of file cuddGenCof.c.

1971 {
1972  DdNode *one, *zero, *r, *lt, *le, *ut, *ue, *t, *e;
1973 #if 0
1974  DdNode *ar;
1975 #endif
1976  int comple = 0;
1977  unsigned int topu, topl;
1978  int index;
1979 
1980  statLine(dd);
1981  if (l == u) {
1982  return(l);
1983  }
1984  one = DD_ONE(dd);
1985  zero = Cudd_Not(one);
1986  /* The only case when l == zero && u == one is at the top level,
1987  ** where returning either one or zero is OK. In all other cases
1988  ** the procedure will detect such a case and will perform
1989  ** remapping. Therefore the order in which we test l and u at this
1990  ** point is immaterial. */
1991  if (l == zero) return(l);
1992  if (u == one) return(u);
1993 
1994  /* Make canonical to increase the utilization of the cache. */
1995  if (Cudd_IsComplement(u)) {
1996  DdNode *temp;
1997  temp = Cudd_Not(l);
1998  l = Cudd_Not(u);
1999  u = temp;
2000  comple = 1;
2001  }
2002  /* At this point u is regular and non-constant; l is non-constant, but
2003  ** may be complemented. */
2004 
2005  /* Here we could check the relative sizes. */
2006 
2007  /* Check the cache. */
2008  r = cuddCacheLookup2(dd, Cudd_bddSqueeze, l, u);
2009  if (r != NULL) {
2010  return(Cudd_NotCond(r,comple));
2011  }
2012 
2013  /* Recursive step. */
2014  topu = dd->perm[u->index];
2015  topl = dd->perm[Cudd_Regular(l)->index];
2016  if (topu <= topl) {
2017  index = u->index;
2018  ut = cuddT(u); ue = cuddE(u);
2019  } else {
2020  index = Cudd_Regular(l)->index;
2021  ut = ue = u;
2022  }
2023  if (topl <= topu) {
2024  lt = cuddT(Cudd_Regular(l)); le = cuddE(Cudd_Regular(l));
2025  if (Cudd_IsComplement(l)) {
2026  lt = Cudd_Not(lt);
2027  le = Cudd_Not(le);
2028  }
2029  } else {
2030  lt = le = l;
2031  }
2032 
2033  /* If one interval is contained in the other, use the smaller
2034  ** interval. This corresponds to one-sided matching. */
2035  if ((lt == zero || Cudd_bddLeq(dd,lt,le)) &&
2036  (ut == one || Cudd_bddLeq(dd,ue,ut))) { /* remap */
2037  r = cuddBddSqueeze(dd, le, ue);
2038  if (r == NULL)
2039  return(NULL);
2040  return(Cudd_NotCond(r,comple));
2041  } else if ((le == zero || Cudd_bddLeq(dd,le,lt)) &&
2042  (ue == one || Cudd_bddLeq(dd,ut,ue))) { /* remap */
2043  r = cuddBddSqueeze(dd, lt, ut);
2044  if (r == NULL)
2045  return(NULL);
2046  return(Cudd_NotCond(r,comple));
2047  } else if ((le == zero || Cudd_bddLeq(dd,le,Cudd_Not(ut))) &&
2048  (ue == one || Cudd_bddLeq(dd,Cudd_Not(lt),ue))) { /* c-remap */
2049  t = cuddBddSqueeze(dd, lt, ut);
2050  cuddRef(t);
2051  if (Cudd_IsComplement(t)) {
2052  r = cuddUniqueInter(dd, index, Cudd_Not(t), t);
2053  if (r == NULL) {
2054  Cudd_IterDerefBdd(dd, t);
2055  return(NULL);
2056  }
2057  r = Cudd_Not(r);
2058  } else {
2059  r = cuddUniqueInter(dd, index, t, Cudd_Not(t));
2060  if (r == NULL) {
2061  Cudd_IterDerefBdd(dd, t);
2062  return(NULL);
2063  }
2064  }
2065  cuddDeref(t);
2066  if (r == NULL)
2067  return(NULL);
2068  cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r);
2069  return(Cudd_NotCond(r,comple));
2070  } else if ((lt == zero || Cudd_bddLeq(dd,lt,Cudd_Not(ue))) &&
2071  (ut == one || Cudd_bddLeq(dd,Cudd_Not(le),ut))) { /* c-remap */
2072  e = cuddBddSqueeze(dd, le, ue);
2073  cuddRef(e);
2074  if (Cudd_IsComplement(e)) {
2075  r = cuddUniqueInter(dd, index, Cudd_Not(e), e);
2076  if (r == NULL) {
2077  Cudd_IterDerefBdd(dd, e);
2078  return(NULL);
2079  }
2080  } else {
2081  r = cuddUniqueInter(dd, index, e, Cudd_Not(e));
2082  if (r == NULL) {
2083  Cudd_IterDerefBdd(dd, e);
2084  return(NULL);
2085  }
2086  r = Cudd_Not(r);
2087  }
2088  cuddDeref(e);
2089  if (r == NULL)
2090  return(NULL);
2091  cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r);
2092  return(Cudd_NotCond(r,comple));
2093  }
2094 
2095 #if 0
2096  /* If the two intervals intersect, take a solution from
2097  ** the intersection of the intervals. This guarantees that the
2098  ** splitting variable will not appear in the result.
2099  ** This approach corresponds to two-sided matching, and is very
2100  ** expensive. */
2101  if (Cudd_bddLeq(dd,lt,ue) && Cudd_bddLeq(dd,le,ut)) {
2102  DdNode *au, *al;
2103  au = cuddBddAndRecur(dd,ut,ue);
2104  if (au == NULL)
2105  return(NULL);
2106  cuddRef(au);
2107  al = cuddBddAndRecur(dd,Cudd_Not(lt),Cudd_Not(le));
2108  if (al == NULL) {
2109  Cudd_IterDerefBdd(dd,au);
2110  return(NULL);
2111  }
2112  cuddRef(al);
2113  al = Cudd_Not(al);
2114  ar = cuddBddSqueeze(dd, al, au);
2115  if (ar == NULL) {
2116  Cudd_IterDerefBdd(dd,au);
2117  Cudd_IterDerefBdd(dd,al);
2118  return(NULL);
2119  }
2120  cuddRef(ar);
2121  Cudd_IterDerefBdd(dd,au);
2122  Cudd_IterDerefBdd(dd,al);
2123  } else {
2124  ar = NULL;
2125  }
2126 #endif
2127 
2128  t = cuddBddSqueeze(dd, lt, ut);
2129  if (t == NULL) {
2130  return(NULL);
2131  }
2132  cuddRef(t);
2133  e = cuddBddSqueeze(dd, le, ue);
2134  if (e == NULL) {
2135  Cudd_IterDerefBdd(dd,t);
2136  return(NULL);
2137  }
2138  cuddRef(e);
2139 
2140  if (Cudd_IsComplement(t)) {
2141  t = Cudd_Not(t);
2142  e = Cudd_Not(e);
2143  r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
2144  if (r == NULL) {
2145  Cudd_IterDerefBdd(dd, e);
2146  Cudd_IterDerefBdd(dd, t);
2147  return(NULL);
2148  }
2149  r = Cudd_Not(r);
2150  } else {
2151  r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
2152  if (r == NULL) {
2153  Cudd_IterDerefBdd(dd, e);
2154  Cudd_IterDerefBdd(dd, t);
2155  return(NULL);
2156  }
2157  }
2158  cuddDeref(t);
2159  cuddDeref(e);
2160 
2161 #if 0
2162  /* Check whether there is a result obtained by abstraction and whether
2163  ** it is better than the one obtained by recursion. */
2164  cuddRef(r);
2165  if (ar != NULL) {
2166  if (Cudd_DagSize(ar) <= Cudd_DagSize(r)) {
2167  Cudd_IterDerefBdd(dd, r);
2168  r = ar;
2169  } else {
2170  Cudd_IterDerefBdd(dd, ar);
2171  }
2172  }
2173  cuddDeref(r);
2174 #endif
2175 
2176  cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r);
2177  return(Cudd_NotCond(r,comple));
2178 
2179 } /* end of cuddBddSqueeze */
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
static DdNode * cuddBddSqueeze(DdManager *dd, DdNode *l, DdNode *u)
Definition: cuddGenCof.c:1967
DdNode * Cudd_bddSqueeze(DdManager *dd, DdNode *l, DdNode *u)
Definition: cuddGenCof.c:602
#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 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 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
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
int Cudd_DagSize(DdNode *node)
Definition: cuddUtil.c:442
static enum st__retval MarkCacheCleanUp ( char *  key,
char *  value,
char *  arg 
)
static

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

Synopsis [Frees memory associated with computed table of cuddBddLICMarkEdges.]

Description [Frees memory associated with computed table of cuddBddLICMarkEdges. Returns st__CONTINUE.]

SideEffects [None]

SeeAlso [Cudd_bddLICompaction]

Definition at line 1936 of file cuddGenCof.c.

1940 {
1942 
1943  entry = (MarkCacheKey *) key;
1944  ABC_FREE(entry);
1945  return st__CONTINUE;
1946 
1947 } /* end of MarkCacheCleanUp */
static int * entry
Definition: cuddGroup.c:122
#define ABC_FREE(obj)
Definition: abc_global.h:232
enum keys key
static int MarkCacheCompare ( const char *  ptr1,
const char *  ptr2 
)
static

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

Synopsis [Comparison function for the computed table of cuddBddLICMarkEdges.]

Description [Comparison function for the computed table of cuddBddLICMarkEdges. Returns 0 if the two nodes of the key are equal; 1 otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddLICompaction]

Definition at line 1907 of file cuddGenCof.c.

1910 {
1911  MarkCacheKey *entry1, *entry2;
1912 
1913  entry1 = (MarkCacheKey *) ptr1;
1914  entry2 = (MarkCacheKey *) ptr2;
1915 
1916  return((entry1->f != entry2->f) || (entry1->c != entry2->c));
1917 
1918 } /* end of MarkCacheCompare */
DdNode * c
Definition: cuddGenCof.c:110
DdNode * f
Definition: cuddGenCof.c:109
static int MarkCacheHash ( const char *  ptr,
int  modulus 
)
static

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

Synopsis [Hash function for the computed table of cuddBddLICMarkEdges.]

Description [Hash function for the computed table of cuddBddLICMarkEdges. Returns the bucket number.]

SideEffects [None]

SeeAlso [Cudd_bddLICompaction]

Definition at line 1875 of file cuddGenCof.c.

1878 {
1879  int val = 0;
1881 
1882  entry = (MarkCacheKey *) ptr;
1883 
1884  val = (int) (ptrint) entry->f;
1885  val = val * 997 + (int) (ptrint) entry->c;
1886 
1887  return ((val < 0) ? -val : val) % modulus;
1888 
1889 } /* end of MarkCacheHash */
static int * entry
Definition: cuddGroup.c:122
ABC_PTRINT_T ptrint
Definition: cuddInt.h:260
DdNode * f
Definition: cuddGenCof.c:109

Variable Documentation

char rcsid [] DD_UNUSED = "$Id: cuddGenCof.c,v 1.38 2005/05/14 17:27:11 fabio Exp $"
static

Definition at line 118 of file cuddGenCof.c.