SVF
Classes | Macros | Typedefs | Functions | Variables
cuddSat.c File Reference
#include "CUDD/util.h"
#include "CUDD/cuddInt.h"

Go to the source code of this file.

Classes

struct  cuddPathPair
 

Macros

#define DD_BIGGY   100000000
 
#define WEIGHT(weight, col)   ((weight) == NULL ? 1 : weight[col])
 

Typedefs

typedef struct cuddPathPair cuddPathPair
 

Functions

static enum st_retval freePathPair (char *key, char *value, char *arg)
 
static cuddPathPair getShortest (DdNode *root, int *cost, int *support, st_table *visited)
 
static DdNodegetPath (DdManager *manager, st_table *visited, DdNode *f, int *weight, int cost)
 
static cuddPathPair getLargest (DdNode *root, st_table *visited)
 
static DdNodegetCube (DdManager *manager, st_table *visited, DdNode *f, int cost)
 
static DdNodeddBddMaximallyExpand (DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f)
 
static int ddBddShortestPathUnate (DdManager *dd, DdNode *f, int *phases, st_table *table)
 
static DdNodeddGetLargestCubeUnate (DdManager *dd, DdNode *f, int *phases, st_table *table)
 
DdNodeCudd_Eval (DdManager *dd, DdNode *f, int *inputs)
 
DdNodeCudd_ShortestPath (DdManager *manager, DdNode *f, int *weight, int *support, int *length)
 
DdNodeCudd_LargestCube (DdManager *manager, DdNode *f, int *length)
 
int Cudd_ShortestLength (DdManager *manager, DdNode *f, int *weight)
 
DdNodeCudd_Decreasing (DdManager *dd, DdNode *f, int i)
 
DdNodeCudd_Increasing (DdManager *dd, DdNode *f, int i)
 
int Cudd_EquivDC (DdManager *dd, DdNode *F, DdNode *G, DdNode *D)
 
int Cudd_bddLeqUnless (DdManager *dd, DdNode *f, DdNode *g, DdNode *D)
 
int Cudd_EqualSupNorm (DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE tolerance, int pr)
 
DdNodeCudd_bddMakePrime (DdManager *dd, DdNode *cube, DdNode *f)
 
DdNodeCudd_bddMaximallyExpand (DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f)
 
DdNodeCudd_bddLargestPrimeUnate (DdManager *dd, DdNode *f, DdNode *phaseBdd)
 
DdNodecuddBddMakePrime (DdManager *dd, DdNode *cube, DdNode *f)
 

Variables

static char rcsid [] DD_UNUSED = "$Id: cuddSat.c,v 1.39 2012/02/05 01:07:19 fabio Exp $"
 
static DdNodeone
 
static DdNodezero
 

Macro Definition Documentation

◆ DD_BIGGY

#define DD_BIGGY   100000000

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

FileName [cuddSat.c]

PackageName [cudd]

Synopsis [Functions for the solution of satisfiability related problems.]

Description [External procedures included in this file:

Internal procedures included in this module:

Static procedures included in this module:

]

Author [Seh-Woong Jeong, Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 82 of file cuddSat.c.

◆ WEIGHT

#define WEIGHT (   weight,
  col 
)    ((weight) == NULL ? 1 : weight[col])

Definition at line 111 of file cuddSat.c.

Typedef Documentation

◆ cuddPathPair

typedef struct cuddPathPair cuddPathPair

Function Documentation

◆ Cudd_bddLargestPrimeUnate()

DdNode* Cudd_bddLargestPrimeUnate ( DdManager dd,
DdNode f,
DdNode phaseBdd 
)

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

Synopsis [Find a largest prime of a unate function.]

Description [Find a largest prime implicant of a unate function. Returns the BDD for the prime if succesful; NULL otherwise. The behavior is undefined if f is not unate. The third argument is used to determine whether f is unate positive (increasing) or negative (decreasing) in each of the variables in its support.]

SideEffects [None]

SeeAlso [Cudd_bddMaximallyExpand]

Definition at line 941 of file cuddSat.c.

945 {
946  DdNode *res;
947  int *phases;
948  int retval;
949  st_table *table;
950 
951  /* Extract phase vector for quick access. */
952  phases = ALLOC(int, dd->size);
953  if (phases == NULL) return(NULL);
954  retval = Cudd_BddToCubeArray(dd, phaseBdd, phases);
955  if (retval == 0) {
956  FREE(phases);
957  return(NULL);
958  }
959  do {
960  dd->reordered = 0;
962  if (table == NULL) {
963  FREE(phases);
964  return(NULL);
965  }
966  (void) ddBddShortestPathUnate(dd, f, phases, table);
967  res = ddGetLargestCubeUnate(dd, f, phases, table);
968  st_free_table(table);
969  } while (dd->reordered == 1);
970 
971  FREE(phases);
972  return(res);
973 
974 } /* end of Cudd_bddLargestPrimeUnate */
Definition: st.h:60
Definition: cudd.h:270
#define FREE(obj)
Definition: util.h:80
int size
Definition: cuddInt.h:345
void st_free_table(st_table *)
Definition: st.c:252
int reordered
Definition: cuddInt.h:392
#define ALLOC(type, num)
Definition: util.h:76
int st_ptrcmp(const char *, const char *)
Definition: st.c:849
st_table * st_init_table(ST_PFICPCP, ST_PFICPI)
Definition: st.c:163
static DdNode * ddGetLargestCubeUnate(DdManager *dd, DdNode *f, int *phases, st_table *table)
Definition: cuddSat.c:1717
static int ddBddShortestPathUnate(DdManager *dd, DdNode *f, int *phases, st_table *table)
Definition: cuddSat.c:1665
int st_ptrhash(char *, int)
Definition: st.c:811
int Cudd_BddToCubeArray(DdManager *dd, DdNode *cube, int *array)
Definition: cuddUtil.c:2354

◆ Cudd_bddLeqUnless()

int Cudd_bddLeqUnless ( DdManager dd,
DdNode f,
DdNode g,
DdNode D 
)

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

Synopsis [Tells whether f is less than of equal to G unless D is 1.]

Description [Tells whether f is less than of equal to G unless D is

  1. f, g, and D are BDDs. The function returns 1 if f is less than of equal to G, and 0 otherwise. No new nodes are created.]

SideEffects [None]

SeeAlso [Cudd_EquivDC Cudd_bddLeq Cudd_bddIteConstant]

Definition at line 629 of file cuddSat.c.

634 {
635  DdNode *tmp, *One, *F, *G;
636  DdNode *Ft, *Fe, *Gt, *Ge, *Dt, *De;
637  int res;
638  unsigned int flevel, glevel, dlevel, top;
639 
640  statLine(dd);
641 
642  One = DD_ONE(dd);
643 
644  /* Check terminal cases. */
645  if (f == g || g == One || f == Cudd_Not(One) || D == One ||
646  D == f || D == Cudd_Not(g)) return(1);
647  /* Check for two-operand cases. */
648  if (D == Cudd_Not(One) || D == g || D == Cudd_Not(f))
649  return(Cudd_bddLeq(dd,f,g));
650  if (g == Cudd_Not(One) || g == Cudd_Not(f)) return(Cudd_bddLeq(dd,f,D));
651  if (f == One) return(Cudd_bddLeq(dd,Cudd_Not(g),D));
652 
653  /* From now on, f, g, and D are non-constant, distinct, and
654  ** non-complementary. */
655 
656  /* Normalize call to increase cache efficiency. We rely on the
657  ** fact that f <= g unless D is equivalent to not(g) <= not(f)
658  ** unless D and to f <= D unless g. We make sure that D is
659  ** regular, and that at most one of f and g is complemented. We also
660  ** ensure that when two operands can be swapped, the one with the
661  ** lowest address comes first. */
662 
663  if (Cudd_IsComplement(D)) {
664  if (Cudd_IsComplement(g)) {
665  /* Special case: if f is regular and g is complemented,
666  ** f(1,...,1) = 1 > 0 = g(1,...,1). If D(1,...,1) = 0, return 0.
667  */
668  if (!Cudd_IsComplement(f)) return(0);
669  /* !g <= D unless !f or !D <= g unless !f */
670  tmp = D;
671  D = Cudd_Not(f);
672  if (g < tmp) {
673  f = Cudd_Not(g);
674  g = tmp;
675  } else {
676  f = Cudd_Not(tmp);
677  }
678  } else {
679  if (Cudd_IsComplement(f)) {
680  /* !D <= !f unless g or !D <= g unless !f */
681  tmp = f;
682  f = Cudd_Not(D);
683  if (tmp < g) {
684  D = g;
685  g = Cudd_Not(tmp);
686  } else {
687  D = Cudd_Not(tmp);
688  }
689  } else {
690  /* f <= D unless g or !D <= !f unless g */
691  tmp = D;
692  D = g;
693  if (tmp < f) {
694  g = Cudd_Not(f);
695  f = Cudd_Not(tmp);
696  } else {
697  g = tmp;
698  }
699  }
700  }
701  } else {
702  if (Cudd_IsComplement(g)) {
703  if (Cudd_IsComplement(f)) {
704  /* !g <= !f unless D or !g <= D unless !f */
705  tmp = f;
706  f = Cudd_Not(g);
707  if (D < tmp) {
708  g = D;
709  D = Cudd_Not(tmp);
710  } else {
711  g = Cudd_Not(tmp);
712  }
713  } else {
714  /* f <= g unless D or !g <= !f unless D */
715  if (g < f) {
716  tmp = g;
717  g = Cudd_Not(f);
718  f = Cudd_Not(tmp);
719  }
720  }
721  } else {
722  /* f <= g unless D or f <= D unless g */
723  if (D < g) {
724  tmp = D;
725  D = g;
726  g = tmp;
727  }
728  }
729  }
730 
731  /* From now on, D is regular. */
732 
733  /* Check cache. */
734  tmp = cuddCacheLookup(dd,DD_BDD_LEQ_UNLESS_TAG,f,g,D);
735  if (tmp != NULL) return(tmp == One);
736 
737  /* Find splitting variable. */
738  F = Cudd_Regular(f);
739  flevel = dd->perm[F->index];
740  G = Cudd_Regular(g);
741  glevel = dd->perm[G->index];
742  top = ddMin(flevel,glevel);
743  dlevel = dd->perm[D->index];
744  top = ddMin(top,dlevel);
745 
746  /* Compute cofactors. */
747  if (top == flevel) {
748  Ft = cuddT(F);
749  Fe = cuddE(F);
750  if (F != f) {
751  Ft = Cudd_Not(Ft);
752  Fe = Cudd_Not(Fe);
753  }
754  } else {
755  Ft = Fe = f;
756  }
757  if (top == glevel) {
758  Gt = cuddT(G);
759  Ge = cuddE(G);
760  if (G != g) {
761  Gt = Cudd_Not(Gt);
762  Ge = Cudd_Not(Ge);
763  }
764  } else {
765  Gt = Ge = g;
766  }
767  if (top == dlevel) {
768  Dt = cuddT(D);
769  De = cuddE(D);
770  } else {
771  Dt = De = D;
772  }
773 
774  /* Solve recursively. */
775  res = Cudd_bddLeqUnless(dd,Ft,Gt,Dt);
776  if (res != 0) {
777  res = Cudd_bddLeqUnless(dd,Fe,Ge,De);
778  }
780 
781  return(res);
782 
783 } /* end of Cudd_bddLeqUnless */
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
#define Cudd_Regular(node)
Definition: cudd.h:384
#define statLine(dd)
Definition: cuddInt.h:990
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
#define DD_BDD_LEQ_UNLESS_TAG
Definition: cuddInt.h:189
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:645
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:347
DdHalfWord index
Definition: cudd.h:271
#define cuddE(node)
Definition: cuddInt.h:625
#define Cudd_NotCond(node, c)
Definition: cudd.h:370
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:217
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369
int Cudd_bddLeqUnless(DdManager *dd, DdNode *f, DdNode *g, DdNode *D)
Definition: cuddSat.c:629

◆ Cudd_bddMakePrime()

DdNode* Cudd_bddMakePrime ( DdManager dd,
DdNode cube,
DdNode f 
)

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

Synopsis [Expands cube to a prime implicant of f.]

Description [Expands cube to a prime implicant of f. Returns the prime if successful; NULL otherwise. In particular, NULL is returned if cube is not a real cube or is not an implicant of f.]

SideEffects [None]

SeeAlso [Cudd_bddMaximallyExpand]

Definition at line 871 of file cuddSat.c.

875 {
876  DdNode *res;
877 
878  if (!Cudd_bddLeq(dd,cube,f)) return(NULL);
879 
880  do {
881  dd->reordered = 0;
882  res = cuddBddMakePrime(dd,cube,f);
883  } while (dd->reordered == 1);
884  return(res);
885 
886 } /* end of Cudd_bddMakePrime */
Definition: cudd.h:270
DdNode * cuddBddMakePrime(DdManager *dd, DdNode *cube, DdNode *f)
Definition: cuddSat.c:995
int reordered
Definition: cuddInt.h:392
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:645

◆ Cudd_bddMaximallyExpand()

DdNode* Cudd_bddMaximallyExpand ( DdManager dd,
DdNode lb,
DdNode ub,
DdNode f 
)

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

Synopsis [Expands lb to prime implicants of (f and ub).]

Description [Expands lb to all prime implicants of (f and ub) that contain lb. Assumes that lb is contained in ub. Returns the disjunction of the primes if lb is contained in f; returns the zero BDD if lb is not contained in f; returns NULL in case of failure. In particular, NULL is returned if cube is not a real cube or is not an implicant of f. Returning the disjunction of all prime implicants works because the resulting function is unate.]

SideEffects [None]

SeeAlso [Cudd_bddMakePrime]

Definition at line 906 of file cuddSat.c.

911 {
912  DdNode *res;
913 
914  if (!Cudd_bddLeq(dd,lb,ub)) return(NULL);
915 
916  do {
917  dd->reordered = 0;
918  res = ddBddMaximallyExpand(dd,lb,ub,f);
919  } while (dd->reordered == 1);
920  return(res);
921 
922 } /* end of Cudd_bddMaximallyExpand */
Definition: cudd.h:270
int reordered
Definition: cuddInt.h:392
static DdNode * ddBddMaximallyExpand(DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f)
Definition: cuddSat.c:1456
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:645

◆ Cudd_Decreasing()

DdNode* Cudd_Decreasing ( DdManager dd,
DdNode f,
int  i 
)

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

Synopsis [Determines whether a BDD is negative unate in a variable.]

Description [Determines whether the function represented by BDD f is negative unate (monotonic decreasing) in variable i. Returns the constant one is f is unate and the (logical) constant zero if it is not. This function does not generate any new nodes.]

SideEffects [None]

SeeAlso [Cudd_Increasing]

Definition at line 424 of file cuddSat.c.

428 {
429  unsigned int topf, level;
430  DdNode *F, *fv, *fvn, *res;
431  DD_CTFP cacheOp;
432 
433  statLine(dd);
434 #ifdef DD_DEBUG
435  assert(0 <= i && i < dd->size);
436 #endif
437 
438  F = Cudd_Regular(f);
439  topf = cuddI(dd,F->index);
440 
441  /* Check terminal case. If topf > i, f does not depend on var.
442  ** Therefore, f is unate in i.
443  */
444  level = (unsigned) dd->perm[i];
445  if (topf > level) {
446  return(DD_ONE(dd));
447  }
448 
449  /* From now on, f is not constant. */
450 
451  /* Check cache. */
452  cacheOp = (DD_CTFP) Cudd_Decreasing;
453  res = cuddCacheLookup2(dd,cacheOp,f,dd->vars[i]);
454  if (res != NULL) {
455  return(res);
456  }
457 
458  /* Compute cofactors. */
459  fv = cuddT(F); fvn = cuddE(F);
460  if (F != f) {
461  fv = Cudd_Not(fv);
462  fvn = Cudd_Not(fvn);
463  }
464 
465  if (topf == (unsigned) level) {
466  /* Special case: if fv is regular, fv(1,...,1) = 1;
467  ** If in addition fvn is complemented, fvn(1,...,1) = 0.
468  ** But then f(1,1,...,1) > f(0,1,...,1). Hence f is not
469  ** monotonic decreasing in i.
470  */
471  if (!Cudd_IsComplement(fv) && Cudd_IsComplement(fvn)) {
472  return(Cudd_Not(DD_ONE(dd)));
473  }
474  res = Cudd_bddLeq(dd,fv,fvn) ? DD_ONE(dd) : Cudd_Not(DD_ONE(dd));
475  } else {
476  res = Cudd_Decreasing(dd,fv,i);
477  if (res == DD_ONE(dd)) {
478  res = Cudd_Decreasing(dd,fvn,i);
479  }
480  }
481 
482  cuddCacheInsert2(dd,cacheOp,f,dd->vars[i],res);
483  return(res);
484 
485 } /* end of Cudd_Decreasing */
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
#define assert(ex)
Definition: util.h:141
DdNode * cuddCacheLookup2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
#define Cudd_Regular(node)
Definition: cudd.h:384
#define statLine(dd)
Definition: cuddInt.h:990
#define Cudd_IsComplement(node)
Definition: cudd.h:412
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:308
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddI(dd, index)
Definition: cuddInt.h:659
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:645
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdNode * Cudd_Decreasing(DdManager *dd, DdNode *f, int i)
Definition: cuddSat.c:424
DdHalfWord index
Definition: cudd.h:271
DdNode ** vars
Definition: cuddInt.h:373
#define cuddE(node)
Definition: cuddInt.h:625
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369
if(DEFINED IN_SOURCE_BUILD) set(LLVM_LINK_COMPONENTS BitWriter Core IPO IrReader InstCombine Instrumentation Target Linker Analysis ScalarOpts Support Svf Cudd) add_llvm_tool(dvf dda.cpp) else() add_executable(dvf dda.cpp) target_link_libraries(dvf Svf Cudd $
Definition: CMakeLists.txt:2

◆ Cudd_EqualSupNorm()

int Cudd_EqualSupNorm ( DdManager dd,
DdNode f,
DdNode g,
CUDD_VALUE_TYPE  tolerance,
int  pr 
)

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

Synopsis [Compares two ADDs for equality within tolerance.]

Description [Compares two ADDs for equality within tolerance. Two ADDs are reported to be equal if the maximum difference between them (the sup norm of their difference) is less than or equal to the tolerance parameter. Returns 1 if the two ADDs are equal (within tolerance); 0 otherwise. If parameter pr is positive the first failure is reported to the standard output.]

SideEffects [None]

SeeAlso []

Definition at line 803 of file cuddSat.c.

809 {
810  DdNode *fv, *fvn, *gv, *gvn, *r;
811  unsigned int topf, topg;
812 
813  statLine(dd);
814  /* Check terminal cases. */
815  if (f == g) return(1);
816  if (Cudd_IsConstant(f) && Cudd_IsConstant(g)) {
817  if (ddEqualVal(cuddV(f),cuddV(g),tolerance)) {
818  return(1);
819  } else {
820  if (pr>0) {
821  (void) fprintf(dd->out,"Offending nodes:\n");
822  (void) fprintf(dd->out,
823  "f: address = %p\t value = %40.30f\n",
824  (void *) f, cuddV(f));
825  (void) fprintf(dd->out,
826  "g: address = %p\t value = %40.30f\n",
827  (void *) g, cuddV(g));
828  }
829  return(0);
830  }
831  }
832 
833  /* We only insert the result in the cache if the comparison is
834  ** successful. Therefore, if we hit we return 1. */
836  if (r != NULL) {
837  return(1);
838  }
839 
840  /* Compute the cofactors and solve the recursive subproblems. */
841  topf = cuddI(dd,f->index);
842  topg = cuddI(dd,g->index);
843 
844  if (topf <= topg) {fv = cuddT(f); fvn = cuddE(f);} else {fv = fvn = f;}
845  if (topg <= topf) {gv = cuddT(g); gvn = cuddE(g);} else {gv = gvn = g;}
846 
847  if (!Cudd_EqualSupNorm(dd,fv,gv,tolerance,pr)) return(0);
848  if (!Cudd_EqualSupNorm(dd,fvn,gvn,tolerance,pr)) return(0);
849 
851 
852  return(1);
853 
854 } /* end of Cudd_EqualSupNorm */
Definition: cudd.h:270
DdNode * cuddCacheLookup2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
#define Cudd_IsConstant(node)
Definition: cudd.h:339
int Cudd_EqualSupNorm(DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE tolerance, int pr)
Definition: cuddSat.c:803
#define statLine(dd)
Definition: cuddInt.h:990
#define cuddV(node)
Definition: cuddInt.h:641
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:308
FILE * out
Definition: cuddInt.h:423
#define cuddT(node)
Definition: cuddInt.h:609
#define ddEqualVal(x, y, e)
Definition: cuddInt.h:814
#define cuddI(dd, index)
Definition: cuddInt.h:659
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
#define cuddE(node)
Definition: cuddInt.h:625
#define DD_ONE(dd)
Definition: cuddInt.h:864

◆ Cudd_EquivDC()

int Cudd_EquivDC ( DdManager dd,
DdNode F,
DdNode G,
DdNode D 
)

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

Synopsis [Tells whether F and G are identical wherever D is 0.]

Description [Tells whether F and G are identical wherever D is 0. F and G are either two ADDs or two BDDs. D is either a 0-1 ADD or a BDD. The function returns 1 if F and G are equivalent, and 0 otherwise. No new nodes are created.]

SideEffects [None]

SeeAlso [Cudd_bddLeqUnless]

Definition at line 529 of file cuddSat.c.

534 {
535  DdNode *tmp, *One, *Gr, *Dr;
536  DdNode *Fv, *Fvn, *Gv, *Gvn, *Dv, *Dvn;
537  int res;
538  unsigned int flevel, glevel, dlevel, top;
539 
540  One = DD_ONE(dd);
541 
542  statLine(dd);
543  /* Check terminal cases. */
544  if (D == One || F == G) return(1);
545  if (D == Cudd_Not(One) || D == DD_ZERO(dd) || F == Cudd_Not(G)) return(0);
546 
547  /* From now on, D is non-constant. */
548 
549  /* Normalize call to increase cache efficiency. */
550  if (F > G) {
551  tmp = F;
552  F = G;
553  G = tmp;
554  }
555  if (Cudd_IsComplement(F)) {
556  F = Cudd_Not(F);
557  G = Cudd_Not(G);
558  }
559 
560  /* From now on, F is regular. */
561 
562  /* Check cache. */
563  tmp = cuddCacheLookup(dd,DD_EQUIV_DC_TAG,F,G,D);
564  if (tmp != NULL) return(tmp == One);
565 
566  /* Find splitting variable. */
567  flevel = cuddI(dd,F->index);
568  Gr = Cudd_Regular(G);
569  glevel = cuddI(dd,Gr->index);
570  top = ddMin(flevel,glevel);
571  Dr = Cudd_Regular(D);
572  dlevel = dd->perm[Dr->index];
573  top = ddMin(top,dlevel);
574 
575  /* Compute cofactors. */
576  if (top == flevel) {
577  Fv = cuddT(F);
578  Fvn = cuddE(F);
579  } else {
580  Fv = Fvn = F;
581  }
582  if (top == glevel) {
583  Gv = cuddT(Gr);
584  Gvn = cuddE(Gr);
585  if (G != Gr) {
586  Gv = Cudd_Not(Gv);
587  Gvn = Cudd_Not(Gvn);
588  }
589  } else {
590  Gv = Gvn = G;
591  }
592  if (top == dlevel) {
593  Dv = cuddT(Dr);
594  Dvn = cuddE(Dr);
595  if (D != Dr) {
596  Dv = Cudd_Not(Dv);
597  Dvn = Cudd_Not(Dvn);
598  }
599  } else {
600  Dv = Dvn = D;
601  }
602 
603  /* Solve recursively. */
604  res = Cudd_EquivDC(dd,Fv,Gv,Dv);
605  if (res != 0) {
606  res = Cudd_EquivDC(dd,Fvn,Gvn,Dvn);
607  }
608  cuddCacheInsert(dd,DD_EQUIV_DC_TAG,F,G,D,(res) ? One : Cudd_Not(One));
609 
610  return(res);
611 
612 } /* end of Cudd_EquivDC */
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
int Cudd_EquivDC(DdManager *dd, DdNode *F, DdNode *G, DdNode *D)
Definition: cuddSat.c:529
#define Cudd_Regular(node)
Definition: cudd.h:384
#define statLine(dd)
Definition: cuddInt.h:990
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddI(dd, index)
Definition: cuddInt.h:659
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:347
#define DD_EQUIV_DC_TAG
Definition: cuddInt.h:183
DdHalfWord index
Definition: cudd.h:271
#define cuddE(node)
Definition: cuddInt.h:625
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:217
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ Cudd_Eval()

DdNode* Cudd_Eval ( DdManager dd,
DdNode f,
int *  inputs 
)

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

Synopsis [Returns the value of a DD for a given variable assignment.]

Description [Finds the value of a DD for a given variable assignment. The variable assignment is passed in an array of int's, that should specify a zero or a one for each variable in the support of the function. Returns a pointer to a constant node. No new nodes are produced.]

SideEffects [None]

SeeAlso [Cudd_bddLeq Cudd_addEvalConst]

Definition at line 159 of file cuddSat.c.

163 {
164  int comple;
165  DdNode *ptr;
166 
167  comple = Cudd_IsComplement(f);
168  ptr = Cudd_Regular(f);
169 
170  while (!cuddIsConstant(ptr)) {
171  if (inputs[ptr->index] == 1) {
172  ptr = cuddT(ptr);
173  } else {
174  comple ^= Cudd_IsComplement(cuddE(ptr));
175  ptr = Cudd_Regular(cuddE(ptr));
176  }
177  }
178  return(Cudd_NotCond(ptr,comple));
179 
180 } /* end of Cudd_Eval */
Definition: cudd.h:270
#define Cudd_Regular(node)
Definition: cudd.h:384
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:271
#define cuddE(node)
Definition: cuddInt.h:625
#define Cudd_NotCond(node, c)
Definition: cudd.h:370

◆ Cudd_Increasing()

DdNode* Cudd_Increasing ( DdManager dd,
DdNode f,
int  i 
)

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

Synopsis [Determines whether a BDD is positive unate in a variable.]

Description [Determines whether the function represented by BDD f is positive unate (monotonic increasing) in variable i. It is based on Cudd_Decreasing and the fact that f is monotonic increasing in i if and only if its complement is monotonic decreasing in i.]

SideEffects [None]

SeeAlso [Cudd_Decreasing]

Definition at line 504 of file cuddSat.c.

508 {
509  return(Cudd_Decreasing(dd,Cudd_Not(f),i));
510 
511 } /* end of Cudd_Increasing */
#define Cudd_Not(node)
Definition: cudd.h:354
DdNode * Cudd_Decreasing(DdManager *dd, DdNode *f, int i)
Definition: cuddSat.c:424

◆ Cudd_LargestCube()

DdNode* Cudd_LargestCube ( DdManager manager,
DdNode f,
int *  length 
)

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

Synopsis [Finds a largest cube in a DD.]

Description [Finds a largest cube in a DD. f is the DD we want to get the largest cube for. The problem is translated into the one of finding a shortest path in f, when both THEN and ELSE arcs are assumed to have unit length. This yields a largest cube in the disjoint cover corresponding to the DD. Therefore, it is not necessarily the largest implicant of f. Returns the largest cube as a BDD.]

SideEffects [The number of literals of the cube is returned in the location pointed by length if it is non-null.]

SeeAlso [Cudd_ShortestPath]

Definition at line 288 of file cuddSat.c.

292 {
293  register DdNode *F;
294  st_table *visited;
295  DdNode *sol;
296  cuddPathPair *rootPair;
297  int complement, cost;
298 
299  one = DD_ONE(manager);
300  zero = DD_ZERO(manager);
301 
302  if (f == Cudd_Not(one) || f == zero) {
303  if (length != NULL) {
304  *length = DD_BIGGY;
305  }
306  return(Cudd_Not(one));
307  }
308  /* From this point on, a path exists. */
309 
310  do {
311  manager->reordered = 0;
312 
313  /* Initialize visited table. */
314  visited = st_init_table(st_ptrcmp, st_ptrhash);
315 
316  /* Now get the length of the shortest path(s) from f to 1. */
317  (void) getLargest(f, visited);
318 
319  complement = Cudd_IsComplement(f);
320 
321  F = Cudd_Regular(f);
322 
323  if (!st_lookup(visited, F, &rootPair)) return(NULL);
324 
325  if (complement) {
326  cost = rootPair->neg;
327  } else {
328  cost = rootPair->pos;
329  }
330 
331  /* Recover an actual shortest path. */
332  sol = getCube(manager,visited,f,cost);
333 
334  st_foreach(visited, freePathPair, NULL);
335  st_free_table(visited);
336 
337  } while (manager->reordered == 1);
338 
339  if (length != NULL) {
340  *length = cost;
341  }
342  return(sol);
343 
344 } /* end of Cudd_LargestCube */
int st_lookup(st_table *, void *, void *)
Definition: st.c:286
Definition: st.h:60
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
int st_foreach(st_table *, ST_PFSR, char *)
Definition: st.c:725
void st_free_table(st_table *)
Definition: st.c:252
#define Cudd_Regular(node)
Definition: cudd.h:384
static enum st_retval freePathPair(char *key, char *value, char *arg)
Definition: cuddSat.c:1060
int reordered
Definition: cuddInt.h:392
static DdNode * one
Definition: cuddSat.c:105
#define Cudd_IsComplement(node)
Definition: cudd.h:412
int st_ptrcmp(const char *, const char *)
Definition: st.c:849
st_table * st_init_table(ST_PFICPCP, ST_PFICPI)
Definition: st.c:163
static DdNode * getCube(DdManager *manager, st_table *visited, DdNode *f, int cost)
Definition: cuddSat.c:1370
static DdNode * zero
Definition: cuddSat.c:105
int st_ptrhash(char *, int)
Definition: st.c:811
#define DD_BIGGY
Definition: cuddSat.c:82
#define DD_ONE(dd)
Definition: cuddInt.h:864
static cuddPathPair getLargest(DdNode *root, st_table *visited)
Definition: cuddSat.c:1282
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ Cudd_ShortestLength()

int Cudd_ShortestLength ( DdManager manager,
DdNode f,
int *  weight 
)

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

Synopsis [Find the length of the shortest path(s) in a DD.]

Description [Find the length of the shortest path(s) in a DD. f is the DD we want to get the shortest path for; weight[i] is the weight of the THEN edge coming from the node whose index is i. All ELSE edges have 0 weight. Returns the length of the shortest path(s) if such a path is found; a large number if the function is identically 0, and CUDD_OUT_OF_MEM in case of failure.]

SideEffects [None]

SeeAlso [Cudd_ShortestPath]

Definition at line 364 of file cuddSat.c.

368 {
369  register DdNode *F;
370  st_table *visited;
371  cuddPathPair *my_pair;
372  int complement, cost;
373 
374  one = DD_ONE(manager);
375  zero = DD_ZERO(manager);
376 
377  if (f == Cudd_Not(one) || f == zero) {
378  return(DD_BIGGY);
379  }
380 
381  /* From this point on, a path exists. */
382  /* Initialize visited table and support. */
383  visited = st_init_table(st_ptrcmp, st_ptrhash);
384 
385  /* Now get the length of the shortest path(s) from f to 1. */
386  (void) getShortest(f, weight, NULL, visited);
387 
388  complement = Cudd_IsComplement(f);
389 
390  F = Cudd_Regular(f);
391 
392  if (!st_lookup(visited, F, &my_pair)) return(CUDD_OUT_OF_MEM);
393 
394  if (complement) {
395  cost = my_pair->neg;
396  } else {
397  cost = my_pair->pos;
398  }
399 
400  st_foreach(visited, freePathPair, NULL);
401  st_free_table(visited);
402 
403  return(cost);
404 
405 } /* end of Cudd_ShortestLength */
#define CUDD_OUT_OF_MEM
Definition: cudd.h:91
int st_lookup(st_table *, void *, void *)
Definition: st.c:286
Definition: st.h:60
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
int st_foreach(st_table *, ST_PFSR, char *)
Definition: st.c:725
void st_free_table(st_table *)
Definition: st.c:252
#define Cudd_Regular(node)
Definition: cudd.h:384
static enum st_retval freePathPair(char *key, char *value, char *arg)
Definition: cuddSat.c:1060
static DdNode * one
Definition: cuddSat.c:105
static cuddPathPair getShortest(DdNode *root, int *cost, int *support, st_table *visited)
Definition: cuddSat.c:1093
#define Cudd_IsComplement(node)
Definition: cudd.h:412
int st_ptrcmp(const char *, const char *)
Definition: st.c:849
st_table * st_init_table(ST_PFICPCP, ST_PFICPI)
Definition: st.c:163
static DdNode * zero
Definition: cuddSat.c:105
int st_ptrhash(char *, int)
Definition: st.c:811
#define DD_BIGGY
Definition: cuddSat.c:82
#define DD_ONE(dd)
Definition: cuddInt.h:864
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ Cudd_ShortestPath()

DdNode* Cudd_ShortestPath ( DdManager manager,
DdNode f,
int *  weight,
int *  support,
int *  length 
)

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

Synopsis [Finds a shortest path in a DD.]

Description [Finds a shortest path in a DD. f is the DD we want to get the shortest path for; weight[i] is the weight of the THEN arc coming from the node whose index is i. If weight is NULL, then unit weights are assumed for all THEN arcs. All ELSE arcs have 0 weight. If non-NULL, both weight and support should point to arrays with at least as many entries as there are variables in the manager. Returns the shortest path as the BDD of a cube.]

SideEffects [support contains on return the true support of f. If support is NULL on entry, then Cudd_ShortestPath does not compute the true support info. length contains the length of the path.]

SeeAlso [Cudd_ShortestLength Cudd_LargestCube]

Definition at line 203 of file cuddSat.c.

209 {
210  DdNode *F;
211  st_table *visited;
212  DdNode *sol;
213  cuddPathPair *rootPair;
214  int complement, cost;
215  int i;
216 
217  one = DD_ONE(manager);
218  zero = DD_ZERO(manager);
219 
220  /* Initialize support. Support does not depend on variable order.
221  ** Hence, it does not need to be reinitialized if reordering occurs.
222  */
223  if (support) {
224  for (i = 0; i < manager->size; i++) {
225  support[i] = 0;
226  }
227  }
228 
229  if (f == Cudd_Not(one) || f == zero) {
230  *length = DD_BIGGY;
231  return(Cudd_Not(one));
232  }
233  /* From this point on, a path exists. */
234 
235  do {
236  manager->reordered = 0;
237 
238  /* Initialize visited table. */
239  visited = st_init_table(st_ptrcmp, st_ptrhash);
240 
241  /* Now get the length of the shortest path(s) from f to 1. */
242  (void) getShortest(f, weight, support, visited);
243 
244  complement = Cudd_IsComplement(f);
245 
246  F = Cudd_Regular(f);
247 
248  if (!st_lookup(visited, F, &rootPair)) return(NULL);
249 
250  if (complement) {
251  cost = rootPair->neg;
252  } else {
253  cost = rootPair->pos;
254  }
255 
256  /* Recover an actual shortest path. */
257  sol = getPath(manager,visited,f,weight,cost);
258 
259  st_foreach(visited, freePathPair, NULL);
260  st_free_table(visited);
261 
262  } while (manager->reordered == 1);
263 
264  *length = cost;
265  return(sol);
266 
267 } /* end of Cudd_ShortestPath */
int st_lookup(st_table *, void *, void *)
Definition: st.c:286
Definition: st.h:60
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
int st_foreach(st_table *, ST_PFSR, char *)
Definition: st.c:725
int size
Definition: cuddInt.h:345
void st_free_table(st_table *)
Definition: st.c:252
#define Cudd_Regular(node)
Definition: cudd.h:384
static enum st_retval freePathPair(char *key, char *value, char *arg)
Definition: cuddSat.c:1060
int reordered
Definition: cuddInt.h:392
static DdNode * one
Definition: cuddSat.c:105
static cuddPathPair getShortest(DdNode *root, int *cost, int *support, st_table *visited)
Definition: cuddSat.c:1093
#define Cudd_IsComplement(node)
Definition: cudd.h:412
static DdNode * getPath(DdManager *manager, st_table *visited, DdNode *f, int *weight, int cost)
Definition: cuddSat.c:1189
int st_ptrcmp(const char *, const char *)
Definition: st.c:849
st_table * st_init_table(ST_PFICPCP, ST_PFICPI)
Definition: st.c:163
static DdNode * zero
Definition: cuddSat.c:105
int st_ptrhash(char *, int)
Definition: st.c:811
#define DD_BIGGY
Definition: cuddSat.c:82
#define DD_ONE(dd)
Definition: cuddInt.h:864
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddBddMakePrime()

DdNode* cuddBddMakePrime ( DdManager dd,
DdNode cube,
DdNode f 
)

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

Synopsis [Performs the recursive step of Cudd_bddMakePrime.]

Description [Performs the recursive step of Cudd_bddMakePrime. Returns the prime if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 995 of file cuddSat.c.

999 {
1000  DdNode *scan;
1001  DdNode *t, *e;
1002  DdNode *res = cube;
1003  DdNode *zero = Cudd_Not(DD_ONE(dd));
1004 
1005  Cudd_Ref(res);
1006  scan = cube;
1007  while (!Cudd_IsConstant(scan)) {
1008  DdNode *reg = Cudd_Regular(scan);
1009  DdNode *var = dd->vars[reg->index];
1010  DdNode *expanded = Cudd_bddExistAbstract(dd,res,var);
1011  if (expanded == NULL) {
1012  Cudd_RecursiveDeref(dd,res);
1013  return(NULL);
1014  }
1015  Cudd_Ref(expanded);
1016  if (Cudd_bddLeq(dd,expanded,f)) {
1017  Cudd_RecursiveDeref(dd,res);
1018  res = expanded;
1019  } else {
1020  Cudd_RecursiveDeref(dd,expanded);
1021  }
1022  cuddGetBranches(scan,&t,&e);
1023  if (t == zero) {
1024  scan = e;
1025  } else if (e == zero) {
1026  scan = t;
1027  } else {
1028  Cudd_RecursiveDeref(dd,res);
1029  return(NULL); /* cube is not a cube */
1030  }
1031  }
1032 
1033  if (scan == DD_ONE(dd)) {
1034  Cudd_Deref(res);
1035  return(res);
1036  } else {
1037  Cudd_RecursiveDeref(dd,res);
1038  return(NULL);
1039  }
1040 
1041 } /* end of cuddBddMakePrime */
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:150
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:434
#define Cudd_IsConstant(node)
Definition: cudd.h:339
#define Cudd_Regular(node)
Definition: cudd.h:384
DdNode * Cudd_bddExistAbstract(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:127
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:645
void cuddGetBranches(DdNode *g, DdNode **g1, DdNode **g0)
Definition: cuddCof.c:196
DdHalfWord index
Definition: cudd.h:271
DdNode ** vars
Definition: cuddInt.h:373
static DdNode * zero
Definition: cuddSat.c:105
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:125
#define DD_ONE(dd)
Definition: cuddInt.h:864

◆ ddBddMaximallyExpand()

static DdNode * ddBddMaximallyExpand ( DdManager dd,
DdNode lb,
DdNode ub,
DdNode f 
)
static

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

Synopsis [Performs the recursive step of Cudd_bddMaximallyExpand.]

Description [Performs the recursive step of Cudd_bddMaximallyExpand. Returns set of primes or zero BDD if successful; NULL otherwise. On entry to this function, ub and lb should be different from the zero BDD. The function then maintains this invariant.]

SideEffects [None]

SeeAlso []

There are three major terminal cases in theory: ub -> f : return ub lb == f : return lb not(lb -> f): return zero Only the second case can be checked exactly in constant time. For the others, we check for sufficient conditions.

Definition at line 1456 of file cuddSat.c.

1461 {
1462  DdNode *one, *zero, *lbv, *lbvn, *lbnx, *ubv, *ubvn, *fv, *fvn, *res;
1463  DdNode *F, *UB, *LB, *t, *e;
1464  unsigned int top, toplb, topub, topf, index;
1465 
1466  statLine(dd);
1467  /* Terminal cases. */
1468  one = DD_ONE(dd);
1469  zero = Cudd_Not(one);
1470  assert(ub != zero && lb != zero);
1478  if (ub == f || f == one) return(ub);
1479  if (lb == f) return(lb);
1480  if (f == zero || ub == Cudd_Not(f) || lb == one || lb == Cudd_Not(f))
1481  return(zero);
1482  if (!Cudd_IsComplement(lb) && Cudd_IsComplement(f)) return(zero);
1483 
1484  /* Here lb and f are not constant. */
1485 
1486  /* Check cache. Since lb and ub are cubes, their local reference counts
1487  ** are always 1. Hence, we only check the reference count of f.
1488  */
1489  F = Cudd_Regular(f);
1490  if (F->ref != 1) {
1491  DdNode *tmp = cuddCacheLookup(dd, DD_BDD_MAX_EXP_TAG, lb, ub, f);
1492  if (tmp != NULL) {
1493  return(tmp);
1494  }
1495  }
1496 
1497  /* Compute cofactors. For lb we use the non-zero one in
1498  ** both branches of the recursion.
1499  */
1500  LB = Cudd_Regular(lb);
1501  UB = Cudd_Regular(ub);
1502  topf = dd->perm[F->index];
1503  toplb = dd->perm[LB->index];
1504  topub = (ub == one) ? CUDD_CONST_INDEX : dd->perm[UB->index];
1505  assert(toplb <= topub);
1506  top = ddMin(topf,toplb);
1507  if (toplb == top) {
1508  index = LB->index;
1509  lbv = cuddT(LB);
1510  lbvn = cuddE(LB);
1511  if (lb != LB) {
1512  lbv = Cudd_Not(lbv);
1513  lbvn = Cudd_Not(lbvn);
1514  }
1515  if (lbv == zero) {
1516  lbnx = lbvn;
1517  } else {
1518  lbnx = lbv;
1519  }
1520  } else {
1521  index = F->index;
1522  lbnx = lbv = lbvn = lb;
1523  }
1524  if (topub == top) {
1525  ubv = cuddT(UB);
1526  ubvn = cuddE(UB);
1527  if (ub != UB) {
1528  ubv = Cudd_Not(ubv);
1529  ubvn = Cudd_Not(ubvn);
1530  }
1531  } else {
1532  ubv = ubvn = ub;
1533  }
1534  if (topf == top) {
1535  fv = cuddT(F);
1536  fvn = cuddE(F);
1537  if (f != F) {
1538  fv = Cudd_Not(fv);
1539  fvn = Cudd_Not(fvn);
1540  }
1541  } else {
1542  fv = fvn = f;
1543  }
1544 
1545  /* Recursive calls. */
1546  if (ubv != zero) {
1547  t = ddBddMaximallyExpand(dd, lbnx, ubv, fv);
1548  if (t == NULL) return(NULL);
1549  } else {
1550  assert(topub == toplb && topub == top && lbv == zero);
1551  t = zero;
1552  }
1553  cuddRef(t);
1554 
1555  /* If the top variable appears only in lb, the positive and negative
1556  ** cofactors of each operand are the same. We want to avoid a
1557  ** needless recursive call, which would force us to give up the
1558  ** cache optimization trick based on reference counts.
1559  */
1560  if (ubv == ubvn && fv == fvn) {
1561  res = t;
1562  } else {
1563  if (ubvn != zero) {
1564  e = ddBddMaximallyExpand(dd, lbnx, ubvn, fvn);
1565  if (e == NULL) {
1566  Cudd_IterDerefBdd(dd,t);
1567  return(NULL);
1568  }
1569  } else {
1570  assert(topub == toplb && topub == top && lbvn == zero);
1571  e = zero;
1572  }
1573 
1574  if (t == e) {
1575  res = t;
1576  } else {
1577  cuddRef(e);
1578 
1579  if (toplb == top) {
1580  if (lbv == zero) {
1581  /* Top variable appears in negative phase. */
1582  if (t != one) {
1583  DdNode *newT;
1584  if (Cudd_IsComplement(t)) {
1585  newT = cuddUniqueInter(dd, index, Cudd_Not(t), zero);
1586  if (newT == NULL) {
1587  Cudd_IterDerefBdd(dd,t);
1588  Cudd_IterDerefBdd(dd,e);
1589  return(NULL);
1590  }
1591  newT = Cudd_Not(newT);
1592  } else {
1593  newT = cuddUniqueInter(dd, index, t, one);
1594  if (newT == NULL) {
1595  Cudd_IterDerefBdd(dd,t);
1596  Cudd_IterDerefBdd(dd,e);
1597  return(NULL);
1598  }
1599  }
1600  cuddRef(newT);
1601  cuddDeref(t);
1602  t = newT;
1603  }
1604  } else if (lbvn == zero) {
1605  /* Top variable appears in positive phase. */
1606  if (e != one) {
1607  DdNode *newE;
1608  newE = cuddUniqueInter(dd, index, one, e);
1609  if (newE == NULL) {
1610  Cudd_IterDerefBdd(dd,t);
1611  Cudd_IterDerefBdd(dd,e);
1612  return(NULL);
1613  }
1614  cuddRef(newE);
1615  cuddDeref(e);
1616  e = newE;
1617  }
1618  } else {
1619  /* Not a cube. */
1620  Cudd_IterDerefBdd(dd,t);
1621  Cudd_IterDerefBdd(dd,e);
1622  return(NULL);
1623  }
1624  }
1625 
1626  /* Combine results. */
1627  res = cuddBddAndRecur(dd, t, e);
1628  if (res == NULL) {
1629  Cudd_IterDerefBdd(dd,t);
1630  Cudd_IterDerefBdd(dd,e);
1631  return(NULL);
1632  }
1633  cuddRef(res);
1634  Cudd_IterDerefBdd(dd,t);
1635  Cudd_IterDerefBdd(dd,e);
1636  }
1637  }
1638 
1639  /* Cache result and return. */
1640  if (F->ref != 1) {
1641  cuddCacheInsert(dd, DD_BDD_MAX_EXP_TAG, lb, ub, f, res);
1642  }
1643  cuddDeref(res);
1644  return(res);
1645 
1646 } /* end of ddBddMaximallyExpand */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:213
DdHalfWord ref
Definition: cudd.h:272
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
#define assert(ex)
Definition: util.h:141
#define Cudd_Regular(node)
Definition: cudd.h:384
#define DD_BDD_MAX_EXP_TAG
Definition: cuddInt.h:191
#define statLine(dd)
Definition: cuddInt.h:990
static DdNode * one
Definition: cuddSat.c:105
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define CUDD_CONST_INDEX
Definition: cudd.h:113
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
static DdNode * ddBddMaximallyExpand(DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f)
Definition: cuddSat.c:1456
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:347
DdHalfWord index
Definition: cudd.h:271
static DdNode * zero
Definition: cuddSat.c:105
#define cuddE(node)
Definition: cuddInt.h:625
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:217
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1137

◆ ddBddShortestPathUnate()

static int ddBddShortestPathUnate ( DdManager dd,
DdNode f,
int *  phases,
st_table table 
)
static

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

Synopsis [Performs shortest path computation on a unate function.]

Description [Performs shortest path computation on a unate function. Returns the length of the shortest path to one if successful; CUDD_OUT_OF_MEM otherwise. This function is based on the observation that in the BDD of a unate function no node except the constant is reachable from the root via paths of different parity.]

SideEffects [None]

SeeAlso [getShortest]

Definition at line 1665 of file cuddSat.c.

1670 {
1671  int positive, l, lT, lE;
1672  DdNode *one = DD_ONE(dd);
1673  DdNode *zero = Cudd_Not(one);
1674  DdNode *F, *fv, *fvn;
1675 
1676  if (st_lookup_int(table, f, &l)) {
1677  return(l);
1678  }
1679  if (f == one) {
1680  l = 0;
1681  } else if (f == zero) {
1682  l = DD_BIGGY;
1683  } else {
1684  F = Cudd_Regular(f);
1685  fv = cuddT(F);
1686  fvn = cuddE(F);
1687  if (f != F) {
1688  fv = Cudd_Not(fv);
1689  fvn = Cudd_Not(fvn);
1690  }
1691  lT = ddBddShortestPathUnate(dd, fv, phases, table);
1692  lE = ddBddShortestPathUnate(dd, fvn, phases, table);
1693  positive = phases[F->index];
1694  l = positive ? ddMin(lT+1, lE) : ddMin(lT, lE+1);
1695  }
1696  if (st_insert(table, f, (void *)(ptrint) l) == ST_OUT_OF_MEM) {
1697  return(CUDD_OUT_OF_MEM);
1698  }
1699  return(l);
1700 
1701 } /* end of ddShortestPathUnate */
int ptrint
Definition: cuddInt.h:249
#define CUDD_OUT_OF_MEM
Definition: cudd.h:91
int st_lookup_int(st_table *, void *, int *)
Definition: st.c:322
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
#define Cudd_Regular(node)
Definition: cudd.h:384
int st_insert(st_table *, void *, void *)
Definition: st.c:358
static DdNode * one
Definition: cuddSat.c:105
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
#define ST_OUT_OF_MEM
Definition: st.h:41
DdHalfWord index
Definition: cudd.h:271
static int ddBddShortestPathUnate(DdManager *dd, DdNode *f, int *phases, st_table *table)
Definition: cuddSat.c:1665
static DdNode * zero
Definition: cuddSat.c:105
#define cuddE(node)
Definition: cuddInt.h:625
#define DD_BIGGY
Definition: cuddSat.c:82
#define DD_ONE(dd)
Definition: cuddInt.h:864

◆ ddGetLargestCubeUnate()

static DdNode * ddGetLargestCubeUnate ( DdManager dd,
DdNode f,
int *  phases,
st_table table 
)
static

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

Synopsis [Extracts largest prime of a unate function.]

Description [Extracts largest prime of a unate function. Returns the BDD of the prime if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [getPath]

Definition at line 1717 of file cuddSat.c.

1722 {
1723  DdNode *res, *scan;
1724  DdNode *one = DD_ONE(dd);
1725  int cost;
1726 
1727  res = one;
1728  cuddRef(res);
1729  scan = f;
1730  st_lookup_int(table, scan, &cost);
1731 
1732  while (!Cudd_IsConstant(scan)) {
1733  int Pcost, Ncost, Tcost;
1734  DdNode *tmp, *T, *E;
1735  DdNode *rscan = Cudd_Regular(scan);
1736  int index = rscan->index;
1737  assert(phases[index] == 0 || phases[index] == 1);
1738  int positive = phases[index] == 1;
1739  Pcost = positive ? cost - 1 : cost;
1740  Ncost = positive ? cost : cost - 1;
1741  T = cuddT(rscan);
1742  E = cuddE(rscan);
1743  if (rscan != scan) {
1744  T = Cudd_Not(T);
1745  E = Cudd_Not(E);
1746  }
1747  tmp = res;
1748  st_lookup_int(table, T, &Tcost);
1749  if (Tcost == Pcost) {
1750  cost = Pcost;
1751  scan = T;
1752  if (positive) {
1753  tmp = cuddBddAndRecur(dd, dd->vars[index], res);
1754  }
1755  } else {
1756  cost = Ncost;
1757  scan = E;
1758  if (!positive) {
1759  tmp = cuddBddAndRecur(dd, Cudd_Not(dd->vars[index]), res);
1760  }
1761  }
1762  if (tmp == NULL) {
1763  Cudd_IterDerefBdd(dd, res);
1764  return(NULL);
1765  }
1766  cuddRef(tmp);
1767  Cudd_IterDerefBdd(dd, res);
1768  res = tmp;
1769  }
1770 
1771  cuddDeref(res);
1772  return(res);
1773 
1774 } /* end of ddGetLargestCubeUnate */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:213
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
int st_lookup_int(st_table *, void *, int *)
Definition: st.c:322
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
#define assert(ex)
Definition: util.h:141
#define Cudd_IsConstant(node)
Definition: cudd.h:339
#define Cudd_Regular(node)
Definition: cudd.h:384
static DdNode * one
Definition: cuddSat.c:105
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995
DdHalfWord index
Definition: cudd.h:271
DdNode ** vars
Definition: cuddInt.h:373
#define cuddE(node)
Definition: cuddInt.h:625
#define DD_ONE(dd)
Definition: cuddInt.h:864

◆ freePathPair()

static enum st_retval freePathPair ( char *  key,
char *  value,
char *  arg 
)
static

AutomaticStart

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

Synopsis [Frees the entries of the visited symbol table.]

Description [Frees the entries of the visited symbol table. Returns ST_CONTINUE.]

SideEffects [None]

Definition at line 1060 of file cuddSat.c.

1064 {
1065  cuddPathPair *pair;
1066 
1067  pair = (cuddPathPair *) value;
1068  FREE(pair);
1069  return(ST_CONTINUE);
1070 
1071 } /* end of freePathPair */
#define FREE(obj)
Definition: util.h:80
Definition: st.h:78

◆ getCube()

static DdNode * getCube ( DdManager manager,
st_table visited,
DdNode f,
int  cost 
)
static

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

Synopsis [Build a BDD for a largest cube of f.]

Description [Build a BDD for a largest cube of f. Given the minimum length from the root, and the minimum lengths for each node (in visited), apply triangulation at each node. Of the two children of each node on a shortest path, at least one is on a shortest path. In case of ties the procedure chooses the THEN children. Returns a pointer to the cube BDD representing the path if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 1370 of file cuddSat.c.

1375 {
1376  DdNode *sol, *tmp;
1377  DdNode *my_dd, *T, *E;
1378  cuddPathPair *T_pair, *E_pair;
1379  int Tcost, Ecost;
1380  int complement;
1381 
1382  my_dd = Cudd_Regular(f);
1383  complement = Cudd_IsComplement(f);
1384 
1385  sol = one;
1386  cuddRef(sol);
1387 
1388  while (!cuddIsConstant(my_dd)) {
1389  Tcost = cost - 1;
1390  Ecost = cost - 1;
1391 
1392  T = cuddT(my_dd);
1393  E = cuddE(my_dd);
1394 
1395  if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);}
1396 
1397  if (!st_lookup(visited, Cudd_Regular(T), &T_pair)) return(NULL);
1398  if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) ||
1399  (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) {
1400  tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol);
1401  if (tmp == NULL) {
1402  Cudd_RecursiveDeref(manager,sol);
1403  return(NULL);
1404  }
1405  cuddRef(tmp);
1406  Cudd_RecursiveDeref(manager,sol);
1407  sol = tmp;
1408 
1409  complement = Cudd_IsComplement(T);
1410  my_dd = Cudd_Regular(T);
1411  cost = Tcost;
1412  continue;
1413  }
1414  if (!st_lookup(visited, Cudd_Regular(E), &E_pair)) return(NULL);
1415  if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) ||
1416  (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) {
1417  tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol);
1418  if (tmp == NULL) {
1419  Cudd_RecursiveDeref(manager,sol);
1420  return(NULL);
1421  }
1422  cuddRef(tmp);
1423  Cudd_RecursiveDeref(manager,sol);
1424  sol = tmp;
1425  complement = Cudd_IsComplement(E);
1426  my_dd = Cudd_Regular(E);
1427  cost = Ecost;
1428  continue;
1429  }
1430  (void) fprintf(manager->err,"We shouldn't be here!\n");
1431  manager->errorCode = CUDD_INTERNAL_ERROR;
1432  return(NULL);
1433  }
1434 
1435  cuddDeref(sol);
1436  return(sol);
1437 
1438 } /* end of getCube */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
int st_lookup(st_table *, void *, void *)
Definition: st.c:286
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:150
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
#define Cudd_Regular(node)
Definition: cudd.h:384
FILE * err
Definition: cuddInt.h:424
static DdNode * one
Definition: cuddSat.c:105
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995
DdHalfWord index
Definition: cudd.h:271
DdNode ** vars
Definition: cuddInt.h:373
#define cuddE(node)
Definition: cuddInt.h:625
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ getLargest()

static cuddPathPair getLargest ( DdNode root,
st_table visited 
)
static

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

Synopsis [Finds the size of the largest cube(s) in a DD.]

Description [Finds the size of the largest cube(s) in a DD. This problem is translated into finding the shortest paths from a node when both THEN and ELSE arcs have unit lengths. Uses a local symbol table to store the lengths for each node. Only the lengths for the regular nodes are entered in the table, because those for the complement nodes are simply obtained by swapping the two lenghts. Returns a pair of lengths: the length of the shortest path to 1; and the length of the shortest path to 0. This is done so as to take complement arcs into account.]

SideEffects [none]

SeeAlso []

Definition at line 1282 of file cuddSat.c.

1285 {
1286  cuddPathPair *my_pair, res_pair, pair_T, pair_E;
1287  DdNode *my_root, *T, *E;
1288 
1289  my_root = Cudd_Regular(root);
1290 
1291  if (st_lookup(visited, my_root, &my_pair)) {
1292  if (Cudd_IsComplement(root)) {
1293  res_pair.pos = my_pair->neg;
1294  res_pair.neg = my_pair->pos;
1295  } else {
1296  res_pair.pos = my_pair->pos;
1297  res_pair.neg = my_pair->neg;
1298  }
1299  return(res_pair);
1300  }
1301 
1302  /* In the case of a BDD the following test is equivalent to
1303  ** testing whether the BDD is the constant 1. This formulation,
1304  ** however, works for ADDs as well, by assuming the usual
1305  ** dichotomy of 0 and != 0.
1306  */
1307  if (cuddIsConstant(my_root)) {
1308  if (my_root != zero) {
1309  res_pair.pos = 0;
1310  res_pair.neg = DD_BIGGY;
1311  } else {
1312  res_pair.pos = DD_BIGGY;
1313  res_pair.neg = 0;
1314  }
1315  } else {
1316  T = cuddT(my_root);
1317  E = cuddE(my_root);
1318 
1319  pair_T = getLargest(T, visited);
1320  pair_E = getLargest(E, visited);
1321  res_pair.pos = ddMin(pair_T.pos, pair_E.pos) + 1;
1322  res_pair.neg = ddMin(pair_T.neg, pair_E.neg) + 1;
1323  }
1324 
1325  my_pair = ALLOC(cuddPathPair, 1);
1326  if (my_pair == NULL) { /* simply do not cache this result */
1327  if (Cudd_IsComplement(root)) {
1328  int tmp = res_pair.pos;
1329  res_pair.pos = res_pair.neg;
1330  res_pair.neg = tmp;
1331  }
1332  return(res_pair);
1333  }
1334  my_pair->pos = res_pair.pos;
1335  my_pair->neg = res_pair.neg;
1336 
1337  /* Caching may fail without affecting correctness. */
1338  st_insert(visited, (char *)my_root, (char *)my_pair);
1339  if (Cudd_IsComplement(root)) {
1340  res_pair.pos = my_pair->neg;
1341  res_pair.neg = my_pair->pos;
1342  } else {
1343  res_pair.pos = my_pair->pos;
1344  res_pair.neg = my_pair->neg;
1345  }
1346  return(res_pair);
1347 
1348 } /* end of getLargest */
int st_lookup(st_table *, void *, void *)
Definition: st.c:286
Definition: cudd.h:270
#define Cudd_Regular(node)
Definition: cudd.h:384
int st_insert(st_table *, void *, void *)
Definition: st.c:358
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define ALLOC(type, num)
Definition: util.h:76
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
static DdNode * zero
Definition: cuddSat.c:105
#define cuddE(node)
Definition: cuddInt.h:625
#define DD_BIGGY
Definition: cuddSat.c:82
static cuddPathPair getLargest(DdNode *root, st_table *visited)
Definition: cuddSat.c:1282

◆ getPath()

static DdNode * getPath ( DdManager manager,
st_table visited,
DdNode f,
int *  weight,
int  cost 
)
static

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

Synopsis [Build a BDD for a shortest path of f.]

Description [Build a BDD for a shortest path of f. Given the minimum length from the root, and the minimum lengths for each node (in visited), apply triangulation at each node. Of the two children of each node on a shortest path, at least one is on a shortest path. In case of ties the procedure chooses the THEN children. Returns a pointer to the cube BDD representing the path if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 1189 of file cuddSat.c.

1195 {
1196  DdNode *sol, *tmp;
1197  DdNode *my_dd, *T, *E;
1198  cuddPathPair *T_pair, *E_pair;
1199  int Tcost, Ecost;
1200  int complement;
1201 
1202  my_dd = Cudd_Regular(f);
1203  complement = Cudd_IsComplement(f);
1204 
1205  sol = one;
1206  cuddRef(sol);
1207 
1208  while (!cuddIsConstant(my_dd)) {
1209  Tcost = cost - WEIGHT(weight, my_dd->index);
1210  Ecost = cost;
1211 
1212  T = cuddT(my_dd);
1213  E = cuddE(my_dd);
1214 
1215  if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);}
1216 
1217  st_lookup(visited, Cudd_Regular(T), &T_pair);
1218  if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) ||
1219  (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) {
1220  tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol);
1221  if (tmp == NULL) {
1222  Cudd_RecursiveDeref(manager,sol);
1223  return(NULL);
1224  }
1225  cuddRef(tmp);
1226  Cudd_RecursiveDeref(manager,sol);
1227  sol = tmp;
1228 
1229  complement = Cudd_IsComplement(T);
1230  my_dd = Cudd_Regular(T);
1231  cost = Tcost;
1232  continue;
1233  }
1234  st_lookup(visited, Cudd_Regular(E), &E_pair);
1235  if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) ||
1236  (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) {
1237  tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol);
1238  if (tmp == NULL) {
1239  Cudd_RecursiveDeref(manager,sol);
1240  return(NULL);
1241  }
1242  cuddRef(tmp);
1243  Cudd_RecursiveDeref(manager,sol);
1244  sol = tmp;
1245  complement = Cudd_IsComplement(E);
1246  my_dd = Cudd_Regular(E);
1247  cost = Ecost;
1248  continue;
1249  }
1250  (void) fprintf(manager->err,"We shouldn't be here!!\n");
1251  manager->errorCode = CUDD_INTERNAL_ERROR;
1252  return(NULL);
1253  }
1254 
1255  cuddDeref(sol);
1256  return(sol);
1257 
1258 } /* end of getPath */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
int st_lookup(st_table *, void *, void *)
Definition: st.c:286
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:150
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
#define Cudd_Regular(node)
Definition: cudd.h:384
FILE * err
Definition: cuddInt.h:424
static DdNode * one
Definition: cuddSat.c:105
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
#define WEIGHT(weight, col)
Definition: cuddSat.c:111
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995
DdHalfWord index
Definition: cudd.h:271
DdNode ** vars
Definition: cuddInt.h:373
#define cuddE(node)
Definition: cuddInt.h:625
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ getShortest()

static cuddPathPair getShortest ( DdNode root,
int *  cost,
int *  support,
st_table visited 
)
static

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

Synopsis [Finds the length of the shortest path(s) in a DD.]

Description [Finds the length of the shortest path(s) in a DD. Uses a local symbol table to store the lengths for each node. Only the lengths for the regular nodes are entered in the table, because those for the complement nodes are simply obtained by swapping the two lenghts. Returns a pair of lengths: the length of the shortest path to 1; and the length of the shortest path to 0. This is done so as to take complement arcs into account.]

SideEffects [Accumulates the support of the DD in support.]

SeeAlso []

Definition at line 1093 of file cuddSat.c.

1098 {
1099  cuddPathPair *my_pair, res_pair, pair_T, pair_E;
1100  DdNode *my_root, *T, *E;
1101  int weight;
1102 
1103  my_root = Cudd_Regular(root);
1104 
1105  if (st_lookup(visited, my_root, &my_pair)) {
1106  if (Cudd_IsComplement(root)) {
1107  res_pair.pos = my_pair->neg;
1108  res_pair.neg = my_pair->pos;
1109  } else {
1110  res_pair.pos = my_pair->pos;
1111  res_pair.neg = my_pair->neg;
1112  }
1113  return(res_pair);
1114  }
1115 
1116  /* In the case of a BDD the following test is equivalent to
1117  ** testing whether the BDD is the constant 1. This formulation,
1118  ** however, works for ADDs as well, by assuming the usual
1119  ** dichotomy of 0 and != 0.
1120  */
1121  if (cuddIsConstant(my_root)) {
1122  if (my_root != zero) {
1123  res_pair.pos = 0;
1124  res_pair.neg = DD_BIGGY;
1125  } else {
1126  res_pair.pos = DD_BIGGY;
1127  res_pair.neg = 0;
1128  }
1129  } else {
1130  T = cuddT(my_root);
1131  E = cuddE(my_root);
1132 
1133  pair_T = getShortest(T, cost, support, visited);
1134  pair_E = getShortest(E, cost, support, visited);
1135  weight = WEIGHT(cost, my_root->index);
1136  res_pair.pos = ddMin(pair_T.pos+weight, pair_E.pos);
1137  res_pair.neg = ddMin(pair_T.neg+weight, pair_E.neg);
1138 
1139  /* Update support. */
1140  if (support != NULL) {
1141  support[my_root->index] = 1;
1142  }
1143  }
1144 
1145  my_pair = ALLOC(cuddPathPair, 1);
1146  if (my_pair == NULL) {
1147  if (Cudd_IsComplement(root)) {
1148  int tmp = res_pair.pos;
1149  res_pair.pos = res_pair.neg;
1150  res_pair.neg = tmp;
1151  }
1152  return(res_pair);
1153  }
1154  my_pair->pos = res_pair.pos;
1155  my_pair->neg = res_pair.neg;
1156 
1157  st_insert(visited, (char *)my_root, (char *)my_pair);
1158  if (Cudd_IsComplement(root)) {
1159  res_pair.pos = my_pair->neg;
1160  res_pair.neg = my_pair->pos;
1161  } else {
1162  res_pair.pos = my_pair->pos;
1163  res_pair.neg = my_pair->neg;
1164  }
1165  return(res_pair);
1166 
1167 } /* end of getShortest */
int st_lookup(st_table *, void *, void *)
Definition: st.c:286
Definition: cudd.h:270
#define Cudd_Regular(node)
Definition: cudd.h:384
int st_insert(st_table *, void *, void *)
Definition: st.c:358
static cuddPathPair getShortest(DdNode *root, int *cost, int *support, st_table *visited)
Definition: cuddSat.c:1093
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define ALLOC(type, num)
Definition: util.h:76
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
#define WEIGHT(weight, col)
Definition: cuddSat.c:111
DdHalfWord index
Definition: cudd.h:271
static DdNode * zero
Definition: cuddSat.c:105
#define cuddE(node)
Definition: cuddInt.h:625
#define DD_BIGGY
Definition: cuddSat.c:82

Variable Documentation

◆ DD_UNUSED

char rcsid [] DD_UNUSED = "$Id: cuddSat.c,v 1.39 2012/02/05 01:07:19 fabio Exp $"
static

Definition at line 102 of file cuddSat.c.

◆ one

DdNode* one
static

Definition at line 105 of file cuddSat.c.

◆ zero

DdNode * zero
static

Definition at line 105 of file cuddSat.c.