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

Go to the source code of this file.

Data Structures

struct  cuddPathPair
 

Macros

#define DD_BIGGY   1000000
 
#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)
 
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)
 
DdNodecuddBddMakePrime (DdManager *dd, DdNode *cube, DdNode *f)
 

Variables

static char rcsid[] DD_UNUSED = "$Id: cuddSat.c,v 1.36 2009/03/08 02:49:02 fabio Exp $"
 
static DdNodeone
 
static DdNodezero
 

Macro Definition Documentation

#define DD_BIGGY   1000000

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-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 83 of file cuddSat.c.

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

Definition at line 112 of file cuddSat.c.

Typedef Documentation

typedef struct cuddPathPair cuddPathPair

Function Documentation

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 622 of file cuddSat.c.

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

Definition at line 864 of file cuddSat.c.

868 {
869  DdNode *res;
870 
871  if (!Cudd_bddLeq(dd,cube,f)) return(NULL);
872 
873  do {
874  dd->reordered = 0;
875  res = cuddBddMakePrime(dd,cube,f);
876  } while (dd->reordered == 1);
877  return(res);
878 
879 } /* end of Cudd_bddMakePrime */
Definition: cudd.h:278
DdNode * cuddBddMakePrime(DdManager *dd, DdNode *cube, DdNode *f)
Definition: cuddSat.c:900
int reordered
Definition: cuddInt.h:409
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:536
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 417 of file cuddSat.c.

421 {
422  unsigned int topf, level;
423  DdNode *F, *fv, *fvn, *res;
424  DD_CTFP cacheOp;
425 
426  statLine(dd);
427 #ifdef DD_DEBUG
428  assert(0 <= i && i < dd->size);
429 #endif
430 
431  F = Cudd_Regular(f);
432  topf = cuddI(dd,F->index);
433 
434  /* Check terminal case. If topf > i, f does not depend on var.
435  ** Therefore, f is unate in i.
436  */
437  level = (unsigned) dd->perm[i];
438  if (topf > level) {
439  return(DD_ONE(dd));
440  }
441 
442  /* From now on, f is not constant. */
443 
444  /* Check cache. */
445  cacheOp = (DD_CTFP) Cudd_Decreasing;
446  res = cuddCacheLookup2(dd,cacheOp,f,dd->vars[i]);
447  if (res != NULL) {
448  return(res);
449  }
450 
451  /* Compute cofactors. */
452  fv = cuddT(F); fvn = cuddE(F);
453  if (F != f) {
454  fv = Cudd_Not(fv);
455  fvn = Cudd_Not(fvn);
456  }
457 
458  if (topf == (unsigned) level) {
459  /* Special case: if fv is regular, fv(1,...,1) = 1;
460  ** If in addition fvn is complemented, fvn(1,...,1) = 0.
461  ** But then f(1,1,...,1) > f(0,1,...,1). Hence f is not
462  ** monotonic decreasing in i.
463  */
464  if (!Cudd_IsComplement(fv) && Cudd_IsComplement(fvn)) {
465  return(Cudd_Not(DD_ONE(dd)));
466  }
467  res = Cudd_bddLeq(dd,fv,fvn) ? DD_ONE(dd) : Cudd_Not(DD_ONE(dd));
468  } else {
469  res = Cudd_Decreasing(dd,fv,i);
470  if (res == DD_ONE(dd)) {
471  res = Cudd_Decreasing(dd,fvn,i);
472  }
473  }
474 
475  cuddCacheInsert2(dd,cacheOp,f,dd->vars[i],res);
476  return(res);
477 
478 } /* end of Cudd_Decreasing */
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define Cudd_Regular(node)
Definition: cudd.h:397
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:321
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
#define Cudd_IsComplement(node)
Definition: cudd.h:425
if(last==0)
Definition: sparse_int.h:34
static int size
Definition: cuddSign.c:86
#define cuddT(node)
Definition: cuddInt.h:636
#define cuddI(dd, index)
Definition: cuddInt.h:686
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:536
DdNode * Cudd_Decreasing(DdManager *dd, DdNode *f, int i)
Definition: cuddSat.c:417
DdHalfWord index
Definition: cudd.h:279
DdNode ** vars
Definition: cuddInt.h:390
#define cuddE(node)
Definition: cuddInt.h:652
#define assert(ex)
Definition: util_old.h:213
#define DD_ONE(dd)
Definition: cuddInt.h:911
int * perm
Definition: cuddInt.h:386
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 796 of file cuddSat.c.

802 {
803  DdNode *fv, *fvn, *gv, *gvn, *r;
804  unsigned int topf, topg;
805 
806  statLine(dd);
807  /* Check terminal cases. */
808  if (f == g) return(1);
809  if (Cudd_IsConstant(f) && Cudd_IsConstant(g)) {
810  if (ddEqualVal(cuddV(f),cuddV(g),tolerance)) {
811  return(1);
812  } else {
813  if (pr>0) {
814  (void) fprintf(dd->out,"Offending nodes:\n");
815  (void) fprintf(dd->out,
816  "f: address = %p\t value = %40.30f\n",
817  (void *) f, cuddV(f));
818  (void) fprintf(dd->out,
819  "g: address = %p\t value = %40.30f\n",
820  (void *) g, cuddV(g));
821  }
822  return(0);
823  }
824  }
825 
826  /* We only insert the result in the cache if the comparison is
827  ** successful. Therefore, if we hit we return 1. */
829  if (r != NULL) {
830  return(1);
831  }
832 
833  /* Compute the cofactors and solve the recursive subproblems. */
834  topf = cuddI(dd,f->index);
835  topg = cuddI(dd,g->index);
836 
837  if (topf <= topg) {fv = cuddT(f); fvn = cuddE(f);} else {fv = fvn = f;}
838  if (topg <= topf) {gv = cuddT(g); gvn = cuddE(g);} else {gv = gvn = g;}
839 
840  if (!Cudd_EqualSupNorm(dd,fv,gv,tolerance,pr)) return(0);
841  if (!Cudd_EqualSupNorm(dd,fvn,gvn,tolerance,pr)) return(0);
842 
844 
845  return(1);
846 
847 } /* end of Cudd_EqualSupNorm */
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
int Cudd_EqualSupNorm(DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE tolerance, int pr)
Definition: cuddSat.c:796
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:321
#define statLine(dd)
Definition: cuddInt.h:1037
#define cuddV(node)
Definition: cuddInt.h:668
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
FILE * out
Definition: cuddInt.h:441
#define cuddT(node)
Definition: cuddInt.h:636
#define ddEqualVal(x, y, e)
Definition: cuddInt.h:861
#define cuddI(dd, index)
Definition: cuddInt.h:686
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#define DD_ONE(dd)
Definition: cuddInt.h:911
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 522 of file cuddSat.c.

527 {
528  DdNode *tmp, *One, *Gr, *Dr;
529  DdNode *Fv, *Fvn, *Gv, *Gvn, *Dv, *Dvn;
530  int res;
531  unsigned int flevel, glevel, dlevel, top;
532 
533  One = DD_ONE(dd);
534 
535  statLine(dd);
536  /* Check terminal cases. */
537  if (D == One || F == G) return(1);
538  if (D == Cudd_Not(One) || D == DD_ZERO(dd) || F == Cudd_Not(G)) return(0);
539 
540  /* From now on, D is non-constant. */
541 
542  /* Normalize call to increase cache efficiency. */
543  if (F > G) {
544  tmp = F;
545  F = G;
546  G = tmp;
547  }
548  if (Cudd_IsComplement(F)) {
549  F = Cudd_Not(F);
550  G = Cudd_Not(G);
551  }
552 
553  /* From now on, F is regular. */
554 
555  /* Check cache. */
556  tmp = cuddCacheLookup(dd,DD_EQUIV_DC_TAG,F,G,D);
557  if (tmp != NULL) return(tmp == One);
558 
559  /* Find splitting variable. */
560  flevel = cuddI(dd,F->index);
561  Gr = Cudd_Regular(G);
562  glevel = cuddI(dd,Gr->index);
563  top = ddMin(flevel,glevel);
564  Dr = Cudd_Regular(D);
565  dlevel = dd->perm[Dr->index];
566  top = ddMin(top,dlevel);
567 
568  /* Compute cofactors. */
569  if (top == flevel) {
570  Fv = cuddT(F);
571  Fvn = cuddE(F);
572  } else {
573  Fv = Fvn = F;
574  }
575  if (top == glevel) {
576  Gv = cuddT(Gr);
577  Gvn = cuddE(Gr);
578  if (G != Gr) {
579  Gv = Cudd_Not(Gv);
580  Gvn = Cudd_Not(Gvn);
581  }
582  } else {
583  Gv = Gvn = G;
584  }
585  if (top == dlevel) {
586  Dv = cuddT(Dr);
587  Dvn = cuddE(Dr);
588  if (D != Dr) {
589  Dv = Cudd_Not(Dv);
590  Dvn = Cudd_Not(Dvn);
591  }
592  } else {
593  Dv = Dvn = D;
594  }
595 
596  /* Solve recursively. */
597  res = Cudd_EquivDC(dd,Fv,Gv,Dv);
598  if (res != 0) {
599  res = Cudd_EquivDC(dd,Fvn,Gvn,Dvn);
600  }
601  cuddCacheInsert(dd,DD_EQUIV_DC_TAG,F,G,D,(res) ? One : Cudd_Not(One));
602 
603  return(res);
604 
605 } /* end of Cudd_EquivDC */
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
int Cudd_EquivDC(DdManager *dd, DdNode *F, DdNode *G, DdNode *D)
Definition: cuddSat.c:522
#define Cudd_Regular(node)
Definition: cudd.h:397
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:222
#define statLine(dd)
Definition: cuddInt.h:1037
#define Cudd_IsComplement(node)
Definition: cudd.h:425
#define ddMin(x, y)
Definition: cuddInt.h:818
#define cuddT(node)
Definition: cuddInt.h:636
#define cuddI(dd, index)
Definition: cuddInt.h:686
#define DD_EQUIV_DC_TAG
Definition: cuddInt.h:182
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 * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:369
#define DD_ZERO(dd)
Definition: cuddInt.h:927
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 157 of file cuddSat.c.

161 {
162  int comple;
163  DdNode *ptr;
164 
165  comple = Cudd_IsComplement(f);
166  ptr = Cudd_Regular(f);
167 
168  while (!cuddIsConstant(ptr)) {
169  if (inputs[ptr->index] == 1) {
170  ptr = cuddT(ptr);
171  } else {
172  comple ^= Cudd_IsComplement(cuddE(ptr));
173  ptr = Cudd_Regular(cuddE(ptr));
174  }
175  }
176  return(Cudd_NotCond(ptr,comple));
177 
178 } /* end of Cudd_Eval */
Definition: cudd.h:278
#define Cudd_Regular(node)
Definition: cudd.h:397
#define Cudd_IsComplement(node)
Definition: cudd.h:425
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#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
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 497 of file cuddSat.c.

501 {
502  return(Cudd_Decreasing(dd,Cudd_Not(f),i));
503 
504 } /* end of Cudd_Increasing */
#define Cudd_Not(node)
Definition: cudd.h:367
DdNode * Cudd_Decreasing(DdManager *dd, DdNode *f, int i)
Definition: cuddSat.c:417
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 length.]

SeeAlso [Cudd_ShortestPath]

Definition at line 285 of file cuddSat.c.

289 {
290  register DdNode *F;
291  st__table *visited;
292  DdNode *sol;
293  cuddPathPair *rootPair;
294  int complement, cost;
295 
296  one = DD_ONE(manager);
297  zero = DD_ZERO(manager);
298 
299  if (f == Cudd_Not(one) || f == zero) {
300  *length = DD_BIGGY;
301  return(Cudd_Not(one));
302  }
303  /* From this point on, a path exists. */
304 
305  do {
306  manager->reordered = 0;
307 
308  /* Initialize visited table. */
310 
311  /* Now get the length of the shortest path(s) from f to 1. */
312  (void) getLargest(f, visited);
313 
314  complement = Cudd_IsComplement(f);
315 
316  F = Cudd_Regular(f);
317 
318  if (! st__lookup(visited, (const char *)F, (char **)&rootPair)) return(NULL);
319 
320  if (complement) {
321  cost = rootPair->neg;
322  } else {
323  cost = rootPair->pos;
324  }
325 
326  /* Recover an actual shortest path. */
327  sol = getCube(manager,visited,f,cost);
328 
329  st__foreach(visited, freePathPair, NULL);
330  st__free_table(visited);
331 
332  } while (manager->reordered == 1);
333 
334  *length = cost;
335  return(sol);
336 
337 } /* end of Cudd_LargestCube */
void st__free_table(st__table *table)
Definition: st.c:81
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
static enum st__retval freePathPair(char *key, char *value, char *arg)
Definition: cuddSat.c:964
#define Cudd_Regular(node)
Definition: cudd.h:397
int st__ptrcmp(const char *, const char *)
Definition: st.c:480
pcover complement(pcube *T)
Definition: compl.c:49
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition: st.c:72
int reordered
Definition: cuddInt.h:409
static DdNode * one
Definition: cuddSat.c:106
#define Cudd_IsComplement(node)
Definition: cudd.h:425
Definition: st.h:52
int st__foreach(st__table *table, enum st__retval(*func)(char *, char *, char *), char *arg)
Definition: st.c:421
static DdNode * getCube(DdManager *manager, st__table *visited, DdNode *f, int cost)
Definition: cuddSat.c:1274
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
static DdNode * zero
Definition: cuddSat.c:106
static cuddPathPair getLargest(DdNode *root, st__table *visited)
Definition: cuddSat.c:1186
#define DD_BIGGY
Definition: cuddSat.c:83
#define DD_ONE(dd)
Definition: cuddInt.h:911
int st__ptrhash(const char *, int)
Definition: st.c:468
#define DD_ZERO(dd)
Definition: cuddInt.h:927
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 357 of file cuddSat.c.

361 {
362  register DdNode *F;
363  st__table *visited;
364  cuddPathPair *my_pair;
365  int complement, cost;
366 
367  one = DD_ONE(manager);
368  zero = DD_ZERO(manager);
369 
370  if (f == Cudd_Not(one) || f == zero) {
371  return(DD_BIGGY);
372  }
373 
374  /* From this point on, a path exists. */
375  /* Initialize visited table and support. */
377 
378  /* Now get the length of the shortest path(s) from f to 1. */
379  (void) getShortest(f, weight, NULL, visited);
380 
381  complement = Cudd_IsComplement(f);
382 
383  F = Cudd_Regular(f);
384 
385  if (! st__lookup(visited, (const char *)F, (char **)&my_pair)) return(CUDD_OUT_OF_MEM);
386 
387  if (complement) {
388  cost = my_pair->neg;
389  } else {
390  cost = my_pair->pos;
391  }
392 
393  st__foreach(visited, freePathPair, NULL);
394  st__free_table(visited);
395 
396  return(cost);
397 
398 } /* end of Cudd_ShortestLength */
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
static enum st__retval freePathPair(char *key, char *value, char *arg)
Definition: cuddSat.c:964
#define Cudd_Regular(node)
Definition: cudd.h:397
int st__ptrcmp(const char *, const char *)
Definition: st.c:480
pcover complement(pcube *T)
Definition: compl.c:49
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition: st.c:72
static DdNode * one
Definition: cuddSat.c:106
#define Cudd_IsComplement(node)
Definition: cudd.h:425
Definition: st.h:52
int st__foreach(st__table *table, enum st__retval(*func)(char *, char *, char *), char *arg)
Definition: st.c:421
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
static DdNode * zero
Definition: cuddSat.c:106
#define DD_BIGGY
Definition: cuddSat.c:83
static cuddPathPair getShortest(DdNode *root, int *cost, int *support, st__table *visited)
Definition: cuddSat.c:997
#define DD_ONE(dd)
Definition: cuddInt.h:911
int st__ptrhash(const char *, int)
Definition: st.c:468
#define DD_ZERO(dd)
Definition: cuddInt.h:927
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 201 of file cuddSat.c.

207 {
208  DdNode *F;
209  st__table *visited;
210  DdNode *sol;
211  cuddPathPair *rootPair;
212  int complement, cost;
213  int i;
214 
215  one = DD_ONE(manager);
216  zero = DD_ZERO(manager);
217 
218  /* Initialize support. Support does not depend on variable order.
219  ** Hence, it does not need to be reinitialized if reordering occurs.
220  */
221  if (support) {
222  for (i = 0; i < manager->size; i++) {
223  support[i] = 0;
224  }
225  }
226 
227  if (f == Cudd_Not(one) || f == zero) {
228  *length = DD_BIGGY;
229  return(Cudd_Not(one));
230  }
231  /* From this point on, a path exists. */
232 
233  do {
234  manager->reordered = 0;
235 
236  /* Initialize visited table. */
238 
239  /* Now get the length of the shortest path(s) from f to 1. */
240  (void) getShortest(f, weight, support, visited);
241 
242  complement = Cudd_IsComplement(f);
243 
244  F = Cudd_Regular(f);
245 
246  if (! st__lookup(visited, (const char *)F, (char **)&rootPair)) return(NULL);
247 
248  if (complement) {
249  cost = rootPair->neg;
250  } else {
251  cost = rootPair->pos;
252  }
253 
254  /* Recover an actual shortest path. */
255  sol = getPath(manager,visited,f,weight,cost);
256 
257  st__foreach(visited, freePathPair, NULL);
258  st__free_table(visited);
259 
260  } while (manager->reordered == 1);
261 
262  *length = cost;
263  return(sol);
264 
265 } /* end of Cudd_ShortestPath */
void st__free_table(st__table *table)
Definition: st.c:81
static DdNode * getPath(DdManager *manager, st__table *visited, DdNode *f, int *weight, int cost)
Definition: cuddSat.c:1093
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
static enum st__retval freePathPair(char *key, char *value, char *arg)
Definition: cuddSat.c:964
int size
Definition: cuddInt.h:361
#define Cudd_Regular(node)
Definition: cudd.h:397
int st__ptrcmp(const char *, const char *)
Definition: st.c:480
pcover complement(pcube *T)
Definition: compl.c:49
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition: st.c:72
int reordered
Definition: cuddInt.h:409
static DdNode * one
Definition: cuddSat.c:106
#define Cudd_IsComplement(node)
Definition: cudd.h:425
Definition: st.h:52
int st__foreach(st__table *table, enum st__retval(*func)(char *, char *, char *), char *arg)
Definition: st.c:421
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
static DdNode * zero
Definition: cuddSat.c:106
#define DD_BIGGY
Definition: cuddSat.c:83
static cuddPathPair getShortest(DdNode *root, int *cost, int *support, st__table *visited)
Definition: cuddSat.c:997
#define DD_ONE(dd)
Definition: cuddInt.h:911
int st__ptrhash(const char *, int)
Definition: st.c:468
#define DD_ZERO(dd)
Definition: cuddInt.h:927
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 900 of file cuddSat.c.

904 {
905  DdNode *scan;
906  DdNode *t, *e;
907  DdNode *res = cube;
908  DdNode *zero = Cudd_Not(DD_ONE(dd));
909 
910  Cudd_Ref(res);
911  scan = cube;
912  while (!Cudd_IsConstant(scan)) {
913  DdNode *reg = Cudd_Regular(scan);
914  DdNode *var = dd->vars[reg->index];
915  DdNode *expanded = Cudd_bddExistAbstract(dd,res,var);
916  if (expanded == NULL) {
917  return(NULL);
918  }
919  Cudd_Ref(expanded);
920  if (Cudd_bddLeq(dd,expanded,f)) {
921  Cudd_RecursiveDeref(dd,res);
922  res = expanded;
923  } else {
924  Cudd_RecursiveDeref(dd,expanded);
925  }
926  cuddGetBranches(scan,&t,&e);
927  if (t == zero) {
928  scan = e;
929  } else if (e == zero) {
930  scan = t;
931  } else {
932  Cudd_RecursiveDeref(dd,res);
933  return(NULL); /* cube is not a cube */
934  }
935  }
936 
937  if (scan == DD_ONE(dd)) {
938  Cudd_Deref(res);
939  return(res);
940  } else {
941  Cudd_RecursiveDeref(dd,res);
942  return(NULL);
943  }
944 
945 } /* end of cuddBddMakePrime */
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:438
int var(Lit p)
Definition: SolverTypes.h:62
#define Cudd_IsConstant(node)
Definition: cudd.h:352
#define Cudd_Regular(node)
Definition: cudd.h:397
DdNode * Cudd_bddExistAbstract(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:130
void cuddGetBranches(DdNode *g, DdNode **g1, DdNode **g0)
Definition: cuddCof.c:162
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:536
DdHalfWord index
Definition: cudd.h:279
DdNode ** vars
Definition: cuddInt.h:390
static DdNode * zero
Definition: cuddSat.c:106
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
#define DD_ONE(dd)
Definition: cuddInt.h:911
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 964 of file cuddSat.c.

968 {
969  cuddPathPair *pair;
970 
971  pair = (cuddPathPair *) value;
972  ABC_FREE(pair);
973  return( st__CONTINUE);
974 
975 } /* end of freePathPair */
#define ABC_FREE(obj)
Definition: abc_global.h:232
int value
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 1274 of file cuddSat.c.

1279 {
1280  DdNode *sol, *tmp;
1281  DdNode *my_dd, *T, *E;
1282  cuddPathPair *T_pair, *E_pair;
1283  int Tcost, Ecost;
1284  int complement;
1285 
1286  my_dd = Cudd_Regular(f);
1287  complement = Cudd_IsComplement(f);
1288 
1289  sol = one;
1290  cuddRef(sol);
1291 
1292  while (!cuddIsConstant(my_dd)) {
1293  Tcost = cost - 1;
1294  Ecost = cost - 1;
1295 
1296  T = cuddT(my_dd);
1297  E = cuddE(my_dd);
1298 
1299  if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);}
1300 
1301  if (! st__lookup(visited, (const char *)Cudd_Regular(T), (char **)&T_pair)) return(NULL);
1302  if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) ||
1303  (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) {
1304  tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol);
1305  if (tmp == NULL) {
1306  Cudd_RecursiveDeref(manager,sol);
1307  return(NULL);
1308  }
1309  cuddRef(tmp);
1310  Cudd_RecursiveDeref(manager,sol);
1311  sol = tmp;
1312 
1313  complement = Cudd_IsComplement(T);
1314  my_dd = Cudd_Regular(T);
1315  cost = Tcost;
1316  continue;
1317  }
1318  if (! st__lookup(visited, (const char *)Cudd_Regular(E), (char **)&E_pair)) return(NULL);
1319  if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) ||
1320  (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) {
1321  tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol);
1322  if (tmp == NULL) {
1323  Cudd_RecursiveDeref(manager,sol);
1324  return(NULL);
1325  }
1326  cuddRef(tmp);
1327  Cudd_RecursiveDeref(manager,sol);
1328  sol = tmp;
1329  complement = Cudd_IsComplement(E);
1330  my_dd = Cudd_Regular(E);
1331  cost = Ecost;
1332  continue;
1333  }
1334  (void) fprintf(manager->err,"We shouldn't be here!\n");
1335  manager->errorCode = CUDD_INTERNAL_ERROR;
1336  return(NULL);
1337  }
1338 
1339  cuddDeref(sol);
1340  return(sol);
1341 
1342 } /* end of getCube */
#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
#define Cudd_Not(node)
Definition: cudd.h:367
#define Cudd_Regular(node)
Definition: cudd.h:397
FILE * err
Definition: cuddInt.h:442
pcover complement(pcube *T)
Definition: compl.c:49
static DdNode * one
Definition: cuddSat.c:106
#define Cudd_IsComplement(node)
Definition: cudd.h:425
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define cuddT(node)
Definition: cuddInt.h:636
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
DdHalfWord index
Definition: cudd.h:279
DdNode ** vars
Definition: cuddInt.h:390
#define cuddE(node)
Definition: cuddInt.h:652
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
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 1186 of file cuddSat.c.

1189 {
1190  cuddPathPair *my_pair, res_pair, pair_T, pair_E;
1191  DdNode *my_root, *T, *E;
1192 
1193  my_root = Cudd_Regular(root);
1194 
1195  if ( st__lookup(visited, (const char *)my_root, (char **)&my_pair)) {
1196  if (Cudd_IsComplement(root)) {
1197  res_pair.pos = my_pair->neg;
1198  res_pair.neg = my_pair->pos;
1199  } else {
1200  res_pair.pos = my_pair->pos;
1201  res_pair.neg = my_pair->neg;
1202  }
1203  return(res_pair);
1204  }
1205 
1206  /* In the case of a BDD the following test is equivalent to
1207  ** testing whether the BDD is the constant 1. This formulation,
1208  ** however, works for ADDs as well, by assuming the usual
1209  ** dichotomy of 0 and != 0.
1210  */
1211  if (cuddIsConstant(my_root)) {
1212  if (my_root != zero) {
1213  res_pair.pos = 0;
1214  res_pair.neg = DD_BIGGY;
1215  } else {
1216  res_pair.pos = DD_BIGGY;
1217  res_pair.neg = 0;
1218  }
1219  } else {
1220  T = cuddT(my_root);
1221  E = cuddE(my_root);
1222 
1223  pair_T = getLargest(T, visited);
1224  pair_E = getLargest(E, visited);
1225  res_pair.pos = ddMin(pair_T.pos, pair_E.pos) + 1;
1226  res_pair.neg = ddMin(pair_T.neg, pair_E.neg) + 1;
1227  }
1228 
1229  my_pair = ABC_ALLOC(cuddPathPair, 1);
1230  if (my_pair == NULL) { /* simply do not cache this result */
1231  if (Cudd_IsComplement(root)) {
1232  int tmp = res_pair.pos;
1233  res_pair.pos = res_pair.neg;
1234  res_pair.neg = tmp;
1235  }
1236  return(res_pair);
1237  }
1238  my_pair->pos = res_pair.pos;
1239  my_pair->neg = res_pair.neg;
1240 
1241  /* Caching may fail without affecting correctness. */
1242  st__insert(visited, (char *)my_root, (char *)my_pair);
1243  if (Cudd_IsComplement(root)) {
1244  res_pair.pos = my_pair->neg;
1245  res_pair.neg = my_pair->pos;
1246  } else {
1247  res_pair.pos = my_pair->pos;
1248  res_pair.neg = my_pair->neg;
1249  }
1250  return(res_pair);
1251 
1252 } /* end of getLargest */
Definition: cudd.h:278
int st__insert(st__table *table, const char *key, char *value)
Definition: st.c:171
#define Cudd_Regular(node)
Definition: cudd.h:397
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
#define Cudd_IsComplement(node)
Definition: cudd.h:425
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define ddMin(x, y)
Definition: cuddInt.h:818
#define cuddT(node)
Definition: cuddInt.h:636
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
static DdNode * zero
Definition: cuddSat.c:106
#define cuddE(node)
Definition: cuddInt.h:652
static cuddPathPair getLargest(DdNode *root, st__table *visited)
Definition: cuddSat.c:1186
#define DD_BIGGY
Definition: cuddSat.c:83
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 1093 of file cuddSat.c.

1099 {
1100  DdNode *sol, *tmp;
1101  DdNode *my_dd, *T, *E;
1102  cuddPathPair *T_pair, *E_pair;
1103  int Tcost, Ecost;
1104  int complement;
1105 
1106  my_dd = Cudd_Regular(f);
1107  complement = Cudd_IsComplement(f);
1108 
1109  sol = one;
1110  cuddRef(sol);
1111 
1112  while (!cuddIsConstant(my_dd)) {
1113  Tcost = cost - WEIGHT(weight, my_dd->index);
1114  Ecost = cost;
1115 
1116  T = cuddT(my_dd);
1117  E = cuddE(my_dd);
1118 
1119  if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);}
1120 
1121  st__lookup(visited, (const char *)Cudd_Regular(T), (char **)&T_pair);
1122  if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) ||
1123  (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) {
1124  tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol);
1125  if (tmp == NULL) {
1126  Cudd_RecursiveDeref(manager,sol);
1127  return(NULL);
1128  }
1129  cuddRef(tmp);
1130  Cudd_RecursiveDeref(manager,sol);
1131  sol = tmp;
1132 
1133  complement = Cudd_IsComplement(T);
1134  my_dd = Cudd_Regular(T);
1135  cost = Tcost;
1136  continue;
1137  }
1138  st__lookup(visited, (const char *)Cudd_Regular(E), (char **)&E_pair);
1139  if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) ||
1140  (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) {
1141  tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol);
1142  if (tmp == NULL) {
1143  Cudd_RecursiveDeref(manager,sol);
1144  return(NULL);
1145  }
1146  cuddRef(tmp);
1147  Cudd_RecursiveDeref(manager,sol);
1148  sol = tmp;
1149  complement = Cudd_IsComplement(E);
1150  my_dd = Cudd_Regular(E);
1151  cost = Ecost;
1152  continue;
1153  }
1154  (void) fprintf(manager->err,"We shouldn't be here!!\n");
1155  manager->errorCode = CUDD_INTERNAL_ERROR;
1156  return(NULL);
1157  }
1158 
1159  cuddDeref(sol);
1160  return(sol);
1161 
1162 } /* end of getPath */
#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
#define Cudd_Not(node)
Definition: cudd.h:367
#define Cudd_Regular(node)
Definition: cudd.h:397
FILE * err
Definition: cuddInt.h:442
pcover complement(pcube *T)
Definition: compl.c:49
static DdNode * one
Definition: cuddSat.c:106
#define Cudd_IsComplement(node)
Definition: cudd.h:425
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define cuddT(node)
Definition: cuddInt.h:636
#define WEIGHT(weight, col)
Definition: cuddSat.c:112
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
DdHalfWord index
Definition: cudd.h:279
DdNode ** vars
Definition: cuddInt.h:390
#define cuddE(node)
Definition: cuddInt.h:652
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
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 997 of file cuddSat.c.

1002 {
1003  cuddPathPair *my_pair, res_pair, pair_T, pair_E;
1004  DdNode *my_root, *T, *E;
1005  int weight;
1006 
1007  my_root = Cudd_Regular(root);
1008 
1009  if ( st__lookup(visited, (const char *)my_root, (char **)&my_pair)) {
1010  if (Cudd_IsComplement(root)) {
1011  res_pair.pos = my_pair->neg;
1012  res_pair.neg = my_pair->pos;
1013  } else {
1014  res_pair.pos = my_pair->pos;
1015  res_pair.neg = my_pair->neg;
1016  }
1017  return(res_pair);
1018  }
1019 
1020  /* In the case of a BDD the following test is equivalent to
1021  ** testing whether the BDD is the constant 1. This formulation,
1022  ** however, works for ADDs as well, by assuming the usual
1023  ** dichotomy of 0 and != 0.
1024  */
1025  if (cuddIsConstant(my_root)) {
1026  if (my_root != zero) {
1027  res_pair.pos = 0;
1028  res_pair.neg = DD_BIGGY;
1029  } else {
1030  res_pair.pos = DD_BIGGY;
1031  res_pair.neg = 0;
1032  }
1033  } else {
1034  T = cuddT(my_root);
1035  E = cuddE(my_root);
1036 
1037  pair_T = getShortest(T, cost, support, visited);
1038  pair_E = getShortest(E, cost, support, visited);
1039  weight = WEIGHT(cost, my_root->index);
1040  res_pair.pos = ddMin(pair_T.pos+weight, pair_E.pos);
1041  res_pair.neg = ddMin(pair_T.neg+weight, pair_E.neg);
1042 
1043  /* Update support. */
1044  if (support != NULL) {
1045  support[my_root->index] = 1;
1046  }
1047  }
1048 
1049  my_pair = ABC_ALLOC(cuddPathPair, 1);
1050  if (my_pair == NULL) {
1051  if (Cudd_IsComplement(root)) {
1052  int tmp = res_pair.pos;
1053  res_pair.pos = res_pair.neg;
1054  res_pair.neg = tmp;
1055  }
1056  return(res_pair);
1057  }
1058  my_pair->pos = res_pair.pos;
1059  my_pair->neg = res_pair.neg;
1060 
1061  st__insert(visited, (char *)my_root, (char *)my_pair);
1062  if (Cudd_IsComplement(root)) {
1063  res_pair.pos = my_pair->neg;
1064  res_pair.neg = my_pair->pos;
1065  } else {
1066  res_pair.pos = my_pair->pos;
1067  res_pair.neg = my_pair->neg;
1068  }
1069  return(res_pair);
1070 
1071 } /* end of getShortest */
Definition: cudd.h:278
int st__insert(st__table *table, const char *key, char *value)
Definition: st.c:171
#define Cudd_Regular(node)
Definition: cudd.h:397
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
#define Cudd_IsComplement(node)
Definition: cudd.h:425
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define ddMin(x, y)
Definition: cuddInt.h:818
#define cuddT(node)
Definition: cuddInt.h:636
#define WEIGHT(weight, col)
Definition: cuddSat.c:112
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
DdHalfWord index
Definition: cudd.h:279
static DdNode * zero
Definition: cuddSat.c:106
#define cuddE(node)
Definition: cuddInt.h:652
#define DD_BIGGY
Definition: cuddSat.c:83
static cuddPathPair getShortest(DdNode *root, int *cost, int *support, st__table *visited)
Definition: cuddSat.c:997

Variable Documentation

char rcsid [] DD_UNUSED = "$Id: cuddSat.c,v 1.36 2009/03/08 02:49:02 fabio Exp $"
static

Definition at line 103 of file cuddSat.c.

DdNode* one
static

Definition at line 106 of file cuddSat.c.

DdNode * zero
static

Definition at line 106 of file cuddSat.c.