#include "util.h"
#include "cuddInt.h"
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 DdNode * | ddFindEssentialRecur (DdManager *dd, DdNode *f) |
static DdTlcInfo * | ddFindTwoLiteralClausesRecur (DdManager *dd, DdNode *f, st_table *table) |
static DdTlcInfo * | computeClauses (DdTlcInfo *Tres, DdTlcInfo *Eres, DdHalfWord label, int size) |
static DdTlcInfo * | computeClausesWithUniverse (DdTlcInfo *Cres, DdHalfWord label, short phase) |
static DdTlcInfo * | emptyClauseSet (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 BitVector * | bitVectorAlloc (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 DdTlcInfo * | tlcInfoAlloc (void) |
DdNode * | Cudd_FindEssential (DdManager *dd, DdNode *f) |
int | Cudd_bddIsVarEssential (DdManager *manager, DdNode *f, int id, int phase) |
DdTlcInfo * | Cudd_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 BitVector * | Tolv |
static BitVector * | Tolp |
static BitVector * | Eolv |
static BitVector * | Eolp |
#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 long BitVector |
Definition at line 138 of file cuddEssent.c.
Definition at line 139 of file cuddEssent.c.
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.
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.
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.
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 */
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 */
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 */
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 */
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.
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.
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.
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.
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.
Definition at line 152 of file cuddEssent.c.
Definition at line 151 of file cuddEssent.c.
Definition at line 150 of file cuddEssent.c.
Definition at line 149 of file cuddEssent.c.