src/cuBdd/cuddEssent.c File Reference

#include "util.h"
#include "cuddInt.h"
Include dependency graph for cuddEssent.c:

Go to the source code of this file.

Data Structures

struct  DdTlcInfo
struct  TlClause

Defines

#define BPL   32
#define LOGBPL   5

Typedefs

typedef long BitVector
typedef struct TlClause TlClause

Functions

static DdNodeddFindEssentialRecur (DdManager *dd, DdNode *f)
static DdTlcInfoddFindTwoLiteralClausesRecur (DdManager *dd, DdNode *f, st_table *table)
static DdTlcInfocomputeClauses (DdTlcInfo *Tres, DdTlcInfo *Eres, DdHalfWord label, int size)
static DdTlcInfocomputeClausesWithUniverse (DdTlcInfo *Cres, DdHalfWord label, short phase)
static DdTlcInfoemptyClauseSet (void)
static int sentinelp (DdHalfWord var1, DdHalfWord var2)
static int equalp (DdHalfWord var1a, short phase1a, DdHalfWord var1b, short phase1b, DdHalfWord var2a, short phase2a, DdHalfWord var2b, short phase2b)
static int beforep (DdHalfWord var1a, short phase1a, DdHalfWord var1b, short phase1b, DdHalfWord var2a, short phase2a, DdHalfWord var2b, short phase2b)
static int oneliteralp (DdHalfWord var)
static int impliedp (DdHalfWord var1, short phase1, DdHalfWord var2, short phase2, BitVector *olv, BitVector *olp)
static BitVectorbitVectorAlloc (int size)
static DD_INLINE void bitVectorClear (BitVector *vector, int size)
static void bitVectorFree (BitVector *vector)
static DD_INLINE short bitVectorRead (BitVector *vector, int i)
static DD_INLINE void bitVectorSet (BitVector *vector, int i, short val)
static DdTlcInfotlcInfoAlloc (void)
DdNodeCudd_FindEssential (DdManager *dd, DdNode *f)
int Cudd_bddIsVarEssential (DdManager *manager, DdNode *f, int id, int phase)
DdTlcInfoCudd_FindTwoLiteralClauses (DdManager *dd, DdNode *f)
int Cudd_ReadIthClause (DdTlcInfo *tlc, int i, DdHalfWord *var1, DdHalfWord *var2, int *phase1, int *phase2)
int Cudd_PrintTwoLiteralClauses (DdManager *dd, DdNode *f, char **names, FILE *fp)
void Cudd_tlcInfoFree (DdTlcInfo *t)

Variables

static char rcsid[] DD_UNUSED = "$Id: cuddEssent.c,v 1.24 2009/02/21 18:24:10 fabio Exp $"
static BitVectorTolv
static BitVectorTolp
static BitVectorEolv
static BitVectorEolp

Define Documentation

#define BPL   32

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

FileName [cuddEssent.c]

PackageName [cudd]

Synopsis [Functions for the detection of essential variables.]

Description [External procedures included in this file:

Static procedures included in this module:

]

Author [Fabio Somenzi]

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

All rights reserved.

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

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

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

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

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

Definition at line 86 of file cuddEssent.c.

#define LOGBPL   5

Definition at line 87 of file cuddEssent.c.


Typedef Documentation

typedef long BitVector

Definition at line 138 of file cuddEssent.c.

typedef struct TlClause TlClause

Definition at line 139 of file cuddEssent.c.


Function Documentation

static int beforep ( DdHalfWord  var1a,
short  phase1a,
DdHalfWord  var1b,
short  phase1b,
DdHalfWord  var2a,
short  phase2a,
DdHalfWord  var2b,
short  phase2b 
) [static]

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

Synopsis [Returns true iff the first argument precedes the second in the clause order.]

Description [Returns true iff the first argument precedes the second in the clause order. A clause precedes another if its first lieral precedes the first literal of the other, or if the first literals are the same, and its second literal precedes the second literal of the other clause. A literal precedes another if it has a higher index, of if it has the same index, but it has lower phase. Phase 0 is the positive phase, and it is lower than Phase 1 (negative phase).]

SideEffects [None]

SeeAlso [equalp]

Definition at line 1229 of file cuddEssent.c.

01238 {
01239     return(var1a > var2a || (var1a == var2a &&
01240            (phase1a < phase2a || (phase1a == phase2a &&
01241             (var1b > var2b || (var1b == var2b && phase1b < phase2b))))));
01242 
01243 } /* end of beforep */

static BitVector * bitVectorAlloc ( int  size  )  [static]

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

Synopsis [Allocates a bit vector.]

Description [Allocates a bit vector. The parameter size gives the number of bits. This procedure allocates enough long's to hold the specified number of bits. Returns a pointer to the allocated vector if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [bitVectorClear bitVectorFree]

Definition at line 1315 of file cuddEssent.c.

01317 {
01318     int allocSize;
01319     BitVector *vector;
01320 
01321     /* Find out how many long's we need.
01322     ** There are sizeof(long) * 8 bits in a long.
01323     ** The ceiling of the ratio of two integers m and n is given
01324     ** by ((n-1)/m)+1.  Putting all this together, we get... */
01325     allocSize = ((size - 1) / (sizeof(BitVector) * 8)) + 1;
01326     vector = ALLOC(BitVector, allocSize);
01327     if (vector == NULL) return(NULL);
01328     /* Clear the whole array. */
01329     (void) memset(vector, 0, allocSize * sizeof(BitVector));
01330     return(vector);
01331 
01332 } /* end of bitVectorAlloc */

static DD_INLINE void bitVectorClear ( BitVector vector,
int  size 
) [static]

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

Synopsis [Clears a bit vector.]

Description [Clears a bit vector. The parameter size gives the number of bits.]

SideEffects [None]

SeeAlso [bitVectorAlloc]

Definition at line 1349 of file cuddEssent.c.

01352 {
01353     int allocSize;
01354 
01355     /* Find out how many long's we need.
01356     ** There are sizeof(long) * 8 bits in a long.
01357     ** The ceiling of the ratio of two integers m and n is given
01358     ** by ((n-1)/m)+1.  Putting all this together, we get... */
01359     allocSize = ((size - 1) / (sizeof(BitVector) * 8)) + 1;
01360     /* Clear the whole array. */
01361     (void) memset(vector, 0, allocSize * sizeof(BitVector));
01362     return;
01363 
01364 } /* end of bitVectorClear */

static void bitVectorFree ( BitVector vector  )  [static]

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

Synopsis [Frees a bit vector.]

Description [Frees a bit vector.]

SideEffects [None]

SeeAlso [bitVectorAlloc]

Definition at line 1379 of file cuddEssent.c.

01381 {
01382     FREE(vector);
01383 
01384 } /* end of bitVectorFree */

static DD_INLINE short bitVectorRead ( BitVector vector,
int  i 
) [static]

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

Synopsis [Returns the i-th entry of a bit vector.]

Description [Returns the i-th entry of a bit vector.]

SideEffects [None]

SeeAlso [bitVectorSet]

Definition at line 1400 of file cuddEssent.c.

01403 {
01404     int word, bit;
01405     short result;
01406 
01407     if (vector == NULL) return((short) 0);
01408 
01409     word = i >> LOGBPL;
01410     bit = i & (BPL - 1);
01411     result = (short) ((vector[word] >> bit) & 1L);
01412     return(result);
01413 
01414 } /* end of bitVectorRead */

static DD_INLINE void bitVectorSet ( BitVector vector,
int  i,
short  val 
) [static]

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

Synopsis [Sets the i-th entry of a bit vector to a value.]

Description [Sets the i-th entry of a bit vector to a value.]

SideEffects [None]

SeeAlso [bitVectorRead]

Definition at line 1430 of file cuddEssent.c.

01434 {
01435     int word, bit;
01436 
01437     word = i >> LOGBPL;
01438     bit = i & (BPL - 1);
01439     vector[word] &= ~(1L << bit);
01440     vector[word] |= (((long) val) << bit);
01441 
01442 } /* end of bitVectorSet */

static DdTlcInfo * computeClauses ( DdTlcInfo Tres,
DdTlcInfo Eres,
DdHalfWord  label,
int  size 
) [static]

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

Synopsis [Computes the two-literal clauses for a node.]

Description [Computes the two-literal clauses for a node given the clauses for its children and the label of the node. Returns a pointer to a TclInfo structure if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [computeClausesWithUniverse]

Definition at line 764 of file cuddEssent.c.

00769 {
00770     DdHalfWord *Tcv = Tres->vars; /* variables of clauses for the T child */
00771     BitVector *Tcp = Tres->phases; /* phases of clauses for the T child */
00772     DdHalfWord *Ecv = Eres->vars; /* variables of clauses for the E child */
00773     BitVector *Ecp = Eres->phases; /* phases of clauses for the E child */
00774     DdHalfWord *Vcv = NULL; /* pointer to variables of the clauses for v */
00775     BitVector *Vcp = NULL; /* pointer to phases of the clauses for v */
00776     DdTlcInfo *res = NULL; /* the set of clauses to be returned */
00777     int pt = 0; /* index in the list of clauses of T */
00778     int pe = 0; /* index in the list of clauses of E */
00779     int cv = 0; /* counter of the clauses for this node */
00780     TlClause *iclauses = NULL; /* list of inherited clauses */
00781     TlClause *tclauses = NULL; /* list of 1-literal clauses of T */
00782     TlClause *eclauses = NULL; /* list of 1-literal clauses of E */
00783     TlClause *nclauses = NULL; /* list of new (non-inherited) clauses */
00784     TlClause *lnclause = NULL; /* pointer to last new clause */
00785     TlClause *newclause; /* temporary pointer to new clauses */
00786 
00787     /* Initialize sets of one-literal clauses.  The one-literal clauses
00788     ** are stored redundantly.  These sets allow constant-time lookup, which
00789     ** we need when we check for implication of a two-literal clause by a
00790     ** one-literal clause.  The linked lists allow fast sequential
00791     ** processing. */
00792     bitVectorClear(Tolv, size);
00793     bitVectorClear(Tolp, size);
00794     bitVectorClear(Eolv, size);
00795     bitVectorClear(Eolp, size);
00796 
00797     /* Initialize result structure. */
00798     res = tlcInfoAlloc();
00799     if (res == NULL) goto cleanup;
00800 
00801     /* Scan the two input list.  Extract inherited two-literal clauses
00802     ** and set aside one-literal clauses from each list.  The incoming lists
00803     ** are sorted in the order defined by beforep.  The three linked list
00804     ** produced by this loop are sorted in the reverse order because we
00805     ** always append to the front of the lists.
00806     ** The inherited clauses are those clauses (both one- and two-literal)
00807     ** that are common to both children; and the two-literal clauses of
00808     ** one child that are implied by a one-literal clause of the other
00809     ** child. */
00810     while (!sentinelp(Tcv[pt], Tcv[pt+1]) || !sentinelp(Ecv[pe], Ecv[pe+1])) {
00811         if (equalp(Tcv[pt], bitVectorRead(Tcp, pt),
00812                    Tcv[pt+1], bitVectorRead(Tcp, pt+1),
00813                    Ecv[pe], bitVectorRead(Ecp, pe),
00814                    Ecv[pe+1], bitVectorRead(Ecp, pe+1))) {
00815             /* Add clause to inherited list. */
00816             newclause = ALLOC(TlClause,1);
00817             if (newclause == NULL) goto cleanup;
00818             newclause->v1 = Tcv[pt];
00819             newclause->v2 = Tcv[pt+1];
00820             newclause->p1 = bitVectorRead(Tcp, pt);
00821             newclause->p2 = bitVectorRead(Tcp, pt+1);
00822             newclause->next = iclauses;
00823             iclauses = newclause;
00824             pt += 2; pe += 2; cv++;
00825         } else if (beforep(Tcv[pt], bitVectorRead(Tcp, pt),
00826                    Tcv[pt+1], bitVectorRead(Tcp, pt+1),
00827                    Ecv[pe], bitVectorRead(Ecp, pe),
00828                    Ecv[pe+1], bitVectorRead(Ecp, pe+1))) {
00829             if (oneliteralp(Tcv[pt+1])) {
00830                 /* Add this one-literal clause to the T set. */
00831                 newclause = ALLOC(TlClause,1);
00832                 if (newclause == NULL) goto cleanup;
00833                 newclause->v1 = Tcv[pt];
00834                 newclause->v2 = CUDD_MAXINDEX;
00835                 newclause->p1 = bitVectorRead(Tcp, pt);
00836                 newclause->p2 = 1;
00837                 newclause->next = tclauses;
00838                 tclauses = newclause;
00839                 bitVectorSet(Tolv, Tcv[pt], 1);
00840                 bitVectorSet(Tolp, Tcv[pt], bitVectorRead(Tcp, pt));
00841             } else {
00842                 if (impliedp(Tcv[pt], bitVectorRead(Tcp, pt),
00843                              Tcv[pt+1], bitVectorRead(Tcp, pt+1),
00844                              Eolv, Eolp)) {
00845                     /* Add clause to inherited list. */
00846                     newclause = ALLOC(TlClause,1);
00847                     if (newclause == NULL) goto cleanup;
00848                     newclause->v1 = Tcv[pt];
00849                     newclause->v2 = Tcv[pt+1];
00850                     newclause->p1 = bitVectorRead(Tcp, pt);
00851                     newclause->p2 = bitVectorRead(Tcp, pt+1);
00852                     newclause->next = iclauses;
00853                     iclauses = newclause;
00854                     cv++;
00855                 }
00856             }
00857             pt += 2;
00858         } else { /* !beforep() */
00859             if (oneliteralp(Ecv[pe+1])) {
00860                 /* Add this one-literal clause to the E set. */
00861                 newclause = ALLOC(TlClause,1);
00862                 if (newclause == NULL) goto cleanup;
00863                 newclause->v1 = Ecv[pe];
00864                 newclause->v2 = CUDD_MAXINDEX;
00865                 newclause->p1 = bitVectorRead(Ecp, pe);
00866                 newclause->p2 = 1;
00867                 newclause->next = eclauses;
00868                 eclauses = newclause;
00869                 bitVectorSet(Eolv, Ecv[pe], 1);
00870                 bitVectorSet(Eolp, Ecv[pe], bitVectorRead(Ecp, pe));
00871             } else {
00872                 if (impliedp(Ecv[pe], bitVectorRead(Ecp, pe),
00873                              Ecv[pe+1], bitVectorRead(Ecp, pe+1),
00874                              Tolv, Tolp)) {
00875                     /* Add clause to inherited list. */
00876                     newclause = ALLOC(TlClause,1);
00877                     if (newclause == NULL) goto cleanup;
00878                     newclause->v1 = Ecv[pe];
00879                     newclause->v2 = Ecv[pe+1];
00880                     newclause->p1 = bitVectorRead(Ecp, pe);
00881                     newclause->p2 = bitVectorRead(Ecp, pe+1);
00882                     newclause->next = iclauses;
00883                     iclauses = newclause;
00884                     cv++;
00885                 }
00886             }
00887             pe += 2;
00888         }
00889     }
00890 
00891     /* Add one-literal clauses for the label variable to the front of
00892     ** the two lists. */
00893     newclause = ALLOC(TlClause,1);
00894     if (newclause == NULL) goto cleanup;
00895     newclause->v1 = label;
00896     newclause->v2 = CUDD_MAXINDEX;
00897     newclause->p1 = 0;
00898     newclause->p2 = 1;
00899     newclause->next = tclauses;
00900     tclauses = newclause;
00901     newclause = ALLOC(TlClause,1);
00902     if (newclause == NULL) goto cleanup;
00903     newclause->v1 = label;
00904     newclause->v2 = CUDD_MAXINDEX;
00905     newclause->p1 = 1;
00906     newclause->p2 = 1;
00907     newclause->next = eclauses;
00908     eclauses = newclause;
00909 
00910     /* Produce the non-inherited clauses.  We preserve the "reverse"
00911     ** order of the two input lists by appending to the end of the
00912     ** list.  In this way, iclauses and nclauses are consistent. */
00913     while (tclauses != NULL && eclauses != NULL) {
00914         if (beforep(eclauses->v1, eclauses->p1, eclauses->v2, eclauses->p2,
00915                     tclauses->v1, tclauses->p1, tclauses->v2, tclauses->p2)) {
00916             TlClause *nextclause = tclauses->next;
00917             TlClause *otherclauses = eclauses;
00918             while (otherclauses != NULL) {
00919                 if (tclauses->v1 != otherclauses->v1) {
00920                     newclause = ALLOC(TlClause,1);
00921                     if (newclause == NULL) goto cleanup;
00922                     newclause->v1 = tclauses->v1;
00923                     newclause->v2 = otherclauses->v1;
00924                     newclause->p1 = tclauses->p1;
00925                     newclause->p2 = otherclauses->p1;
00926                     newclause->next = NULL;
00927                     if (nclauses == NULL) {
00928                         nclauses = newclause;
00929                         lnclause = newclause;
00930                     } else {
00931                         lnclause->next = newclause;
00932                         lnclause = newclause;
00933                     }
00934                     cv++;
00935                 }
00936                 otherclauses = otherclauses->next;
00937             }
00938             FREE(tclauses);
00939             tclauses = nextclause;
00940         } else {
00941             TlClause *nextclause = eclauses->next;
00942             TlClause *otherclauses = tclauses;
00943             while (otherclauses != NULL) {
00944                 if (eclauses->v1 != otherclauses->v1) {
00945                     newclause = ALLOC(TlClause,1);
00946                     if (newclause == NULL) goto cleanup;
00947                     newclause->v1 = eclauses->v1;
00948                     newclause->v2 = otherclauses->v1;
00949                     newclause->p1 = eclauses->p1;
00950                     newclause->p2 = otherclauses->p1;
00951                     newclause->next = NULL;
00952                     if (nclauses == NULL) {
00953                         nclauses = newclause;
00954                         lnclause = newclause;
00955                     } else {
00956                         lnclause->next = newclause;
00957                         lnclause = newclause;
00958                     }
00959                     cv++;
00960                 }
00961                 otherclauses = otherclauses->next;
00962             }
00963             FREE(eclauses);
00964             eclauses = nextclause;
00965         }
00966     }
00967     while (tclauses != NULL) {
00968         TlClause *nextclause = tclauses->next;
00969         FREE(tclauses);
00970         tclauses = nextclause;
00971     }
00972     while (eclauses != NULL) {
00973         TlClause *nextclause = eclauses->next;
00974         FREE(eclauses);
00975         eclauses = nextclause;
00976     }
00977 
00978     /* Merge inherited and non-inherited clauses.  Now that we know the
00979     ** total number, we allocate the arrays, and we fill them bottom-up
00980     ** to restore the proper ordering. */
00981     Vcv = ALLOC(DdHalfWord, 2*(cv+1));
00982     if (Vcv == NULL) goto cleanup;
00983     if (cv > 0) {
00984         Vcp = bitVectorAlloc(2*cv);
00985         if (Vcp == NULL) goto cleanup;
00986     } else {
00987         Vcp = NULL;
00988     }
00989     res->vars = Vcv;
00990     res->phases = Vcp;
00991     /* Add sentinel. */
00992     Vcv[2*cv] = 0;
00993     Vcv[2*cv+1] = 0;
00994     while (iclauses != NULL || nclauses != NULL) {
00995         TlClause *nextclause;
00996         cv--;
00997         if (nclauses == NULL || (iclauses != NULL &&
00998             beforep(nclauses->v1, nclauses->p1, nclauses->v2, nclauses->p2,
00999                     iclauses->v1, iclauses->p1, iclauses->v2, iclauses->p2))) {
01000             Vcv[2*cv] = iclauses->v1;
01001             Vcv[2*cv+1] = iclauses->v2;
01002             bitVectorSet(Vcp, 2*cv, iclauses->p1);
01003             bitVectorSet(Vcp, 2*cv+1, iclauses->p2);
01004             nextclause = iclauses->next;
01005             FREE(iclauses);
01006             iclauses = nextclause;
01007         } else {
01008             Vcv[2*cv] = nclauses->v1;
01009             Vcv[2*cv+1] = nclauses->v2;
01010             bitVectorSet(Vcp, 2*cv, nclauses->p1);
01011             bitVectorSet(Vcp, 2*cv+1, nclauses->p2);
01012             nextclause = nclauses->next;
01013             FREE(nclauses);
01014             nclauses = nextclause;
01015         }
01016     }
01017     assert(cv == 0);
01018 
01019     return(res);
01020 
01021  cleanup:
01022     if (res != NULL) Cudd_tlcInfoFree(res);
01023     while (iclauses != NULL) {
01024         TlClause *nextclause = iclauses->next;
01025         FREE(iclauses);
01026         iclauses = nextclause;
01027     }
01028     while (nclauses != NULL) {
01029         TlClause *nextclause = nclauses->next;
01030         FREE(nclauses);
01031         nclauses = nextclause;
01032     }
01033     while (tclauses != NULL) {
01034         TlClause *nextclause = tclauses->next;
01035         FREE(tclauses);
01036         tclauses = nextclause;
01037     }
01038     while (eclauses != NULL) {
01039         TlClause *nextclause = eclauses->next;
01040         FREE(eclauses);
01041         eclauses = nextclause;
01042     }
01043 
01044     return(NULL);
01045 
01046 } /* end of computeClauses */

static DdTlcInfo * computeClausesWithUniverse ( DdTlcInfo Cres,
DdHalfWord  label,
short  phase 
) [static]

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

Synopsis [Computes the two-literal clauses for a node.]

Description [Computes the two-literal clauses for a node with a zero child, given the clauses for its other child and the label of the node. Returns a pointer to a TclInfo structure if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [computeClauses]

Definition at line 1064 of file cuddEssent.c.

01068 {
01069     DdHalfWord *Ccv = Cres->vars; /* variables of clauses for child */
01070     BitVector *Ccp = Cres->phases; /* phases of clauses for child */
01071     DdHalfWord *Vcv = NULL; /* pointer to the variables of the clauses for v */
01072     BitVector *Vcp = NULL; /* pointer to the phases of the clauses for v */
01073     DdTlcInfo *res = NULL; /* the set of clauses to be returned */
01074     int i;
01075 
01076     /* Initialize result. */
01077     res = tlcInfoAlloc();
01078     if (res == NULL) goto cleanup;
01079     /* Count entries for new list and allocate accordingly. */
01080     for (i = 0; !sentinelp(Ccv[i], Ccv[i+1]); i += 2);
01081     /* At this point, i is twice the number of clauses in the child's
01082     ** list.  We need four more entries for this node: 2 for the one-literal
01083     ** clause for the label, and 2 for the sentinel. */
01084     Vcv = ALLOC(DdHalfWord,i+4);
01085     if (Vcv == NULL) goto cleanup;
01086     Vcp = bitVectorAlloc(i+4);
01087     if (Vcp == NULL) goto cleanup;
01088     res->vars = Vcv;
01089     res->phases = Vcp;
01090     /* Copy old list into new. */
01091     for (i = 0; !sentinelp(Ccv[i], Ccv[i+1]); i += 2) {
01092         Vcv[i] = Ccv[i];
01093         Vcv[i+1] = Ccv[i+1];
01094         bitVectorSet(Vcp, i, bitVectorRead(Ccp, i));
01095         bitVectorSet(Vcp, i+1, bitVectorRead(Ccp, i+1));
01096     }
01097     /* Add clause corresponding to label. */
01098     Vcv[i] = label;
01099     bitVectorSet(Vcp, i, phase);
01100     i++;
01101     Vcv[i] = CUDD_MAXINDEX;
01102     bitVectorSet(Vcp, i, 1);
01103     i++;
01104     /* Add sentinel. */
01105     Vcv[i] = 0;
01106     Vcv[i+1] = 0;
01107     bitVectorSet(Vcp, i, 0);
01108     bitVectorSet(Vcp, i+1, 0);
01109 
01110     return(res);
01111 
01112  cleanup:
01113     /* Vcp is guaranteed to be NULL here.  Hence, we do not try to free it. */
01114     if (Vcv != NULL) FREE(Vcv);
01115     if (res != NULL) Cudd_tlcInfoFree(res);
01116 
01117     return(NULL);
01118 
01119 } /* end of computeClausesWithUniverse */

int Cudd_bddIsVarEssential ( DdManager manager,
DdNode f,
int  id,
int  phase 
)

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

Synopsis [Determines whether a given variable is essential with a given phase in a BDD.]

Description [Determines whether a given variable is essential with a given phase in a BDD. Uses Cudd_bddIteConstant. Returns 1 if phase == 1 and f-->x_id, or if phase == 0 and f-->x_id'.]

SideEffects [None]

SeeAlso [Cudd_FindEssential]

Definition at line 235 of file cuddEssent.c.

00240 {
00241     DdNode      *var;
00242     int         res;
00243 
00244     var = Cudd_bddIthVar(manager, id);
00245 
00246     var = Cudd_NotCond(var,phase == 0);
00247 
00248     res = Cudd_bddLeq(manager, f, var);
00249 
00250     return(res);
00251 
00252 } /* end of Cudd_bddIsVarEssential */

DdNode* Cudd_FindEssential ( DdManager dd,
DdNode f 
)

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

Synopsis [Finds the essential variables of a DD.]

Description [Returns the cube of the essential variables. A positive literal means that the variable must be set to 1 for the function to be 1. A negative literal means that the variable must be set to 0 for the function to be 1. Returns a pointer to the cube BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddIsVarEssential]

Definition at line 205 of file cuddEssent.c.

00208 {
00209     DdNode *res;
00210 
00211     do {
00212         dd->reordered = 0;
00213         res = ddFindEssentialRecur(dd,f);
00214     } while (dd->reordered == 1);
00215     return(res);
00216 
00217 } /* end of Cudd_FindEssential */

DdTlcInfo* Cudd_FindTwoLiteralClauses ( DdManager dd,
DdNode f 
)

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

Synopsis [Finds the two literal clauses of a DD.]

Description [Returns the one- and two-literal clauses of a DD. Returns a pointer to the structure holding the clauses if successful; NULL otherwise. For a constant DD, the empty set of clauses is returned. This is obviously correct for a non-zero constant. For the constant zero, it is based on the assumption that only those clauses containing variables in the support of the function are considered. Since the support of a constant function is empty, no clauses are returned.]

SideEffects [None]

SeeAlso [Cudd_FindEssential]

Definition at line 273 of file cuddEssent.c.

00276 {
00277     DdTlcInfo *res;
00278     st_table *table;
00279     st_generator *gen;
00280     DdTlcInfo *tlc;
00281     DdNode *node;
00282     int size = dd->size;
00283 
00284     if (Cudd_IsConstant(f)) {
00285         res = emptyClauseSet();
00286         return(res);
00287     }
00288     table = st_init_table(st_ptrcmp,st_ptrhash);
00289     if (table == NULL) return(NULL);
00290     Tolv = bitVectorAlloc(size);
00291     if (Tolv == NULL) {
00292         st_free_table(table);
00293         return(NULL);
00294     }
00295     Tolp = bitVectorAlloc(size);
00296     if (Tolp == NULL) {
00297         st_free_table(table);
00298         bitVectorFree(Tolv);
00299         return(NULL);
00300     }
00301     Eolv = bitVectorAlloc(size);
00302     if (Eolv == NULL) {
00303         st_free_table(table);
00304         bitVectorFree(Tolv);
00305         bitVectorFree(Tolp);
00306         return(NULL);
00307     }
00308     Eolp = bitVectorAlloc(size);
00309     if (Eolp == NULL) {
00310         st_free_table(table);
00311         bitVectorFree(Tolv);
00312         bitVectorFree(Tolp);
00313         bitVectorFree(Eolv);
00314         return(NULL);
00315     }
00316 
00317     res = ddFindTwoLiteralClausesRecur(dd,f,table);
00318     /* Dispose of table contents and free table. */
00319     st_foreach_item(table, gen, &node, &tlc) {
00320         if (node != f) {
00321             Cudd_tlcInfoFree(tlc);
00322         }
00323     }
00324     st_free_table(table);
00325     bitVectorFree(Tolv);
00326     bitVectorFree(Tolp);
00327     bitVectorFree(Eolv);
00328     bitVectorFree(Eolp);
00329 
00330     if (res != NULL) {
00331         int i;
00332         for (i = 0; !sentinelp(res->vars[i], res->vars[i+1]); i += 2);
00333         res->cnt = i >> 1;
00334     }
00335 
00336     return(res);
00337 
00338 } /* end of Cudd_FindTwoLiteralClauses */

int Cudd_PrintTwoLiteralClauses ( DdManager dd,
DdNode f,
char **  names,
FILE *  fp 
)

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

Synopsis [Prints the two literal clauses of a DD.]

Description [Prints the one- and two-literal clauses. Returns 1 if successful; 0 otherwise. The argument "names" can be NULL, in which case the variable indices are printed.]

SideEffects [None]

SeeAlso [Cudd_FindTwoLiteralClauses]

Definition at line 389 of file cuddEssent.c.

00394 {
00395     DdHalfWord *vars;
00396     BitVector *phases;
00397     int i;
00398     DdTlcInfo *res = Cudd_FindTwoLiteralClauses(dd, f);
00399     FILE *ifp = fp == NULL ? dd->out : fp;
00400 
00401     if (res == NULL) return(0);
00402     vars = res->vars;
00403     phases = res->phases;
00404     for (i = 0; !sentinelp(vars[i], vars[i+1]); i += 2) {
00405         if (names != NULL) {
00406             if (vars[i+1] == CUDD_MAXINDEX) {
00407                 (void) fprintf(ifp, "%s%s\n",
00408                                bitVectorRead(phases, i) ? "~" : " ",
00409                                names[vars[i]]);
00410             } else {
00411                 (void) fprintf(ifp, "%s%s | %s%s\n",
00412                                bitVectorRead(phases, i) ? "~" : " ",
00413                                names[vars[i]],
00414                                bitVectorRead(phases, i+1) ? "~" : " ",
00415                                names[vars[i+1]]);
00416             }
00417         } else {
00418             if (vars[i+1] == CUDD_MAXINDEX) {
00419                 (void) fprintf(ifp, "%s%d\n",
00420                                bitVectorRead(phases, i) ? "~" : " ",
00421                                (int) vars[i]);
00422             } else {
00423                 (void) fprintf(ifp, "%s%d | %s%d\n",
00424                                bitVectorRead(phases, i) ? "~" : " ",
00425                                (int) vars[i],
00426                                bitVectorRead(phases, i+1) ? "~" : " ",
00427                                (int) vars[i+1]);
00428             }
00429         }
00430     }
00431     Cudd_tlcInfoFree(res);
00432 
00433     return(1);
00434 
00435 } /* end of Cudd_PrintTwoLiteralClauses */

int Cudd_ReadIthClause ( DdTlcInfo tlc,
int  i,
DdHalfWord var1,
DdHalfWord var2,
int *  phase1,
int *  phase2 
)

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

Synopsis [Accesses the i-th clause of a DD.]

Description [Accesses the i-th clause of a DD given the clause set which must be already computed. Returns 1 if successful; 0 if i is out of range, or in case of error.]

SideEffects [the four components of a clause are returned as side effects.]

SeeAlso [Cudd_FindTwoLiteralClauses]

Definition at line 355 of file cuddEssent.c.

00362 {
00363     if (tlc == NULL) return(0);
00364     if (tlc->vars == NULL || tlc->phases == NULL) return(0);
00365     if (i < 0 || (unsigned) i >= tlc->cnt) return(0);
00366     *var1 = tlc->vars[2*i];
00367     *var2 = tlc->vars[2*i+1];
00368     *phase1 = (int) bitVectorRead(tlc->phases, 2*i);
00369     *phase2 = (int) bitVectorRead(tlc->phases, 2*i+1);
00370     return(1);
00371 
00372 } /* end of Cudd_ReadIthClause */

void Cudd_tlcInfoFree ( DdTlcInfo t  ) 

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

Synopsis [Frees a DdTlcInfo Structure.]

Description [Frees a DdTlcInfo Structure as well as the memory pointed by it.]

SideEffects [None]

SeeAlso []

Definition at line 451 of file cuddEssent.c.

00453 {
00454     if (t->vars != NULL) FREE(t->vars);
00455     if (t->phases != NULL) FREE(t->phases);
00456     FREE(t);
00457 
00458 } /* end of Cudd_tlcInfoFree */

static DdNode * ddFindEssentialRecur ( DdManager dd,
DdNode f 
) [static]

AutomaticStart

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

Synopsis [Implements the recursive step of Cudd_FindEssential.]

Description [Implements the recursive step of Cudd_FindEssential. Returns a pointer to the cube BDD if successful; NULL otherwise.]

SideEffects [None]

Definition at line 482 of file cuddEssent.c.

00485 {
00486     DdNode      *T, *E, *F;
00487     DdNode      *essT, *essE, *res;
00488     int         index;
00489     DdNode      *one, *lzero, *azero;
00490 
00491     one = DD_ONE(dd);
00492     F = Cudd_Regular(f);
00493     /* If f is constant the set of essential variables is empty. */
00494     if (cuddIsConstant(F)) return(one);
00495 
00496     res = cuddCacheLookup1(dd,Cudd_FindEssential,f);
00497     if (res != NULL) {
00498         return(res);
00499     }
00500 
00501     lzero = Cudd_Not(one);
00502     azero = DD_ZERO(dd);
00503     /* Find cofactors: here f is non-constant. */
00504     T = cuddT(F);
00505     E = cuddE(F);
00506     if (Cudd_IsComplement(f)) {
00507         T = Cudd_Not(T); E = Cudd_Not(E);
00508     }
00509 
00510     index = F->index;
00511     if (Cudd_IsConstant(T) && T != lzero && T != azero) {
00512         /* if E is zero, index is essential, otherwise there are no
00513         ** essentials, because index is not essential and no other variable
00514         ** can be, since setting index = 1 makes the function constant and
00515         ** different from 0.
00516         */
00517         if (E == lzero || E == azero) {
00518             res = dd->vars[index];
00519         } else {
00520             res = one;
00521         }
00522     } else if (T == lzero || T == azero) {
00523         if (Cudd_IsConstant(E)) { /* E cannot be zero here */
00524             res = Cudd_Not(dd->vars[index]);
00525         } else { /* E == non-constant */
00526             /* find essentials in the else branch */
00527             essE = ddFindEssentialRecur(dd,E);
00528             if (essE == NULL) {
00529                 return(NULL);
00530             }
00531             cuddRef(essE);
00532 
00533             /* add index to the set with negative phase */
00534             res = cuddUniqueInter(dd,index,one,Cudd_Not(essE));
00535             if (res == NULL) {
00536                 Cudd_RecursiveDeref(dd,essE);
00537                 return(NULL);
00538             }
00539             res = Cudd_Not(res);
00540             cuddDeref(essE);
00541         }
00542     } else { /* T == non-const */
00543         if (E == lzero || E == azero) {
00544             /* find essentials in the then branch */
00545             essT = ddFindEssentialRecur(dd,T);
00546             if (essT == NULL) {
00547                 return(NULL);
00548             }
00549             cuddRef(essT);
00550 
00551             /* add index to the set with positive phase */
00552             /* use And because essT may be complemented */
00553             res = cuddBddAndRecur(dd,dd->vars[index],essT);
00554             if (res == NULL) {
00555                 Cudd_RecursiveDeref(dd,essT);
00556                 return(NULL);
00557             }
00558             cuddDeref(essT);
00559         } else if (!Cudd_IsConstant(E)) {
00560             /* if E is a non-zero constant there are no essentials
00561             ** because T is non-constant.
00562             */
00563             essT = ddFindEssentialRecur(dd,T);
00564             if (essT == NULL) {
00565                 return(NULL);
00566             }
00567             if (essT == one) {
00568                 res = one;
00569             } else {
00570                 cuddRef(essT);
00571                 essE = ddFindEssentialRecur(dd,E);
00572                 if (essE == NULL) {
00573                     Cudd_RecursiveDeref(dd,essT);
00574                     return(NULL);
00575                 }
00576                 cuddRef(essE);
00577 
00578                 /* res = intersection(essT, essE) */
00579                 res = cuddBddLiteralSetIntersectionRecur(dd,essT,essE);
00580                 if (res == NULL) {
00581                     Cudd_RecursiveDeref(dd,essT);
00582                     Cudd_RecursiveDeref(dd,essE);
00583                     return(NULL);
00584                 }
00585                 cuddRef(res);
00586                 Cudd_RecursiveDeref(dd,essT);
00587                 Cudd_RecursiveDeref(dd,essE);
00588                 cuddDeref(res);
00589             }
00590         } else {        /* E is a non-zero constant */
00591             res = one;
00592         }
00593     }
00594 
00595     cuddCacheInsert1(dd,Cudd_FindEssential, f, res);
00596     return(res);
00597 
00598 } /* end of ddFindEssentialRecur */

static DdTlcInfo * ddFindTwoLiteralClausesRecur ( DdManager dd,
DdNode f,
st_table table 
) [static]

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

Synopsis [Implements the recursive step of Cudd_FindTwoLiteralClauses.]

Description [Implements the recursive step of Cudd_FindTwoLiteralClauses. The DD node is assumed to be not constant. Returns a pointer to a set of clauses if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_FindTwoLiteralClauses]

Definition at line 616 of file cuddEssent.c.

00620 {
00621     DdNode *T, *E, *F;
00622     DdNode *one, *lzero, *azero;
00623     DdTlcInfo *res, *Tres, *Eres;
00624     DdHalfWord index;
00625 
00626     F = Cudd_Regular(f);
00627 
00628     assert(!cuddIsConstant(F));
00629 
00630     /* Check computed table.  Separate entries are necessary for
00631     ** a node and its complement.  We should update the counter here. */
00632     if (st_lookup(table, f, &res)) {
00633         return(res);
00634     }
00635 
00636     /* Easy access to the constants for BDDs and ADDs. */
00637     one = DD_ONE(dd);
00638     lzero = Cudd_Not(one);
00639     azero = DD_ZERO(dd);
00640 
00641     /* Find cofactors and variable labeling the top node. */
00642     T = cuddT(F); E = cuddE(F);
00643     if (Cudd_IsComplement(f)) {
00644         T = Cudd_Not(T); E = Cudd_Not(E);
00645     }
00646     index = F->index;
00647 
00648     if (Cudd_IsConstant(T) && T != lzero && T != azero) {
00649         /* T is a non-zero constant.  If E is zero, then this node's index
00650         ** is a one-literal clause.  Otherwise, if E is a non-zero
00651         ** constant, there are no clauses for this node.  Finally,
00652         ** if E is not constant, we recursively compute its clauses, and then
00653         ** merge using the empty set for T. */
00654         if (E == lzero || E == azero) {
00655             /* Create the clause (index + 0). */
00656             res = tlcInfoAlloc();
00657             if (res == NULL) return(NULL);
00658             res->vars = ALLOC(DdHalfWord,4);
00659             if (res->vars == NULL) {
00660                 FREE(res);
00661                 return(NULL);
00662             }
00663             res->phases = bitVectorAlloc(2);
00664             if (res->phases == NULL) {
00665                 FREE(res->vars);
00666                 FREE(res);
00667                 return(NULL);
00668             }
00669             res->vars[0] = index;
00670             res->vars[1] = CUDD_MAXINDEX;
00671             res->vars[2] = 0;
00672             res->vars[3] = 0;
00673             bitVectorSet(res->phases, 0, 0); /* positive phase */
00674             bitVectorSet(res->phases, 1, 1); /* negative phase */
00675         } else if (Cudd_IsConstant(E)) {
00676             /* If E is a non-zero constant, no clauses. */
00677             res = emptyClauseSet();
00678         } else {
00679             /* E is non-constant */
00680             Tres = emptyClauseSet();
00681             if (Tres == NULL) return(NULL);
00682             Eres = ddFindTwoLiteralClausesRecur(dd, E, table);
00683             if (Eres == NULL) {
00684                 Cudd_tlcInfoFree(Tres);
00685                 return(NULL);
00686             }
00687             res = computeClauses(Tres, Eres, index, dd->size);
00688             Cudd_tlcInfoFree(Tres);
00689         }
00690     } else if (T == lzero || T == azero) {
00691         /* T is zero.  If E is a non-zero constant, then the
00692         ** complement of this node's index is a one-literal clause.
00693         ** Otherwise, if E is not constant, we recursively compute its
00694         ** clauses, and then merge using the universal set for T. */
00695         if (Cudd_IsConstant(E)) { /* E cannot be zero here */
00696             /* Create the clause (!index + 0). */
00697             res = tlcInfoAlloc();
00698             if (res == NULL) return(NULL);
00699             res->vars = ALLOC(DdHalfWord,4);
00700             if (res->vars == NULL) {
00701                 FREE(res);
00702                 return(NULL);
00703             }
00704             res->phases = bitVectorAlloc(2);
00705             if (res->phases == NULL) {
00706                 FREE(res->vars);
00707                 FREE(res);
00708                 return(NULL);
00709             }
00710             res->vars[0] = index;
00711             res->vars[1] = CUDD_MAXINDEX;
00712             res->vars[2] = 0;
00713             res->vars[3] = 0;
00714             bitVectorSet(res->phases, 0, 1); /* negative phase */
00715             bitVectorSet(res->phases, 1, 1); /* negative phase */
00716         } else { /* E == non-constant */
00717             Eres = ddFindTwoLiteralClausesRecur(dd, E, table);
00718             if (Eres == NULL) return(NULL);
00719             res = computeClausesWithUniverse(Eres, index, 1);
00720         }
00721     } else { /* T == non-const */
00722         Tres = ddFindTwoLiteralClausesRecur(dd, T, table);
00723         if (Tres == NULL) return(NULL);
00724         if (Cudd_IsConstant(E)) {
00725             if (E == lzero || E == azero) {
00726                 res = computeClausesWithUniverse(Tres, index, 0);
00727             } else {
00728                 Eres = emptyClauseSet();
00729                 if (Eres == NULL) return(NULL);
00730                 res = computeClauses(Tres, Eres, index, dd->size);
00731                 Cudd_tlcInfoFree(Eres);
00732             }
00733         } else {
00734             Eres = ddFindTwoLiteralClausesRecur(dd, E, table);
00735             if (Eres == NULL) return(NULL);
00736             res = computeClauses(Tres, Eres, index, dd->size);
00737         }
00738     }
00739 
00740     /* Cache results. */
00741     if (st_add_direct(table, (char *)f, (char *)res) == ST_OUT_OF_MEM) {
00742         FREE(res);
00743         return(NULL);
00744     }
00745     return(res);
00746 
00747 } /* end of ddFindTwoLiteralClausesRecur */

static DdTlcInfo * emptyClauseSet ( void   )  [static]

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

Synopsis [Returns an enpty set of clauses.]

Description [Returns a pointer to an empty set of clauses if successful; NULL otherwise. No bit vector for the phases is allocated.]

SideEffects [None]

SeeAlso []

Definition at line 1136 of file cuddEssent.c.

01137 {
01138     DdTlcInfo *eset;
01139 
01140     eset = ALLOC(DdTlcInfo,1);
01141     if (eset == NULL) return(NULL);
01142     eset->vars = ALLOC(DdHalfWord,2);
01143     if (eset->vars == NULL) {
01144         FREE(eset);
01145         return(NULL);
01146     }
01147     /* Sentinel */
01148     eset->vars[0] = 0;
01149     eset->vars[1] = 0;
01150     eset->phases = NULL; /* does not matter */
01151     eset->cnt = 0;
01152     return(eset);
01153 
01154 } /* end of emptyClauseSet */

static int equalp ( DdHalfWord  var1a,
short  phase1a,
DdHalfWord  var1b,
short  phase1b,
DdHalfWord  var2a,
short  phase2a,
DdHalfWord  var2b,
short  phase2b 
) [static]

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

Synopsis [Returns true iff the two arguments are identical clauses.]

Description [Returns true iff the two arguments are identical clauses. Since literals are sorted, we only need to compare literals in the same position.]

SideEffects [None]

SeeAlso [beforep]

Definition at line 1193 of file cuddEssent.c.

01202 {
01203     return(var1a == var2a && phase1a == phase2a &&
01204            var1b == var2b && phase1b == phase2b);
01205 
01206 } /* end of equalp */

static int impliedp ( DdHalfWord  var1,
short  phase1,
DdHalfWord  var2,
short  phase2,
BitVector olv,
BitVector olp 
) [static]

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

Synopsis [Returns true iff either literal of a clause is in a set of literals.]

Description [Returns true iff either literal of a clause is in a set of literals. The first four arguments specify the clause. The remaining two arguments specify the literal set.]

SideEffects [None]

SeeAlso []

Definition at line 1284 of file cuddEssent.c.

01291 {
01292     return((bitVectorRead(olv, var1) &&
01293             bitVectorRead(olp, var1) == phase1) ||
01294            (bitVectorRead(olv, var2) &&
01295             bitVectorRead(olp, var2) == phase2));
01296 
01297 } /* end of impliedp */

static int oneliteralp ( DdHalfWord  var  )  [static]

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

Synopsis [Returns true iff the argument is a one-literal clause.]

Description [Returns true iff the argument is a one-literal clause. A one-litaral clause has the constant FALSE as second literal. Since the constant TRUE is never used, it is sufficient to test for a constant.]

SideEffects [None]

SeeAlso []

Definition at line 1261 of file cuddEssent.c.

01263 {
01264     return(var == CUDD_MAXINDEX);
01265 
01266 } /* end of oneliteralp */

static int sentinelp ( DdHalfWord  var1,
DdHalfWord  var2 
) [static]

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

Synopsis [Returns true iff the argument is the sentinel clause.]

Description [Returns true iff the argument is the sentinel clause. A sentinel clause has both variables equal to 0.]

SideEffects [None]

SeeAlso []

Definition at line 1170 of file cuddEssent.c.

01173 {
01174     return(var1 == 0 && var2 == 0);
01175 
01176 } /* end of sentinelp */

static DdTlcInfo * tlcInfoAlloc ( void   )  [static]

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

Synopsis [Allocates a DdTlcInfo Structure.]

Description [Returns a pointer to a DdTlcInfo Structure if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_tlcInfoFree]

Definition at line 1458 of file cuddEssent.c.

01459 {
01460     DdTlcInfo *res = ALLOC(DdTlcInfo,1);
01461     if (res == NULL) return(NULL);
01462     res->vars = NULL;
01463     res->phases = NULL;
01464     res->cnt = 0;
01465     return(res);
01466 
01467 } /* end of tlcInfoAlloc */


Variable Documentation

char rcsid [] DD_UNUSED = "$Id: cuddEssent.c,v 1.24 2009/02/21 18:24:10 fabio Exp $" [static]

Definition at line 146 of file cuddEssent.c.

BitVector* Eolp [static]

Definition at line 152 of file cuddEssent.c.

BitVector* Eolv [static]

Definition at line 151 of file cuddEssent.c.

BitVector* Tolp [static]

Definition at line 150 of file cuddEssent.c.

BitVector* Tolv [static]

Definition at line 149 of file cuddEssent.c.


Generated on Tue Jan 12 13:57:19 2010 for glu-2.2 by  doxygen 1.6.1