ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
extraBdd.h File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "misc/st/st.h"
#include "bdd/cudd/cuddInt.h"
#include "misc/extra/extra.h"
Include dependency graph for extraBdd.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  Extra_SymmInfo_t_
 
struct  Extra_UnateVar_t_
 
struct  Extra_UnateInfo_t_
 

Macros

#define b0   Cudd_Not((dd)->one)
 
#define b1   (dd)->one
 
#define z0   (dd)->zero
 
#define z1   (dd)->one
 
#define a0   (dd)->zero
 
#define a1   (dd)->one
 
#define hashKey1(a, TSIZE)
 
#define hashKey2(a, b, TSIZE)
 
#define hashKey3(a, b, c, TSIZE)
 
#define hashKey4(a, b, c, d, TSIZE)
 
#define hashKey5(a, b, c, d, e, TSIZE)
 
#define ABC_PRB(dd, f)
 

Typedefs

typedef struct Extra_ImageTree_t_ Extra_ImageTree_t
 
typedef struct Extra_ImageTree2_t_ Extra_ImageTree2_t
 
typedef struct Extra_SymmInfo_t_ Extra_SymmInfo_t
 
typedef struct Extra_UnateVar_t_ Extra_UnateVar_t
 
typedef struct Extra_UnateInfo_t_ Extra_UnateInfo_t
 

Functions

DdNode * Extra_bddSpaceFromFunctionFast (DdManager *dd, DdNode *bFunc)
 
DdNode * Extra_bddSpaceFromFunction (DdManager *dd, DdNode *bF, DdNode *bG)
 
DdNode * extraBddSpaceFromFunction (DdManager *dd, DdNode *bF, DdNode *bG)
 
DdNode * Extra_bddSpaceFromFunctionPos (DdManager *dd, DdNode *bFunc)
 
DdNode * extraBddSpaceFromFunctionPos (DdManager *dd, DdNode *bFunc)
 
DdNode * Extra_bddSpaceFromFunctionNeg (DdManager *dd, DdNode *bFunc)
 
DdNode * extraBddSpaceFromFunctionNeg (DdManager *dd, DdNode *bFunc)
 
DdNode * Extra_bddSpaceCanonVars (DdManager *dd, DdNode *bSpace)
 
DdNode * extraBddSpaceCanonVars (DdManager *dd, DdNode *bSpace)
 
DdNode * Extra_bddSpaceEquations (DdManager *dd, DdNode *bSpace)
 
DdNode * Extra_bddSpaceEquationsNeg (DdManager *dd, DdNode *bSpace)
 
DdNode * extraBddSpaceEquationsNeg (DdManager *dd, DdNode *bSpace)
 
DdNode * Extra_bddSpaceEquationsPos (DdManager *dd, DdNode *bSpace)
 
DdNode * extraBddSpaceEquationsPos (DdManager *dd, DdNode *bSpace)
 
DdNode * Extra_bddSpaceFromMatrixPos (DdManager *dd, DdNode *zA)
 
DdNode * extraBddSpaceFromMatrixPos (DdManager *dd, DdNode *zA)
 
DdNode * Extra_bddSpaceFromMatrixNeg (DdManager *dd, DdNode *zA)
 
DdNode * extraBddSpaceFromMatrixNeg (DdManager *dd, DdNode *zA)
 
DdNode * Extra_bddSpaceReduce (DdManager *dd, DdNode *bFunc, DdNode *bCanonVars)
 
DdNode ** Extra_bddSpaceExorGates (DdManager *dd, DdNode *bFuncRed, DdNode *zEquations)
 
DdNode * Extra_bddEncodingBinary (DdManager *dd, DdNode **pbFuncs, int nFuncs, DdNode **pbVars, int nVars)
 
DdNode * Extra_bddEncodingNonStrict (DdManager *dd, DdNode **pbColumns, int nColumns, DdNode *bVarsCol, DdNode **pCVars, int nMulti, int *pSimple)
 
st__tableExtra_bddNodePathsUnderCut (DdManager *dd, DdNode *bFunc, int CutLevel)
 
int Extra_bddNodePathsUnderCutArray (DdManager *dd, DdNode **paNodes, DdNode **pbCubes, int nNodes, DdNode **paNodesRes, DdNode **pbCubesRes, int CutLevel)
 
int Extra_ProfileWidth (DdManager *dd, DdNode *F, int *Profile, int CutLevel)
 
Extra_ImageTree_tExtra_bddImageStart (DdManager *dd, DdNode *bCare, int nParts, DdNode **pbParts, int nVars, DdNode **pbVars, int fVerbose)
 
DdNode * Extra_bddImageCompute (Extra_ImageTree_t *pTree, DdNode *bCare)
 
void Extra_bddImageTreeDelete (Extra_ImageTree_t *pTree)
 
DdNode * Extra_bddImageRead (Extra_ImageTree_t *pTree)
 
Extra_ImageTree2_tExtra_bddImageStart2 (DdManager *dd, DdNode *bCare, int nParts, DdNode **pbParts, int nVars, DdNode **pbVars, int fVerbose)
 
DdNode * Extra_bddImageCompute2 (Extra_ImageTree2_t *pTree, DdNode *bCare)
 
void Extra_bddImageTreeDelete2 (Extra_ImageTree2_t *pTree)
 
DdNode * Extra_bddImageRead2 (Extra_ImageTree2_t *pTree)
 
DdNode * Extra_TransferPermute (DdManager *ddSource, DdManager *ddDestination, DdNode *f, int *Permute)
 
DdNode * Extra_TransferLevelByLevel (DdManager *ddSource, DdManager *ddDestination, DdNode *f)
 
DdNode * Extra_bddRemapUp (DdManager *dd, DdNode *bF)
 
DdNode * Extra_bddMove (DdManager *dd, DdNode *bF, int nVars)
 
DdNode * extraBddMove (DdManager *dd, DdNode *bF, DdNode *bFlag)
 
void Extra_StopManager (DdManager *dd)
 
void Extra_bddPrint (DdManager *dd, DdNode *F)
 
void Extra_bddPrintSupport (DdManager *dd, DdNode *F)
 
void extraDecomposeCover (DdManager *dd, DdNode *zC, DdNode **zC0, DdNode **zC1, DdNode **zC2)
 
int Extra_bddSuppSize (DdManager *dd, DdNode *bSupp)
 
int Extra_bddSuppContainVar (DdManager *dd, DdNode *bS, DdNode *bVar)
 
int Extra_bddSuppOverlapping (DdManager *dd, DdNode *S1, DdNode *S2)
 
int Extra_bddSuppDifferentVars (DdManager *dd, DdNode *S1, DdNode *S2, int DiffMax)
 
int Extra_bddSuppCheckContainment (DdManager *dd, DdNode *bL, DdNode *bH, DdNode **bLarge, DdNode **bSmall)
 
int * Extra_SupportArray (DdManager *dd, DdNode *F, int *support)
 
int * Extra_VectorSupportArray (DdManager *dd, DdNode **F, int n, int *support)
 
DdNode * Extra_bddFindOneCube (DdManager *dd, DdNode *bF)
 
DdNode * Extra_bddGetOneCube (DdManager *dd, DdNode *bFunc)
 
DdNode * Extra_bddComputeRangeCube (DdManager *dd, int iStart, int iStop)
 
DdNode * Extra_bddBitsToCube (DdManager *dd, int Code, int CodeWidth, DdNode **pbVars, int fMsbFirst)
 
DdNode * Extra_bddSupportNegativeCube (DdManager *dd, DdNode *f)
 
int Extra_bddIsVar (DdNode *bFunc)
 
DdNode * Extra_bddCreateAnd (DdManager *dd, int nVars)
 
DdNode * Extra_bddCreateOr (DdManager *dd, int nVars)
 
DdNode * Extra_bddCreateExor (DdManager *dd, int nVars)
 
DdNode * Extra_zddPrimes (DdManager *dd, DdNode *F)
 
void Extra_bddPermuteArray (DdManager *dd, DdNode **bNodesIn, DdNode **bNodesOut, int nNodes, int *permut)
 
DdNode * Extra_bddComputeCube (DdManager *dd, DdNode **bXVars, int nVars)
 
DdNode * Extra_bddChangePolarity (DdManager *dd, DdNode *bFunc, DdNode *bVars)
 
DdNode * extraBddChangePolarity (DdManager *dd, DdNode *bFunc, DdNode *bVars)
 
int Extra_bddVarIsInCube (DdNode *bCube, int iVar)
 
DdNode * Extra_bddAndPermute (DdManager *ddF, DdNode *bF, DdManager *ddG, DdNode *bG, int *pPermute)
 
int Extra_bddCountCubes (DdManager *dd, DdNode **pFuncs, int nFuncs, int fMode, int nLimit, int *pGuide)
 
void Extra_zddDumpPla (DdManager *dd, DdNode *zCover, int nVars, char *pFileName)
 
DdNode * Extra_bddTuples (DdManager *dd, int K, DdNode *bVarsN)
 
DdNode * extraBddTuples (DdManager *dd, DdNode *bVarsK, DdNode *bVarsN)
 
DdNode * Extra_zddMaximal (DdManager *dd, DdNode *S)
 
DdNode * extraZddMaximal (DdManager *dd, DdNode *S)
 
DdNode * Extra_zddMinimal (DdManager *dd, DdNode *S)
 
DdNode * extraZddMinimal (DdManager *dd, DdNode *S)
 
DdNode * Extra_zddMaxUnion (DdManager *dd, DdNode *S, DdNode *T)
 
DdNode * extraZddMaxUnion (DdManager *dd, DdNode *S, DdNode *T)
 
DdNode * Extra_zddMinUnion (DdManager *dd, DdNode *S, DdNode *T)
 
DdNode * extraZddMinUnion (DdManager *dd, DdNode *S, DdNode *T)
 
DdNode * Extra_zddDotProduct (DdManager *dd, DdNode *S, DdNode *T)
 
DdNode * extraZddDotProduct (DdManager *dd, DdNode *S, DdNode *T)
 
DdNode * Extra_zddCrossProduct (DdManager *dd, DdNode *S, DdNode *T)
 
DdNode * extraZddCrossProduct (DdManager *dd, DdNode *S, DdNode *T)
 
DdNode * Extra_zddMaxDotProduct (DdManager *dd, DdNode *S, DdNode *T)
 
DdNode * extraZddMaxDotProduct (DdManager *dd, DdNode *S, DdNode *T)
 
DdNode * Extra_zddSubSet (DdManager *dd, DdNode *X, DdNode *Y)
 
DdNode * extraZddSubSet (DdManager *dd, DdNode *X, DdNode *Y)
 
DdNode * Extra_zddSupSet (DdManager *dd, DdNode *X, DdNode *Y)
 
DdNode * extraZddSupSet (DdManager *dd, DdNode *X, DdNode *Y)
 
DdNode * Extra_zddNotSubSet (DdManager *dd, DdNode *X, DdNode *Y)
 
DdNode * extraZddNotSubSet (DdManager *dd, DdNode *X, DdNode *Y)
 
DdNode * Extra_zddNotSupSet (DdManager *dd, DdNode *X, DdNode *Y)
 
DdNode * extraZddNotSupSet (DdManager *dd, DdNode *X, DdNode *Y)
 
DdNode * Extra_zddMaxNotSupSet (DdManager *dd, DdNode *X, DdNode *Y)
 
DdNode * extraZddMaxNotSupSet (DdManager *dd, DdNode *X, DdNode *Y)
 
int Extra_zddEmptyBelongs (DdManager *dd, DdNode *zS)
 
int Extra_zddIsOneSubset (DdManager *dd, DdNode *zS)
 
void Extra_PrintKMap (FILE *pFile, DdManager *dd, DdNode *OnSet, DdNode *OffSet, int nVars, DdNode **XVars, int fSuppType, char **pVarNames)
 
void Extra_PrintKMapRelation (FILE *pFile, DdManager *dd, DdNode *OnSet, DdNode *OffSet, int nXVars, int nYVars, DdNode **XVars, DdNode **YVars)
 
Extra_SymmInfo_tExtra_SymmPairsCompute (DdManager *dd, DdNode *bFunc)
 
Extra_SymmInfo_tExtra_SymmPairsComputeNaive (DdManager *dd, DdNode *bFunc)
 
int Extra_bddCheckVarsSymmetricNaive (DdManager *dd, DdNode *bF, int iVar1, int iVar2)
 
Extra_SymmInfo_tExtra_SymmPairsAllocate (int nVars)
 
void Extra_SymmPairsDissolve (Extra_SymmInfo_t *)
 
void Extra_SymmPairsPrint (Extra_SymmInfo_t *)
 
Extra_SymmInfo_tExtra_SymmPairsCreateFromZdd (DdManager *dd, DdNode *zPairs, DdNode *bVars)
 
DdNode * Extra_zddSymmPairsCompute (DdManager *dd, DdNode *bF, DdNode *bVars)
 
DdNode * extraZddSymmPairsCompute (DdManager *dd, DdNode *bF, DdNode *bVars)
 
DdNode * Extra_zddGetSymmetricVars (DdManager *dd, DdNode *bF, DdNode *bG, DdNode *bVars)
 
DdNode * extraZddGetSymmetricVars (DdManager *dd, DdNode *bF, DdNode *bG, DdNode *bVars)
 
DdNode * Extra_zddGetSingletons (DdManager *dd, DdNode *bVars)
 
DdNode * extraZddGetSingletons (DdManager *dd, DdNode *bVars)
 
DdNode * Extra_bddReduceVarSet (DdManager *dd, DdNode *bVars, DdNode *bF)
 
DdNode * extraBddReduceVarSet (DdManager *dd, DdNode *bVars, DdNode *bF)
 
int Extra_bddCheckVarsSymmetric (DdManager *dd, DdNode *bF, int iVar1, int iVar2)
 
DdNode * extraBddCheckVarsSymmetric (DdManager *dd, DdNode *bF, DdNode *bVars)
 
DdNode * Extra_zddTuplesFromBdd (DdManager *dd, int K, DdNode *bVarsN)
 
DdNode * extraZddTuplesFromBdd (DdManager *dd, DdNode *bVarsK, DdNode *bVarsN)
 
DdNode * Extra_zddSelectOneSubset (DdManager *dd, DdNode *zS)
 
DdNode * extraZddSelectOneSubset (DdManager *dd, DdNode *zS)
 
DdNode * Extra_bddAndTime (DdManager *dd, DdNode *f, DdNode *g, int TimeOut)
 
DdNode * Extra_bddAndAbstractTime (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, int TimeOut)
 
DdNode * Extra_TransferPermuteTime (DdManager *ddSource, DdManager *ddDestination, DdNode *f, int *Permute, int TimeOut)
 
Extra_UnateInfo_tExtra_UnateInfoAllocate (int nVars)
 
void Extra_UnateInfoDissolve (Extra_UnateInfo_t *)
 
void Extra_UnateInfoPrint (Extra_UnateInfo_t *)
 
Extra_UnateInfo_tExtra_UnateInfoCreateFromZdd (DdManager *dd, DdNode *zUnate, DdNode *bVars)
 
int Extra_bddCheckUnateNaive (DdManager *dd, DdNode *bF, int iVar)
 
Extra_UnateInfo_tExtra_UnateComputeFast (DdManager *dd, DdNode *bFunc)
 
Extra_UnateInfo_tExtra_UnateComputeSlow (DdManager *dd, DdNode *bFunc)
 
DdNode * Extra_zddUnateInfoCompute (DdManager *dd, DdNode *bF, DdNode *bVars)
 
DdNode * extraZddUnateInfoCompute (DdManager *dd, DdNode *bF, DdNode *bVars)
 
DdNode * Extra_zddGetSingletonsBoth (DdManager *dd, DdNode *bVars)
 
DdNode * extraZddGetSingletonsBoth (DdManager *dd, DdNode *bVars)
 

Macro Definition Documentation

◆ a0

#define a0   (dd)->zero

Definition at line 79 of file extraBdd.h.

◆ a1

#define a1   (dd)->one

Definition at line 80 of file extraBdd.h.

◆ ABC_PRB

#define ABC_PRB ( dd,
f )
Value:
printf("%s = ", #f); Extra_bddPrint(dd,f); printf("\n")
void Extra_bddPrint(DdManager *dd, DdNode *F)

Definition at line 206 of file extraBdd.h.

◆ b0

#define b0   Cudd_Not((dd)->one)

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

FileName [extraBdd.h]

SystemName [ABC: Logic synthesis and verification system.]

PackageName [extra]

Synopsis [Various reusable software utilities.]

Description [This library contains a number of operators and traversal routines developed to extend the functionality of CUDD v.2.3.x, by Fabio Somenzi (http://vlsi.colorado.edu/~fabio/) To compile your code with the library, #include "extra.h" in your source files and link your project to CUDD and this library. Use the library at your own risk and with caution. Note that debugging of some operators still continues.]

Author [Alan Mishchenko]

Affiliation [UC Berkeley]

Date [Ver. 1.0. Started - June 20, 2005.]

Revision [

Id
extraBdd.h,v 1.00 2005/06/20 00:00:00 alanmi Exp

]

Definition at line 75 of file extraBdd.h.

◆ b1

#define b1   (dd)->one

Definition at line 76 of file extraBdd.h.

◆ hashKey1

#define hashKey1 ( a,
TSIZE )
Value:
((ABC_PTRUINT_T)(a) % TSIZE)

Definition at line 83 of file extraBdd.h.

83#define hashKey1(a,TSIZE) \
84((ABC_PTRUINT_T)(a) % TSIZE)

◆ hashKey2

#define hashKey2 ( a,
b,
TSIZE )
Value:
(((ABC_PTRUINT_T)(a) + (ABC_PTRUINT_T)(b) * DD_P1) % TSIZE)
#define DD_P1
Definition cloud.h:177

Definition at line 86 of file extraBdd.h.

86#define hashKey2(a,b,TSIZE) \
87(((ABC_PTRUINT_T)(a) + (ABC_PTRUINT_T)(b) * DD_P1) % TSIZE)

◆ hashKey3

#define hashKey3 ( a,
b,
c,
TSIZE )
Value:
(((((ABC_PTRUINT_T)(a) + (ABC_PTRUINT_T)(b)) * DD_P1 + (ABC_PTRUINT_T)(c)) * DD_P2 ) % TSIZE)
#define DD_P2
Definition cloud.h:178

Definition at line 89 of file extraBdd.h.

89#define hashKey3(a,b,c,TSIZE) \
90(((((ABC_PTRUINT_T)(a) + (ABC_PTRUINT_T)(b)) * DD_P1 + (ABC_PTRUINT_T)(c)) * DD_P2 ) % TSIZE)

◆ hashKey4

#define hashKey4 ( a,
b,
c,
d,
TSIZE )
Value:
((((((ABC_PTRUINT_T)(a) + (ABC_PTRUINT_T)(b)) * DD_P1 + (ABC_PTRUINT_T)(c)) * DD_P2 + \
(ABC_PTRUINT_T)(d)) * DD_P3) % TSIZE)
#define DD_P3
Definition cloud.h:179

Definition at line 92 of file extraBdd.h.

92#define hashKey4(a,b,c,d,TSIZE) \
93((((((ABC_PTRUINT_T)(a) + (ABC_PTRUINT_T)(b)) * DD_P1 + (ABC_PTRUINT_T)(c)) * DD_P2 + \
94 (ABC_PTRUINT_T)(d)) * DD_P3) % TSIZE)

◆ hashKey5

#define hashKey5 ( a,
b,
c,
d,
e,
TSIZE )
Value:
(((((((ABC_PTRUINT_T)(a) + (ABC_PTRUINT_T)(b)) * DD_P1 + (ABC_PTRUINT_T)(c)) * DD_P2 + \
(ABC_PTRUINT_T)(d)) * DD_P3 + (ABC_PTRUINT_T)(e)) * DD_P1) % TSIZE)

Definition at line 96 of file extraBdd.h.

96#define hashKey5(a,b,c,d,e,TSIZE) \
97(((((((ABC_PTRUINT_T)(a) + (ABC_PTRUINT_T)(b)) * DD_P1 + (ABC_PTRUINT_T)(c)) * DD_P2 + \
98 (ABC_PTRUINT_T)(d)) * DD_P3 + (ABC_PTRUINT_T)(e)) * DD_P1) % TSIZE)

◆ z0

#define z0   (dd)->zero

Definition at line 77 of file extraBdd.h.

◆ z1

#define z1   (dd)->one

Definition at line 78 of file extraBdd.h.

Typedef Documentation

◆ Extra_ImageTree2_t

Definition at line 155 of file extraBdd.h.

◆ Extra_ImageTree_t

Definition at line 146 of file extraBdd.h.

◆ Extra_SymmInfo_t

Definition at line 256 of file extraBdd.h.

◆ Extra_UnateInfo_t

Definition at line 320 of file extraBdd.h.

◆ Extra_UnateVar_t

Definition at line 313 of file extraBdd.h.

Function Documentation

◆ Extra_bddAndAbstractTime()

DdNode * Extra_bddAndAbstractTime ( DdManager * manager,
DdNode * f,
DdNode * g,
DdNode * cube,
int TimeOut )
extern

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

Synopsis [Takes the AND of two BDDs and simultaneously abstracts the variables in cube.]

Description [Takes the AND of two BDDs and simultaneously abstracts the variables in cube. The variables are existentially abstracted. Returns a pointer to the result is successful; NULL otherwise. Cudd_bddAndAbstract implements the semiring matrix multiplication algorithm for the boolean semiring.]

SideEffects [None]

SeeAlso [Cudd_addMatrixMultiply Cudd_addTriangle Cudd_bddAnd]

Definition at line 117 of file extraBddTime.c.

123{
124 DdNode *res;
125 int Counter = 0;
126
127 do {
128 manager->reordered = 0;
129 res = cuddBddAndAbstractRecurTime(manager, f, g, cube, &Counter, TimeOut);
130 } while (manager->reordered == 1);
131 return(res);
132
133} /* end of Extra_bddAndAbstractTime */
Definition exor.h:123

◆ Extra_bddAndPermute()

DdNode * Extra_bddAndPermute ( DdManager * ddF,
DdNode * bF,
DdManager * ddG,
DdNode * bG,
int * pPermute )
extern

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

Synopsis [Computes the AND of two BDD with different orders.]

Description [Derives the result of Boolean AND of bF and bG in ddF. The array pPermute gives the mapping of variables of ddG into that of ddF.]

SideEffects []

SeeAlso []

Definition at line 1090 of file extraBddMisc.c.

1091{
1092 DdHashTable * table;
1093 DdNode * bRes;
1094 do
1095 {
1096 ddF->reordered = 0;
1097 table = cuddHashTableInit( ddF, 2, 256 );
1098 if (table == NULL) return NULL;
1099 bRes = extraBddAndPermute( table, ddF, bF, ddG, bG, pPermute );
1100 if ( bRes ) cuddRef( bRes );
1101 cuddHashTableQuit( table );
1102 if ( bRes ) cuddDeref( bRes );
1103//if ( ddF->reordered == 1 )
1104//printf( "Reordering happened\n" );
1105 }
1106 while ( ddF->reordered == 1 );
1107//printf( "|F| =%6d |G| =%6d |H| =%6d |F|*|G| =%9d\n",
1108// Cudd_DagSize(bF), Cudd_DagSize(bG), Cudd_DagSize(bRes),
1109// Cudd_DagSize(bF) * Cudd_DagSize(bG) );
1110 return ( bRes );
1111}
Here is the caller graph for this function:

◆ Extra_bddAndTime()

DdNode * Extra_bddAndTime ( DdManager * dd,
DdNode * f,
DdNode * g,
int TimeOut )
extern

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

Synopsis [Computes the conjunction of two BDDs f and g.]

Description [Computes the conjunction of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]

SideEffects [None]

SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAndAbstract Cudd_bddIntersect Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXor Cudd_bddXnor]

Definition at line 83 of file extraBddTime.c.

88{
89 DdNode *res;
90 int Counter = 0;
91
92 do {
93 dd->reordered = 0;
94 res = cuddBddAndRecurTime(dd,f,g, &Counter, TimeOut);
95 } while (dd->reordered == 1);
96 return(res);
97
98} /* end of Extra_bddAndTime */

◆ Extra_bddBitsToCube()

DdNode * Extra_bddBitsToCube ( DdManager * dd,
int Code,
int CodeWidth,
DdNode ** pbVars,
int fMsbFirst )
extern

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

Synopsis [Computes the cube of BDD variables corresponding to bits it the bit-code]

Description [Returns a bdd composed of elementary bdds found in array BddVars[] such that the bdd vars encode the number Value of bit length CodeWidth (if fMsbFirst is 1, the most significant bit is encoded with the first bdd variable). If the variables BddVars are not specified, takes the first CodeWidth variables of the manager]

SideEffects []

SeeAlso []

Definition at line 730 of file extraBddMisc.c.

731{
732 int z;
733 DdNode * bTemp, * bVar, * bVarBdd, * bResult;
734
735 bResult = b1; Cudd_Ref( bResult );
736 for ( z = 0; z < CodeWidth; z++ )
737 {
738 bVarBdd = (pbVars)? pbVars[z]: dd->vars[z];
739 if ( fMsbFirst )
740 bVar = Cudd_NotCond( bVarBdd, (Code & (1 << (CodeWidth-1-z)))==0 );
741 else
742 bVar = Cudd_NotCond( bVarBdd, (Code & (1 << (z)))==0 );
743 bResult = Cudd_bddAnd( dd, bTemp = bResult, bVar ); Cudd_Ref( bResult );
744 Cudd_RecursiveDeref( dd, bTemp );
745 }
746 Cudd_Deref( bResult );
747
748 return bResult;
749} /* end of Extra_bddBitsToCube */
#define b1
Definition bbrImage.c:97
#define Code
Definition deflate.h:76
Here is the caller graph for this function:

◆ Extra_bddChangePolarity()

DdNode * Extra_bddChangePolarity ( DdManager * dd,
DdNode * bFunc,
DdNode * bVars )
extern

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

Synopsis [Changes the polarity of vars listed in the cube.]

Description []

SideEffects []

SeeAlso []

Definition at line 1029 of file extraBddMisc.c.

1033{
1034 DdNode *res;
1035 do {
1036 dd->reordered = 0;
1037 res = extraBddChangePolarity( dd, bFunc, bVars );
1038 } while (dd->reordered == 1);
1039 return(res);
1040
1041} /* end of Extra_bddChangePolarity */
DdNode * extraBddChangePolarity(DdManager *dd, DdNode *bFunc, DdNode *bVars)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_bddCheckUnateNaive()

int Extra_bddCheckUnateNaive ( DdManager * dd,
DdNode * bF,
int iVar )
extern

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

Synopsis [Checks if the two variables are symmetric.]

Description [Returns 0 if vars are not unate. Return -1/+1 if the var is neg/pos unate.]

SideEffects []

SeeAlso []

Definition at line 338 of file extraBddUnate.c.

342{
343 DdNode * bCof0, * bCof1;
344 int Res;
345
346 assert( iVar < dd->size );
347
348 bCof0 = Cudd_Cofactor( dd, bF, Cudd_Not(Cudd_bddIthVar(dd,iVar)) ); Cudd_Ref( bCof0 );
349 bCof1 = Cudd_Cofactor( dd, bF, Cudd_bddIthVar(dd,iVar) ); Cudd_Ref( bCof1 );
350
351 if ( Cudd_bddLeq( dd, bCof0, bCof1 ) )
352 Res = 1;
353 else if ( Cudd_bddLeq( dd, bCof1, bCof0 ) )
354 Res =-1;
355 else
356 Res = 0;
357
358 Cudd_RecursiveDeref( dd, bCof0 );
359 Cudd_RecursiveDeref( dd, bCof1 );
360 return Res;
361} /* end of Extra_bddCheckUnateNaive */
#define assert(ex)
Definition util_old.h:213
Here is the caller graph for this function:

◆ Extra_bddCheckVarsSymmetric()

int Extra_bddCheckVarsSymmetric ( DdManager * dd,
DdNode * bF,
int iVar1,
int iVar2 )
extern

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

Synopsis [Checks the possibility of two variables being symmetric.]

Description [Returns 0 if vars are not symmetric. Return 1 if vars can be symmetric.]

SideEffects []

SeeAlso []

Definition at line 360 of file extraBddSymm.c.

365{
366 DdNode * bVars;
367 int Res;
368
369// return 1;
370
371 assert( iVar1 != iVar2 );
372 assert( iVar1 < dd->size );
373 assert( iVar2 < dd->size );
374
375 bVars = Cudd_bddAnd( dd, dd->vars[iVar1], dd->vars[iVar2] ); Cudd_Ref( bVars );
376
377 Res = (int)( extraBddCheckVarsSymmetric( dd, bF, bVars ) == b1 );
378
379 Cudd_RecursiveDeref( dd, bVars );
380
381 return Res;
382} /* end of Extra_bddCheckVarsSymmetric */
DdNode * extraBddCheckVarsSymmetric(DdManager *dd, DdNode *bF, DdNode *bVars)
Here is the call graph for this function:

◆ Extra_bddCheckVarsSymmetricNaive()

int Extra_bddCheckVarsSymmetricNaive ( DdManager * dd,
DdNode * bF,
int iVar1,
int iVar2 )
extern

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

Synopsis [Checks if the two variables are symmetric.]

Description [Returns 0 if vars are not symmetric. Return 1 if vars are symmetric.]

SideEffects []

SeeAlso []

Definition at line 443 of file extraBddSymm.c.

448{
449 DdNode * bCube1, * bCube2;
450 DdNode * bCof01, * bCof10;
451 int Res;
452
453 assert( iVar1 != iVar2 );
454 assert( iVar1 < dd->size );
455 assert( iVar2 < dd->size );
456
457 bCube1 = Cudd_bddAnd( dd, Cudd_Not( dd->vars[iVar1] ), dd->vars[iVar2] ); Cudd_Ref( bCube1 );
458 bCube2 = Cudd_bddAnd( dd, Cudd_Not( dd->vars[iVar2] ), dd->vars[iVar1] ); Cudd_Ref( bCube2 );
459
460 bCof01 = Cudd_Cofactor( dd, bF, bCube1 ); Cudd_Ref( bCof01 );
461 bCof10 = Cudd_Cofactor( dd, bF, bCube2 ); Cudd_Ref( bCof10 );
462
463 Res = (int)( bCof10 == bCof01 );
464
465 Cudd_RecursiveDeref( dd, bCof01 );
466 Cudd_RecursiveDeref( dd, bCof10 );
467 Cudd_RecursiveDeref( dd, bCube1 );
468 Cudd_RecursiveDeref( dd, bCube2 );
469
470 return Res;
471} /* end of Extra_bddCheckVarsSymmetricNaive */
Here is the caller graph for this function:

◆ Extra_bddComputeCube()

DdNode * Extra_bddComputeCube ( DdManager * dd,
DdNode ** bXVars,
int nVars )
extern

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

Synopsis [Computes the positive polarty cube composed of the first vars in the array.]

Description []

SideEffects []

SeeAlso []

Definition at line 1001 of file extraBddMisc.c.

1002{
1003 DdNode * bRes;
1004 DdNode * bTemp;
1005 int i;
1006
1007 bRes = b1; Cudd_Ref( bRes );
1008 for ( i = 0; i < nVars; i++ )
1009 {
1010 bRes = Cudd_bddAnd( dd, bTemp = bRes, bXVars[i] ); Cudd_Ref( bRes );
1011 Cudd_RecursiveDeref( dd, bTemp );
1012 }
1013
1014 Cudd_Deref( bRes );
1015 return bRes;
1016}
Here is the caller graph for this function:

◆ Extra_bddComputeRangeCube()

DdNode * Extra_bddComputeRangeCube ( DdManager * dd,
int iStart,
int iStop )
extern

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

Synopsis [Performs the reordering-sensitive step of Extra_bddMove().]

Description []

SideEffects []

SeeAlso []

Definition at line 699 of file extraBddMisc.c.

700{
701 DdNode * bTemp, * bProd;
702 int i;
703 assert( iStart <= iStop );
704 assert( iStart >= 0 && iStart <= dd->size );
705 assert( iStop >= 0 && iStop <= dd->size );
706 bProd = b1; Cudd_Ref( bProd );
707 for ( i = iStart; i < iStop; i++ )
708 {
709 bProd = Cudd_bddAnd( dd, bTemp = bProd, dd->vars[i] ); Cudd_Ref( bProd );
710 Cudd_RecursiveDeref( dd, bTemp );
711 }
712 Cudd_Deref( bProd );
713 return bProd;
714}

◆ Extra_bddCountCubes()

int Extra_bddCountCubes ( DdManager * dd,
DdNode ** pFuncs,
int nFuncs,
int fMode,
int nLimit,
int * pGuide )
extern

Definition at line 1485 of file extraBddMisc.c.

1486{
1487 DdNode * pF0, * pF1;
1488 int i, Count, Count0, Count1, CounterAll = 0;
1490 unsigned int saveLimit = dd->maxLive;
1491 dd->maxLive = dd->keys - dd->dead + 1000000; // limit on intermediate BDD nodes
1492 for ( i = 0; i < nFuncs; i++ )
1493 {
1494 if ( !pFuncs[i] )
1495 continue;
1496 pF1 = pF0 = NULL;
1497 Count0 = Count1 = nLimit;
1498 if ( fMode == -1 || fMode == 1 ) // both or pos
1499 pF1 = extraBddCountCubes( dd, pFuncs[i], pFuncs[i], table, &Count1, nLimit );
1500 pFuncs[i] = Cudd_Not( pFuncs[i] );
1501 if ( fMode == -1 || fMode == 0 ) // both or neg
1502 pF0 = extraBddCountCubes( dd, pFuncs[i], pFuncs[i], table, &Count0, Count1 );
1503 pFuncs[i] = Cudd_Not( pFuncs[i] );
1504 if ( !pF1 && !pF0 )
1505 break;
1506 if ( !pF0 ) pGuide[i] = 1, Count = Count1; // use pos
1507 else if ( !pF1 ) pGuide[i] = 0, Count = Count0; // use neg
1508 else if ( Count1 <= Count0 ) pGuide[i] = 1, Count = Count1; // use pos
1509 else pGuide[i] = 0, Count = Count0; // use neg
1510 CounterAll += Count;
1511 //printf( "Output %5d has %5d cubes (%d) (%5d and %5d)\n", nOuts++, Count, pGuide[i], Count1, Count0 );
1512 }
1513 dd->maxLive = saveLimit;
1514 st__free_table( table );
1515 return i == nFuncs ? CounterAll : -1;
1516} /* end of Extra_bddCountCubes */
int st__ptrhash(const char *, int)
Definition st.c:467
int st__ptrcmp(const char *, const char *)
Definition st.c:479
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition st.c:72
void st__free_table(st__table *table)
Definition st.c:81
Definition st.h:52
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_bddCreateAnd()

DdNode * Extra_bddCreateAnd ( DdManager * dd,
int nVars )
extern

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

Synopsis [Creates AND composed of the first nVars of the manager.]

Description []

SideEffects []

SeeAlso []

Definition at line 858 of file extraBddMisc.c.

859{
860 DdNode * bFunc, * bTemp;
861 int i;
862 bFunc = Cudd_ReadOne(dd); Cudd_Ref( bFunc );
863 for ( i = 0; i < nVars; i++ )
864 {
865 bFunc = Cudd_bddAnd( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) ); Cudd_Ref( bFunc );
866 Cudd_RecursiveDeref( dd, bTemp );
867 }
868 Cudd_Deref( bFunc );
869 return bFunc;
870}
Here is the caller graph for this function:

◆ Extra_bddCreateExor()

DdNode * Extra_bddCreateExor ( DdManager * dd,
int nVars )
extern

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

Synopsis [Creates EXOR composed of the first nVars of the manager.]

Description []

SideEffects []

SeeAlso []

Definition at line 908 of file extraBddMisc.c.

909{
910 DdNode * bFunc, * bTemp;
911 int i;
912 bFunc = Cudd_ReadLogicZero(dd); Cudd_Ref( bFunc );
913 for ( i = 0; i < nVars; i++ )
914 {
915 bFunc = Cudd_bddXor( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) ); Cudd_Ref( bFunc );
916 Cudd_RecursiveDeref( dd, bTemp );
917 }
918 Cudd_Deref( bFunc );
919 return bFunc;
920}
Here is the caller graph for this function:

◆ Extra_bddCreateOr()

DdNode * Extra_bddCreateOr ( DdManager * dd,
int nVars )
extern

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

Synopsis [Creates OR composed of the first nVars of the manager.]

Description []

SideEffects []

SeeAlso []

Definition at line 883 of file extraBddMisc.c.

884{
885 DdNode * bFunc, * bTemp;
886 int i;
887 bFunc = Cudd_ReadLogicZero(dd); Cudd_Ref( bFunc );
888 for ( i = 0; i < nVars; i++ )
889 {
890 bFunc = Cudd_bddOr( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) ); Cudd_Ref( bFunc );
891 Cudd_RecursiveDeref( dd, bTemp );
892 }
893 Cudd_Deref( bFunc );
894 return bFunc;
895}
Here is the caller graph for this function:

◆ Extra_bddEncodingBinary()

DdNode * Extra_bddEncodingBinary ( DdManager * dd,
DdNode ** pbFuncs,
int nFuncs,
DdNode ** pbVars,
int nVars )
extern

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

Synopsis [Performs the binary encoding of the set of function using the given vars.]

Description [Performs a straight binary encoding of the set of functions using the variable cubes formed from the given set of variables. ]

SideEffects []

SeeAlso []

Definition at line 138 of file extraBddCas.c.

144{
145 int i;
146 DdNode * bResult;
147 DdNode * bCube, * bTemp, * bProd;
148
149 assert( nVars >= Abc_Base2Log(nFuncs) );
150
151 bResult = b0; Cudd_Ref( bResult );
152 for ( i = 0; i < nFuncs; i++ )
153 {
154 bCube = Extra_bddBitsToCube( dd, i, nVars, pbVars, 1 ); Cudd_Ref( bCube );
155 bProd = Cudd_bddAnd( dd, bCube, pbFuncs[i] ); Cudd_Ref( bProd );
156 Cudd_RecursiveDeref( dd, bCube );
157
158 bResult = Cudd_bddOr( dd, bProd, bTemp = bResult ); Cudd_Ref( bResult );
159 Cudd_RecursiveDeref( dd, bTemp );
160 Cudd_RecursiveDeref( dd, bProd );
161 }
162
163 Cudd_Deref( bResult );
164 return bResult;
165} /* end of Extra_bddEncodingBinary */
#define b0
Definition bbrImage.c:96
DdNode * Extra_bddBitsToCube(DdManager *dd, int Code, int CodeWidth, DdNode **pbVars, int fMsbFirst)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_bddEncodingNonStrict()

DdNode * Extra_bddEncodingNonStrict ( DdManager * dd,
DdNode ** pbColumns,
int nColumns,
DdNode * bVarsCol,
DdNode ** pCVars,
int nMulti,
int * pSimple )
extern

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

Synopsis [Solves the column encoding problem using a sophisticated method.]

Description [The encoding is based on the idea of deriving functions which depend on only one variable, which corresponds to the case of non-disjoint decompostion. It is assumed that the variables pCVars are ordered below the variables representing the solumns, and the first variable pCVars[0] is the topmost one.]

SideEffects []

SeeAlso [Extra_bddEncodingBinary]

Definition at line 184 of file extraBddCas.c.

192{
193 DdNode * bEncoded, * bResult;
194 int nVarsCol = Cudd_SupportSize(dd,bVarsCol);
195 abctime clk;
196
197 // cannot work with more that 32-bit codes
198 assert( nMulti < 32 );
199
200 // perform the preliminary encoding using the straight binary code
201 bEncoded = Extra_bddEncodingBinary( dd, pbColumns, nColumns, pCVars, nMulti ); Cudd_Ref( bEncoded );
202 //printf( "Node count = %d", Cudd_DagSize(bEncoded) );
203
204 // set the backgroup value for counting minterms
205 s_Terminal = b0;
206 // set the level of the encoding variables
207 s_EncodingVarsLevel = dd->invperm[pCVars[0]->index];
208
209 // the current number of backtracks
210 s_BackTracks = 0;
211 // the variables that are cofactored on the topmost level where everything starts (no vars)
212 s_Field[0][0] = b1;
213 // the size of the best set of "simple" encoding variables found so far
214 s_nVarsBest = 0;
215
216 // set the relation to be accessible to traversal procedures
217 s_Encoded = bEncoded;
218 // the set of all vars to be accessible to traversal procedures
219 s_VarAll = bVarsCol;
220 // the column multiplicity
221 s_MultiStart = nMulti;
222
223
224 clk = Abc_Clock();
225 // find the simplest encoding
226 if ( nColumns > 2 )
227 EvaluateEncodings_rec( dd, bVarsCol, nVarsCol, nMulti, 1 );
228// printf( "The number of backtracks = %d\n", s_BackTracks );
229// s_EncSearchTime += Abc_Clock() - clk;
230
231 // allocate the temporary storage for the columns
232 s_pbTemp = (DdNode **)ABC_ALLOC( char, nColumns * sizeof(DdNode *) );
233
234// clk = Abc_Clock();
235 bResult = CreateTheCodes_rec( dd, bEncoded, 0, pCVars ); Cudd_Ref( bResult );
236// s_EncComputeTime += Abc_Clock() - clk;
237
238 // delocate the preliminarily encoded set
239 Cudd_RecursiveDeref( dd, bEncoded );
240// Cudd_RecursiveDeref( dd, aEncoded );
241
242 ABC_FREE( s_pbTemp );
243
244 *pSimple = s_nVarsBest;
245 Cudd_Deref( bResult );
246 return bResult;
247}
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_ALLOC(type, num)
Definition abc_global.h:264
#define ABC_FREE(obj)
Definition abc_global.h:267
DdNode * Extra_bddEncodingBinary(DdManager *dd, DdNode **pbFuncs, int nFuncs, DdNode **pbVars, int nVars)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_bddFindOneCube()

DdNode * Extra_bddFindOneCube ( DdManager * dd,
DdNode * bF )
extern

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

Synopsis [Find any cube belonging to the on-set of the function.]

Description []

SideEffects []

SeeAlso []

Definition at line 605 of file extraBddMisc.c.

606{
607 char * s_Temp;
608 DdNode * bCube, * bTemp;
609 int v;
610
611 // get the vector of variables in the cube
612 s_Temp = ABC_ALLOC( char, dd->size );
613 Cudd_bddPickOneCube( dd, bF, s_Temp );
614
615 // start the cube
616 bCube = b1; Cudd_Ref( bCube );
617 for ( v = 0; v < dd->size; v++ )
618 if ( s_Temp[v] == 0 )
619 {
620// Cube &= !s_XVars[v];
621 bCube = Cudd_bddAnd( dd, bTemp = bCube, Cudd_Not(dd->vars[v]) ); Cudd_Ref( bCube );
622 Cudd_RecursiveDeref( dd, bTemp );
623 }
624 else if ( s_Temp[v] == 1 )
625 {
626// Cube &= s_XVars[v];
627 bCube = Cudd_bddAnd( dd, bTemp = bCube, dd->vars[v] ); Cudd_Ref( bCube );
628 Cudd_RecursiveDeref( dd, bTemp );
629 }
630 Cudd_Deref(bCube);
631 ABC_FREE( s_Temp );
632 return bCube;
633}
Here is the caller graph for this function:

◆ Extra_bddGetOneCube()

DdNode * Extra_bddGetOneCube ( DdManager * dd,
DdNode * bFunc )
extern

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

Synopsis [Returns one cube contained in the given BDD.]

Description [This function returns the cube with the smallest bits-to-integer value.]

SideEffects []

Definition at line 645 of file extraBddMisc.c.

646{
647 DdNode * bFuncR, * bFunc0, * bFunc1;
648 DdNode * bRes0, * bRes1, * bRes;
649
650 bFuncR = Cudd_Regular(bFunc);
651 if ( cuddIsConstant(bFuncR) )
652 return bFunc;
653
654 // cofactor
655 if ( Cudd_IsComplement(bFunc) )
656 {
657 bFunc0 = Cudd_Not( cuddE(bFuncR) );
658 bFunc1 = Cudd_Not( cuddT(bFuncR) );
659 }
660 else
661 {
662 bFunc0 = cuddE(bFuncR);
663 bFunc1 = cuddT(bFuncR);
664 }
665
666 // try to find the cube with the negative literal
667 bRes0 = Extra_bddGetOneCube( dd, bFunc0 ); Cudd_Ref( bRes0 );
668
669 if ( bRes0 != b0 )
670 {
671 bRes = Cudd_bddAnd( dd, bRes0, Cudd_Not(dd->vars[bFuncR->index]) ); Cudd_Ref( bRes );
672 Cudd_RecursiveDeref( dd, bRes0 );
673 }
674 else
675 {
676 Cudd_RecursiveDeref( dd, bRes0 );
677 // try to find the cube with the positive literal
678 bRes1 = Extra_bddGetOneCube( dd, bFunc1 ); Cudd_Ref( bRes1 );
679 assert( bRes1 != b0 );
680 bRes = Cudd_bddAnd( dd, bRes1, dd->vars[bFuncR->index] ); Cudd_Ref( bRes );
681 Cudd_RecursiveDeref( dd, bRes1 );
682 }
683
684 Cudd_Deref( bRes );
685 return bRes;
686}
DdNode * Extra_bddGetOneCube(DdManager *dd, DdNode *bFunc)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_bddImageCompute()

DdNode * Extra_bddImageCompute ( Extra_ImageTree_t * pTree,
DdNode * bCare )
extern

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

Synopsis [Compute the image.]

Description []

SideEffects []

SeeAlso []

Definition at line 220 of file extraBddImage.c.

221{
222 DdManager * dd = pTree->pCare->dd;
223 DdNode * bSupp, * bRem;
224
225 pTree->nIter++;
226
227 // make sure the supports are okay
228 bSupp = Cudd_Support( dd, bCare ); Cudd_Ref( bSupp );
229 if ( bSupp != pTree->bCareSupp )
230 {
231 bRem = Cudd_bddExistAbstract( dd, bSupp, pTree->bCareSupp ); Cudd_Ref( bRem );
232 if ( bRem != b1 )
233 {
234printf( "Original care set support: " );
235ABC_PRB( dd, pTree->bCareSupp );
236printf( "Current care set support: " );
237ABC_PRB( dd, bSupp );
238 Cudd_RecursiveDeref( dd, bSupp );
239 Cudd_RecursiveDeref( dd, bRem );
240 printf( "The care set depends on some vars that were not in the care set during scheduling.\n" );
241 return NULL;
242 }
243 Cudd_RecursiveDeref( dd, bRem );
244 }
245 Cudd_RecursiveDeref( dd, bSupp );
246
247 // remove the previous image
248 Cudd_RecursiveDeref( dd, pTree->pCare->bImage );
249 pTree->pCare->bImage = bCare; Cudd_Ref( bCare );
250
251 // compute the image
252 pTree->nNodesMax = 0;
253 Extra_bddImageCompute_rec( pTree, pTree->pRoot );
254 if ( pTree->nNodesMaxT < pTree->nNodesMax )
255 pTree->nNodesMaxT = pTree->nNodesMax;
256
257// if ( pTree->fVerbose )
258// printf( "Iter %2d : Max nodes = %5d.\n", pTree->nIter, pTree->nNodesMax );
259 return pTree->pRoot->bImage;
260}
#define ABC_PRB(dd, f)
Definition bbrImage.c:100
Extra_ImageNode_t * pCare
Extra_ImageNode_t * pRoot

◆ Extra_bddImageCompute2()

DdNode * Extra_bddImageCompute2 ( Extra_ImageTree2_t * pTree,
DdNode * bCare )
extern

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 1108 of file extraBddImage.c.

1109{
1110 if ( pTree->bImage )
1111 Cudd_RecursiveDeref( pTree->dd, pTree->bImage );
1112 pTree->bImage = Cudd_bddAndAbstract( pTree->dd, pTree->bRel, bCare, pTree->bCube );
1113 Cudd_Ref( pTree->bImage );
1114 return pTree->bImage;
1115}
Here is the caller graph for this function:

◆ Extra_bddImageRead()

DdNode * Extra_bddImageRead ( Extra_ImageTree_t * pTree)
extern

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

Synopsis [Reads the image from the tree.]

Description []

SideEffects []

SeeAlso []

Definition at line 292 of file extraBddImage.c.

293{
294 return pTree->pRoot->bImage;
295}

◆ Extra_bddImageRead2()

DdNode * Extra_bddImageRead2 ( Extra_ImageTree2_t * pTree)
extern

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

Synopsis [Returns the previously computed image.]

Description []

SideEffects []

SeeAlso []

Definition at line 1150 of file extraBddImage.c.

1151{
1152 return pTree->bImage;
1153}

◆ Extra_bddImageStart()

Extra_ImageTree_t * Extra_bddImageStart ( DdManager * dd,
DdNode * bCare,
int nParts,
DdNode ** pbParts,
int nVars,
DdNode ** pbVars,
int fVerbose )
extern

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

Synopsis [Starts the image computation using tree-based scheduling.]

Description [This procedure starts the image computation. It uses the given care set to test-run the image computation and creates the quantification tree by scheduling variable quantifications. The tree can be used to compute images for other care sets without rescheduling. In this case, Extra_bddImageCompute() should be called.]

SideEffects []

SeeAlso []

Definition at line 156 of file extraBddImage.c.

160{
161 Extra_ImageTree_t * pTree;
162 Extra_ImagePart_t ** pParts;
163 Extra_ImageVar_t ** pVars;
164 Extra_ImageNode_t ** pNodes;
165 int v;
166
167 if ( fVerbose && dd->size <= 80 )
168 Extra_bddImagePrintLatchDependency( dd, bCare, nParts, pbParts, nVars, pbVars );
169
170 // create variables, partitions and leaf nodes
171 pParts = Extra_CreateParts( dd, nParts, pbParts, bCare );
172 pVars = Extra_CreateVars( dd, nParts + 1, pParts, nVars, pbVars );
173 pNodes = Extra_CreateNodes( dd, nParts + 1, pParts, dd->size, pVars );
174
175 // create the tree
176 pTree = ABC_ALLOC( Extra_ImageTree_t, 1 );
177 memset( pTree, 0, sizeof(Extra_ImageTree_t) );
178 pTree->pCare = pNodes[nParts];
179 pTree->fVerbose = fVerbose;
180
181 // process the nodes
182 while ( Extra_BuildTreeNode( dd, nParts + 1, pNodes, dd->size, pVars ) );
183
184 // make sure the variables are gone
185 for ( v = 0; v < dd->size; v++ )
186 assert( pVars[v] == NULL );
187 ABC_FREE( pVars );
188
189 // merge the topmost nodes
190 while ( (pTree->pRoot = Extra_MergeTopNodes( dd, nParts + 1, pNodes )) == NULL );
191
192 // make sure the nodes are gone
193 for ( v = 0; v < nParts + 1; v++ )
194 assert( pNodes[v] == NULL );
195 ABC_FREE( pNodes );
196
197// if ( fVerbose )
198// Extra_bddImagePrintTree( pTree );
199
200 // set the support of the care set
201 pTree->bCareSupp = Cudd_Support( dd, bCare ); Cudd_Ref( pTree->bCareSupp );
202
203 // clean the partitions
204 Extra_DeleteParts_rec( pTree->pRoot );
205 ABC_FREE( pParts );
206 return pTree;
207}
struct Extra_ImageVar_t_ Extra_ImageVar_t
typedefABC_NAMESPACE_IMPL_START struct Extra_ImageNode_t_ Extra_ImageNode_t
struct Extra_ImagePart_t_ Extra_ImagePart_t
struct Extra_ImageTree_t_ Extra_ImageTree_t
Definition extraBdd.h:146
char * memset()
Here is the call graph for this function:

◆ Extra_bddImageStart2()

Extra_ImageTree2_t * Extra_bddImageStart2 ( DdManager * dd,
DdNode * bCare,
int nParts,
DdNode ** pbParts,
int nVars,
DdNode ** pbVars,
int fVerbose )
extern

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

Synopsis [Starts the monolithic image computation.]

Description []

SideEffects []

SeeAlso []

Definition at line 1066 of file extraBddImage.c.

1070{
1071 Extra_ImageTree2_t * pTree;
1072 DdNode * bCubeAll, * bCubeNot, * bTemp;
1073 int i;
1074
1075 pTree = ABC_ALLOC( Extra_ImageTree2_t, 1 );
1076 pTree->dd = dd;
1077 pTree->bImage = NULL;
1078
1079 bCubeAll = Extra_bddComputeCube( dd, dd->vars, dd->size ); Cudd_Ref( bCubeAll );
1080 bCubeNot = Extra_bddComputeCube( dd, pbVars, nVars ); Cudd_Ref( bCubeNot );
1081 pTree->bCube = Cudd_bddExistAbstract( dd, bCubeAll, bCubeNot ); Cudd_Ref( pTree->bCube );
1082 Cudd_RecursiveDeref( dd, bCubeAll );
1083 Cudd_RecursiveDeref( dd, bCubeNot );
1084
1085 // derive the monolithic relation
1086 pTree->bRel = b1; Cudd_Ref( pTree->bRel );
1087 for ( i = 0; i < nParts; i++ )
1088 {
1089 pTree->bRel = Cudd_bddAnd( dd, bTemp = pTree->bRel, pbParts[i] ); Cudd_Ref( pTree->bRel );
1090 Cudd_RecursiveDeref( dd, bTemp );
1091 }
1092 Extra_bddImageCompute2( pTree, bCare );
1093 return pTree;
1094}
DdNode * Extra_bddImageCompute2(Extra_ImageTree2_t *pTree, DdNode *bCare)
DdNode * Extra_bddComputeCube(DdManager *dd, DdNode **bXVars, int nVars)
struct Extra_ImageTree2_t_ Extra_ImageTree2_t
Definition extraBdd.h:155
Here is the call graph for this function:

◆ Extra_bddImageTreeDelete()

void Extra_bddImageTreeDelete ( Extra_ImageTree_t * pTree)
extern

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

Synopsis [Delete the tree.]

Description []

SideEffects []

SeeAlso []

Definition at line 273 of file extraBddImage.c.

274{
275 if ( pTree->bCareSupp )
276 Cudd_RecursiveDeref( pTree->pRoot->dd, pTree->bCareSupp );
277 Extra_bddImageTreeDelete_rec( pTree->pRoot );
278 ABC_FREE( pTree );
279}

◆ Extra_bddImageTreeDelete2()

void Extra_bddImageTreeDelete2 ( Extra_ImageTree2_t * pTree)
extern

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 1128 of file extraBddImage.c.

1129{
1130 if ( pTree->bRel )
1131 Cudd_RecursiveDeref( pTree->dd, pTree->bRel );
1132 if ( pTree->bCube )
1133 Cudd_RecursiveDeref( pTree->dd, pTree->bCube );
1134 if ( pTree->bImage )
1135 Cudd_RecursiveDeref( pTree->dd, pTree->bImage );
1136 ABC_FREE( pTree );
1137}

◆ Extra_bddIsVar()

int Extra_bddIsVar ( DdNode * bFunc)
extern

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

Synopsis [Returns 1 if the BDD is the BDD of elementary variable.]

Description []

SideEffects []

SeeAlso []

Definition at line 839 of file extraBddMisc.c.

840{
841 bFunc = Cudd_Regular( bFunc );
842 if ( cuddIsConstant(bFunc) )
843 return 0;
844 return cuddIsConstant( cuddT(bFunc) ) && cuddIsConstant( Cudd_Regular(cuddE(bFunc)) );
845}

◆ Extra_bddMove()

DdNode * Extra_bddMove ( DdManager * dd,
DdNode * bF,
int nVars )
extern

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

Synopsis [Moves the BDD by the given number of variables up or down.]

Description []

SideEffects []

SeeAlso [Extra_bddShift]

Definition at line 187 of file extraBddMisc.c.

191{
192 DdNode * res;
193 DdNode * bVars;
194 if ( nVars == 0 )
195 return bF;
196 if ( Cudd_IsConstant(bF) )
197 return bF;
198 assert( nVars <= dd->size );
199 if ( nVars > 0 )
200 bVars = dd->vars[nVars];
201 else
202 bVars = Cudd_Not(dd->vars[-nVars]);
203
204 do {
205 dd->reordered = 0;
206 res = extraBddMove( dd, bF, bVars );
207 } while (dd->reordered == 1);
208 return(res);
209
210} /* end of Extra_bddMove */
DdNode * extraBddMove(DdManager *dd, DdNode *bF, DdNode *bDist)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_bddNodePathsUnderCut()

st__table * Extra_bddNodePathsUnderCut ( DdManager * dd,
DdNode * bFunc,
int CutLevel )
extern

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

Synopsis [Collects the nodes under the cut and, for each node, computes the sum of paths leading to it from the root.]

Description [The table returned contains the set of BDD nodes pointed to under the cut and, for each node, the BDD of the sum of paths leading to this node from the root The sums of paths in the table are referenced. CutLevel is the first DD level considered to be under the cut.]

SideEffects []

SeeAlso [Extra_bddNodePaths]

Definition at line 263 of file extraBddCas.c.

264{
265 st__table * Visited; // temporary table to remember the visited nodes
266 st__table * CutNodes; // the result goes here
267 st__table * Result; // the result goes here
268 DdNode * aFunc;
269
270 s_CutLevel = CutLevel;
271
273 // the terminal cases
274 if ( Cudd_IsConstant( bFunc ) )
275 {
276 if ( bFunc == b1 )
277 {
278 st__insert( Result, (char*)b1, (char*)b1 );
279 Cudd_Ref( b1 );
280 Cudd_Ref( b1 );
281 }
282 else
283 {
284 st__insert( Result, (char*)b0, (char*)b0 );
285 Cudd_Ref( b0 );
286 Cudd_Ref( b0 );
287 }
288 return Result;
289 }
290
291 // create the ADD to simplify processing (no complemented edges)
292 aFunc = Cudd_BddToAdd( dd, bFunc ); Cudd_Ref( aFunc );
293
294 // Step 1: Start the tables and collect information about the nodes above the cut
295 // this information tells how many edges point to each node
298
299 CountNodeVisits_rec( dd, aFunc, Visited );
300
301 // Step 2: Traverse the BDD using the visited table and compute the sum of paths
302 CollectNodesAndComputePaths_rec( dd, aFunc, b1, Visited, CutNodes );
303
304 // at this point the table of cut nodes is ready and the table of visited is useless
305 {
306 st__generator * gen;
307 DdNode * aNode;
308 traventry * p;
309 st__foreach_item( Visited, gen, (const char**)&aNode, (char**)&p )
310 {
311 Cudd_RecursiveDeref( dd, p->bSum );
312 ABC_FREE( p );
313 }
314 st__free_table( Visited );
315 }
316
317 // go through the table CutNodes and create the BDD and the path to be returned
318 {
319 st__generator * gen;
320 DdNode * aNode, * bNode, * bSum;
321 st__foreach_item( CutNodes, gen, (const char**)&aNode, (char**)&bSum)
322 {
323 // aNode is not referenced, because aFunc is holding it
324 bNode = Cudd_addBddPattern( dd, aNode ); Cudd_Ref( bNode );
325 st__insert( Result, (char*)bNode, (char*)bSum );
326 // the new table takes both refs
327 }
328 st__free_table( CutNodes );
329 }
330
331 // dereference the ADD
332 Cudd_RecursiveDeref( dd, aFunc );
333
334 // return the table
335 return Result;
336
337} /* end of Extra_bddNodePathsUnderCut */
Cube * p
Definition exorList.c:222
int st__insert(st__table *table, const char *key, char *value)
Definition st.c:171
#define st__foreach_item(table, gen, key, value)
Definition st.h:107
Here is the call graph for this function:

◆ Extra_bddNodePathsUnderCutArray()

int Extra_bddNodePathsUnderCutArray ( DdManager * dd,
DdNode ** paNodes,
DdNode ** pbCubes,
int nNodes,
DdNode ** paNodesRes,
DdNode ** pbCubesRes,
int CutLevel )
extern

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

Synopsis [Collects the nodes under the cut in the ADD starting from the given set of ADD nodes.]

Description [Takes the array, paNodes, of ADD nodes to start the traversal, the array, pbCubes, of BDD cubes to start the traversal with in each node, and the number, nNodes, of ADD nodes and BDD cubes in paNodes and pbCubes. Returns the number of columns found. Fills in paNodesRes (pbCubesRes) with the set of ADD columns (BDD paths). These arrays should be allocated by the user.]

SideEffects []

SeeAlso [Extra_bddNodePaths]

Definition at line 355 of file extraBddCas.c.

356{
357 st__table * Visited; // temporary table to remember the visited nodes
358 st__table * CutNodes; // the nodes under the cut go here
359 int i, Counter;
360
361 s_CutLevel = CutLevel;
362
363 // there should be some nodes
364 assert( nNodes > 0 );
365 if ( nNodes == 1 && Cudd_IsConstant( paNodes[0] ) )
366 {
367 if ( paNodes[0] == a1 )
368 {
369 paNodesRes[0] = a1; Cudd_Ref( a1 );
370 pbCubesRes[0] = pbCubes[0]; Cudd_Ref( pbCubes[0] );
371 }
372 else
373 {
374 paNodesRes[0] = a0; Cudd_Ref( a0 );
375 pbCubesRes[0] = pbCubes[0]; Cudd_Ref( pbCubes[0] );
376 }
377 return 1;
378 }
379
380 // Step 1: Start the table and collect information about the nodes above the cut
381 // this information tells how many edges point to each node
384
385 for ( i = 0; i < nNodes; i++ )
386 CountNodeVisits_rec( dd, paNodes[i], Visited );
387
388 // Step 2: Traverse the BDD using the visited table and compute the sum of paths
389 for ( i = 0; i < nNodes; i++ )
390 CollectNodesAndComputePaths_rec( dd, paNodes[i], pbCubes[i], Visited, CutNodes );
391
392 // at this point, the table of cut nodes is ready and the table of visited is useless
393 {
394 st__generator * gen;
395 DdNode * aNode;
396 traventry * p;
397 st__foreach_item( Visited, gen, (const char**)&aNode, (char**)&p )
398 {
399 Cudd_RecursiveDeref( dd, p->bSum );
400 ABC_FREE( p );
401 }
402 st__free_table( Visited );
403 }
404
405 // go through the table CutNodes and create the BDD and the path to be returned
406 {
407 st__generator * gen;
408 DdNode * aNode, * bSum;
409 Counter = 0;
410 st__foreach_item( CutNodes, gen, (const char**)&aNode, (char**)&bSum)
411 {
412 paNodesRes[Counter] = aNode; Cudd_Ref( aNode );
413 pbCubesRes[Counter] = bSum;
414 Counter++;
415 }
416 st__free_table( CutNodes );
417 }
418
419 // return the number of cofactors found
420 return Counter;
421
422} /* end of Extra_bddNodePathsUnderCutArray */
#define a0
Definition extraBdd.h:79
#define a1
Definition extraBdd.h:80
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_bddPermuteArray()

void Extra_bddPermuteArray ( DdManager * manager,
DdNode ** bNodesIn,
DdNode ** bNodesOut,
int nNodes,
int * permut )
extern

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

Synopsis [Permutes the variables of the array of BDDs.]

Description [Given a permutation in array permut, creates a new BDD with permuted variables. There should be an entry in array permut for each variable in the manager. The i-th entry of permut holds the index of the variable that is to substitute the i-th variable. The DDs in the resulting array are already referenced.]

SideEffects [None]

SeeAlso [Cudd_addPermute Cudd_bddSwapVariables]

Definition at line 961 of file extraBddMisc.c.

962{
963 DdHashTable *table;
964 int i, k;
965 do
966 {
967 manager->reordered = 0;
968 table = cuddHashTableInit( manager, 1, 2 );
969
970 /* permute the output functions one-by-one */
971 for ( i = 0; i < nNodes; i++ )
972 {
973 bNodesOut[i] = cuddBddPermuteRecur( manager, table, bNodesIn[i], permut );
974 if ( bNodesOut[i] == NULL )
975 {
976 /* deref the array of the already computed outputs */
977 for ( k = 0; k < i; k++ )
978 Cudd_RecursiveDeref( manager, bNodesOut[k] );
979 break;
980 }
981 cuddRef( bNodesOut[i] );
982 }
983 /* Dispose of local cache. */
984 cuddHashTableQuit( table );
985 }
986 while ( manager->reordered == 1 );
987} /* end of Extra_bddPermuteArray */
Here is the caller graph for this function:

◆ Extra_bddPrint()

void Extra_bddPrint ( DdManager * dd,
DdNode * F )
extern

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

Synopsis [Outputs the BDD in a readable format.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 246 of file extraBddMisc.c.

247{
248 DdGen * Gen;
249 int * Cube;
250 CUDD_VALUE_TYPE Value;
251 int nVars = dd->size;
252 int fFirstCube = 1;
253 int i;
254
255 if ( F == NULL )
256 {
257 printf("NULL");
258 return;
259 }
260 if ( F == b0 )
261 {
262 printf("Constant 0");
263 return;
264 }
265 if ( F == b1 )
266 {
267 printf("Constant 1");
268 return;
269 }
270
271 Cudd_ForeachCube( dd, F, Gen, Cube, Value )
272 {
273 if ( fFirstCube )
274 fFirstCube = 0;
275 else
276// Output << " + ";
277 printf( " + " );
278
279 for ( i = 0; i < nVars; i++ )
280 if ( Cube[i] == 0 )
281 printf( "[%d]'", i );
282// printf( "%c'", (char)('a'+i) );
283 else if ( Cube[i] == 1 )
284 printf( "[%d]", i );
285// printf( "%c", (char)('a'+i) );
286 }
287
288// printf("\n");
289}
struct cube Cube
Here is the caller graph for this function:

◆ Extra_bddPrintSupport()

void Extra_bddPrintSupport ( DdManager * dd,
DdNode * F )
extern

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

Synopsis [Outputs the BDD in a readable format.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 302 of file extraBddMisc.c.

303{
304 DdNode * bSupp;
305 bSupp = Cudd_Support( dd, F ); Cudd_Ref( bSupp );
306 Extra_bddPrint( dd, bSupp );
307 Cudd_RecursiveDeref( dd, bSupp );
308}
void Extra_bddPrint(DdManager *dd, DdNode *F)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_bddReduceVarSet()

DdNode * Extra_bddReduceVarSet ( DdManager * dd,
DdNode * bVars,
DdNode * bF )
extern

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

Synopsis [Filters the set of variables using the support of the function.]

Description []

SideEffects []

SeeAlso []

Definition at line 181 of file extraBddSymm.c.

185{
186 DdNode * res;
187 do {
188 dd->reordered = 0;
189 res = extraBddReduceVarSet( dd, bVars, bF );
190 } while (dd->reordered == 1);
191 return(res);
192
193} /* end of Extra_bddReduceVarSet */
DdNode * extraBddReduceVarSet(DdManager *dd, DdNode *bVars, DdNode *bF)
Here is the call graph for this function:

◆ Extra_bddRemapUp()

DdNode * Extra_bddRemapUp ( DdManager * dd,
DdNode * bF )
extern

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

Synopsis [Remaps the function to depend on the topmost variables on the manager.]

Description []

SideEffects []

SeeAlso []

Definition at line 145 of file extraBddMisc.c.

148{
149 int * pPermute;
150 DdNode * bSupp, * bTemp, * bRes;
151 int Counter;
152
153 pPermute = ABC_ALLOC( int, dd->size );
154
155 // get support
156 bSupp = Cudd_Support( dd, bF ); Cudd_Ref( bSupp );
157
158 // create the variable map
159 // to remap the DD into the upper part of the manager
160 Counter = 0;
161 for ( bTemp = bSupp; bTemp != dd->one; bTemp = cuddT(bTemp) )
162 pPermute[bTemp->index] = dd->invperm[Counter++];
163
164 // transfer the BDD and remap it
165 bRes = Cudd_bddPermute( dd, bF, pPermute ); Cudd_Ref( bRes );
166
167 // remove support
168 Cudd_RecursiveDeref( dd, bSupp );
169
170 // return
171 Cudd_Deref( bRes );
172 ABC_FREE( pPermute );
173 return bRes;
174}
Here is the caller graph for this function:

◆ Extra_bddSpaceCanonVars()

DdNode * Extra_bddSpaceCanonVars ( DdManager * dd,
DdNode * bSpace )
extern

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 316 of file extraBddAuto.c.

317{
318 DdNode * bRes;
319 do {
320 dd->reordered = 0;
321 bRes = extraBddSpaceCanonVars( dd, bSpace );
322 } while (dd->reordered == 1);
323 return bRes;
324}
DdNode * extraBddSpaceCanonVars(DdManager *dd, DdNode *bF)
Here is the call graph for this function:

◆ Extra_bddSpaceEquations()

DdNode * Extra_bddSpaceEquations ( DdManager * dd,
DdNode * bSpace )
extern

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 361 of file extraBddAuto.c.

362{
363 DdNode * zRes;
364 DdNode * zEquPos;
365 DdNode * zEquNeg;
366 zEquPos = Extra_bddSpaceEquationsPos( dd, bSpace ); Cudd_Ref( zEquPos );
367 zEquNeg = Extra_bddSpaceEquationsNeg( dd, bSpace ); Cudd_Ref( zEquNeg );
368 zRes = Cudd_zddUnion( dd, zEquPos, zEquNeg ); Cudd_Ref( zRes );
369 Cudd_RecursiveDerefZdd( dd, zEquPos );
370 Cudd_RecursiveDerefZdd( dd, zEquNeg );
371 Cudd_Deref( zRes );
372 return zRes;
373}
DdNode * Extra_bddSpaceEquationsPos(DdManager *dd, DdNode *bSpace)
DdNode * Extra_bddSpaceEquationsNeg(DdManager *dd, DdNode *bSpace)
Here is the call graph for this function:

◆ Extra_bddSpaceEquationsNeg()

DdNode * Extra_bddSpaceEquationsNeg ( DdManager * dd,
DdNode * bSpace )
extern

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 409 of file extraBddAuto.c.

410{
411 DdNode * zRes;
412 do {
413 dd->reordered = 0;
414 zRes = extraBddSpaceEquationsNeg( dd, bSpace );
415 } while (dd->reordered == 1);
416 return zRes;
417}
DdNode * extraBddSpaceEquationsNeg(DdManager *dd, DdNode *bF)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_bddSpaceEquationsPos()

DdNode * Extra_bddSpaceEquationsPos ( DdManager * dd,
DdNode * bSpace )
extern

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 387 of file extraBddAuto.c.

388{
389 DdNode * zRes;
390 do {
391 dd->reordered = 0;
392 zRes = extraBddSpaceEquationsPos( dd, bSpace );
393 } while (dd->reordered == 1);
394 return zRes;
395}
DdNode * extraBddSpaceEquationsPos(DdManager *dd, DdNode *bF)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_bddSpaceExorGates()

DdNode ** Extra_bddSpaceExorGates ( DdManager * dd,
DdNode * bFuncRed,
DdNode * zEquations )
extern

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

Synopsis []

Description [Returns the array of ZDDs with the number equal to the number of vars in the DD manager. If the given var is non-canonical, this array contains the referenced ZDD representing literals in the corresponding EXOR equation.]

SideEffects []

SeeAlso []

Definition at line 497 of file extraBddAuto.c.

498{
499 DdNode ** pzRes;
500 int * pVarsNonCan;
501 DdNode * zEquRem;
502 int iVarNonCan;
503 DdNode * zExor, * zTemp;
504
505 // get the set of non-canonical variables
506 pVarsNonCan = ABC_ALLOC( int, ddMax(dd->size,dd->sizeZ) );
507 Extra_SupportArray( dd, bFuncRed, pVarsNonCan );
508
509 // allocate storage for the EXOR sets
510 pzRes = ABC_ALLOC( DdNode *, dd->size );
511 memset( pzRes, 0, sizeof(DdNode *) * dd->size );
512
513 // go through all the equations
514 zEquRem = zEquations; Cudd_Ref( zEquRem );
515 while ( zEquRem != z0 )
516 {
517 // extract one product
518 zExor = Extra_zddSelectOneSubset( dd, zEquRem ); Cudd_Ref( zExor );
519 // remove it from the set
520 zEquRem = Cudd_zddDiff( dd, zTemp = zEquRem, zExor ); Cudd_Ref( zEquRem );
521 Cudd_RecursiveDerefZdd( dd, zTemp );
522
523 // locate the non-canonical variable
524 iVarNonCan = -1;
525 for ( zTemp = zExor; zTemp != z1; zTemp = cuddT(zTemp) )
526 {
527 if ( pVarsNonCan[zTemp->index/2] == 1 )
528 {
529 assert( iVarNonCan == -1 );
530 iVarNonCan = zTemp->index/2;
531 }
532 }
533 assert( iVarNonCan != -1 );
534
535 if ( Extra_zddLitCountComb( dd, zExor ) > 1 )
536 pzRes[ iVarNonCan ] = zExor; // takes ref
537 else
538 Cudd_RecursiveDerefZdd( dd, zExor );
539 }
540 Cudd_RecursiveDerefZdd( dd, zEquRem );
541
542 ABC_FREE( pVarsNonCan );
543 return pzRes;
544}
int Extra_zddLitCountComb(DdManager *dd, DdNode *zComb)
#define z0
Definition extraBdd.h:77
#define z1
Definition extraBdd.h:78
DdNode * Extra_zddSelectOneSubset(DdManager *dd, DdNode *zS)
int * Extra_SupportArray(DdManager *dd, DdNode *F, int *support)
Here is the call graph for this function:

◆ Extra_bddSpaceFromFunction()

DdNode * Extra_bddSpaceFromFunction ( DdManager * dd,
DdNode * bF,
DdNode * bG )
extern

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 253 of file extraBddAuto.c.

254{
255 DdNode * bRes;
256 do {
257 dd->reordered = 0;
258 bRes = extraBddSpaceFromFunction( dd, bF, bG );
259 } while (dd->reordered == 1);
260 return bRes;
261}
DdNode * extraBddSpaceFromFunction(DdManager *dd, DdNode *bF, DdNode *bG)
Here is the call graph for this function:

◆ Extra_bddSpaceFromFunctionFast()

DdNode * Extra_bddSpaceFromFunctionFast ( DdManager * dd,
DdNode * bFunc )
extern

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

FileName [extraBddAuto.c]

PackageName [extra]

Synopsis [Computation of autosymmetries.]

Author [Alan Mishchenko]

Affiliation [UC Berkeley]

Date [Ver. 2.0. Started - September 1, 2003.]

Revision [

Id
extraBddAuto.c,v 1.0 2003/05/21 18:03:50 alanmi Exp

] AutomaticStart AutomaticEnd Function*************************************************************

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 153 of file extraBddAuto.c.

154{
155 int * pSupport;
156 int * pPermute;
157 int * pPermuteBack;
158 DdNode ** pCompose;
159 DdNode * bCube, * bTemp;
160 DdNode * bSpace, * bFunc1, * bFunc2, * bSpaceShift;
161 int nSupp, Counter;
162 int i, lev;
163
164 // get the support
165 pSupport = ABC_ALLOC( int, ddMax(dd->size,dd->sizeZ) );
166 Extra_SupportArray( dd, bFunc, pSupport );
167 nSupp = 0;
168 for ( i = 0; i < dd->size; i++ )
169 if ( pSupport[i] )
170 nSupp++;
171
172 // make sure the manager has enough variables
173 if ( 2*nSupp > dd->size )
174 {
175 printf( "Cannot derive linear space, because DD manager does not have enough variables.\n" );
176 fflush( stdout );
177 ABC_FREE( pSupport );
178 return NULL;
179 }
180
181 // create the permutation arrays
182 pPermute = ABC_ALLOC( int, dd->size );
183 pPermuteBack = ABC_ALLOC( int, dd->size );
184 pCompose = ABC_ALLOC( DdNode *, dd->size );
185 for ( i = 0; i < dd->size; i++ )
186 {
187 pPermute[i] = i;
188 pPermuteBack[i] = i;
189 pCompose[i] = dd->vars[i]; Cudd_Ref( pCompose[i] );
190 }
191
192 // remap the function in such a way that the variables are interleaved
193 Counter = 0;
194 bCube = b1; Cudd_Ref( bCube );
195 for ( lev = 0; lev < dd->size; lev++ )
196 if ( pSupport[ dd->invperm[lev] ] )
197 { // var "dd->invperm[lev]" on level "lev" should go to level 2*Counter;
198 pPermute[ dd->invperm[lev] ] = dd->invperm[2*Counter];
199 // var from level 2*Counter+1 should go back to the place of this var
200 pPermuteBack[ dd->invperm[2*Counter+1] ] = dd->invperm[lev];
201 // the permutation should be defined in such a way that variable
202 // on level 2*Counter is replaced by an EXOR of itself and var on the next level
203 Cudd_Deref( pCompose[ dd->invperm[2*Counter] ] );
204 pCompose[ dd->invperm[2*Counter] ] =
205 Cudd_bddXor( dd, dd->vars[ dd->invperm[2*Counter] ], dd->vars[ dd->invperm[2*Counter+1] ] );
206 Cudd_Ref( pCompose[ dd->invperm[2*Counter] ] );
207 // add this variable to the cube
208 bCube = Cudd_bddAnd( dd, bTemp = bCube, dd->vars[ dd->invperm[2*Counter] ] ); Cudd_Ref( bCube );
209 Cudd_RecursiveDeref( dd, bTemp );
210 // increment the counter
211 Counter ++;
212 }
213
214 // permute the functions
215 bFunc1 = Cudd_bddPermute( dd, bFunc, pPermute ); Cudd_Ref( bFunc1 );
216 // compose to gate the function depending on both vars
217 bFunc2 = Cudd_bddVectorCompose( dd, bFunc1, pCompose ); Cudd_Ref( bFunc2 );
218 // gate the vector space
219 // L(a) = ForAll x [ F(x) = F(x+a) ] = Not( Exist x [ F(x) (+) F(x+a) ] )
220 bSpaceShift = Cudd_bddXorExistAbstract( dd, bFunc1, bFunc2, bCube ); Cudd_Ref( bSpaceShift );
221 bSpaceShift = Cudd_Not( bSpaceShift );
222 // permute the space back into the original mapping
223 bSpace = Cudd_bddPermute( dd, bSpaceShift, pPermuteBack ); Cudd_Ref( bSpace );
224 Cudd_RecursiveDeref( dd, bFunc1 );
225 Cudd_RecursiveDeref( dd, bFunc2 );
226 Cudd_RecursiveDeref( dd, bSpaceShift );
227 Cudd_RecursiveDeref( dd, bCube );
228
229 for ( i = 0; i < dd->size; i++ )
230 Cudd_RecursiveDeref( dd, pCompose[i] );
231 ABC_FREE( pPermute );
232 ABC_FREE( pPermuteBack );
233 ABC_FREE( pCompose );
234 ABC_FREE( pSupport );
235
236 Cudd_Deref( bSpace );
237 return bSpace;
238}
Here is the call graph for this function:

◆ Extra_bddSpaceFromFunctionNeg()

DdNode * Extra_bddSpaceFromFunctionNeg ( DdManager * dd,
DdNode * bFunc )
extern

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 295 of file extraBddAuto.c.

296{
297 DdNode * bRes;
298 do {
299 dd->reordered = 0;
300 bRes = extraBddSpaceFromFunctionNeg( dd, bFunc );
301 } while (dd->reordered == 1);
302 return bRes;
303}
DdNode * extraBddSpaceFromFunctionNeg(DdManager *dd, DdNode *bF)
Here is the call graph for this function:

◆ Extra_bddSpaceFromFunctionPos()

DdNode * Extra_bddSpaceFromFunctionPos ( DdManager * dd,
DdNode * bFunc )
extern

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 274 of file extraBddAuto.c.

275{
276 DdNode * bRes;
277 do {
278 dd->reordered = 0;
279 bRes = extraBddSpaceFromFunctionPos( dd, bFunc );
280 } while (dd->reordered == 1);
281 return bRes;
282}
DdNode * extraBddSpaceFromFunctionPos(DdManager *dd, DdNode *bF)
Here is the call graph for this function:

◆ Extra_bddSpaceFromMatrixNeg()

DdNode * Extra_bddSpaceFromMatrixNeg ( DdManager * dd,
DdNode * zA )
extern

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 452 of file extraBddAuto.c.

453{
454 DdNode * bRes;
455 do {
456 dd->reordered = 0;
457 bRes = extraBddSpaceFromMatrixNeg( dd, zA );
458 } while (dd->reordered == 1);
459 return bRes;
460}
DdNode * extraBddSpaceFromMatrixNeg(DdManager *dd, DdNode *zA)
Here is the call graph for this function:

◆ Extra_bddSpaceFromMatrixPos()

DdNode * Extra_bddSpaceFromMatrixPos ( DdManager * dd,
DdNode * zA )
extern

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 431 of file extraBddAuto.c.

432{
433 DdNode * bRes;
434 do {
435 dd->reordered = 0;
436 bRes = extraBddSpaceFromMatrixPos( dd, zA );
437 } while (dd->reordered == 1);
438 return bRes;
439}
DdNode * extraBddSpaceFromMatrixPos(DdManager *dd, DdNode *zA)
Here is the call graph for this function:

◆ Extra_bddSpaceReduce()

DdNode * Extra_bddSpaceReduce ( DdManager * dd,
DdNode * bFunc,
DdNode * bCanonVars )
extern

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 337 of file extraBddAuto.c.

338{
339 DdNode * bNegCube;
340 DdNode * bResult;
341 bNegCube = Extra_bddSupportNegativeCube( dd, bCanonVars ); Cudd_Ref( bNegCube );
342 bResult = Cudd_Cofactor( dd, bFunc, bNegCube ); Cudd_Ref( bResult );
343 Cudd_RecursiveDeref( dd, bNegCube );
344 Cudd_Deref( bResult );
345 return bResult;
346}
DdNode * Extra_bddSupportNegativeCube(DdManager *dd, DdNode *f)
Here is the call graph for this function:

◆ Extra_bddSuppCheckContainment()

int Extra_bddSuppCheckContainment ( DdManager * dd,
DdNode * bL,
DdNode * bH,
DdNode ** bLarge,
DdNode ** bSmall )
extern

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

Synopsis [Checks the support containment.]

Description [This function returns 1 if one support is contained in another. In this case, bLarge (bSmall) is assigned to point to the larger (smaller) support. If the supports are identical, return 0 and does not assign the supports!]

SideEffects []

SeeAlso []

Definition at line 443 of file extraBddMisc.c.

444{
445 DdNode * bSL = bL;
446 DdNode * bSH = bH;
447 int fLcontainsH = 1;
448 int fHcontainsL = 1;
449 int TopVar;
450
451 if ( bSL == bSH )
452 return 0;
453
454 while ( bSL != b1 || bSH != b1 )
455 {
456 if ( bSL == b1 )
457 { // Low component has no vars; High components has some vars
458 fLcontainsH = 0;
459 if ( fHcontainsL == 0 )
460 return 0;
461 else
462 break;
463 }
464
465 if ( bSH == b1 )
466 { // similarly
467 fHcontainsL = 0;
468 if ( fLcontainsH == 0 )
469 return 0;
470 else
471 break;
472 }
473
474 // determine the topmost var of the supports by comparing their levels
475 if ( dd->perm[bSL->index] < dd->perm[bSH->index] )
476 TopVar = bSL->index;
477 else
478 TopVar = bSH->index;
479
480 if ( TopVar == bSL->index && TopVar == bSH->index )
481 { // they are on the same level
482 // it does not tell us anything about their containment
483 // skip this var
484 bSL = cuddT(bSL);
485 bSH = cuddT(bSH);
486 }
487 else if ( TopVar == bSL->index ) // and TopVar != bSH->index
488 { // Low components is higher and contains more vars
489 // it is not possible that High component contains Low
490 fHcontainsL = 0;
491 // skip this var
492 bSL = cuddT(bSL);
493 }
494 else // if ( TopVar == bSH->index ) // and TopVar != bSL->index
495 { // similarly
496 fLcontainsH = 0;
497 // skip this var
498 bSH = cuddT(bSH);
499 }
500
501 // check the stopping condition
502 if ( !fHcontainsL && !fLcontainsH )
503 return 0;
504 }
505 // only one of them can be true at the same time
506 assert( !fHcontainsL || !fLcontainsH );
507 if ( fHcontainsL )
508 {
509 *bLarge = bH;
510 *bSmall = bL;
511 }
512 else // fLcontainsH
513 {
514 *bLarge = bL;
515 *bSmall = bH;
516 }
517 return 1;
518}

◆ Extra_bddSuppContainVar()

int Extra_bddSuppContainVar ( DdManager * dd,
DdNode * bS,
DdNode * bVar )
extern

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

Synopsis [Returns 1 if the support contains the given BDD variable.]

Description []

SideEffects []

SeeAlso []

Definition at line 346 of file extraBddMisc.c.

347{
348 for( ; bS != b1; bS = cuddT(bS) )
349 if ( bS->index == bVar->index )
350 return 1;
351 return 0;
352}

◆ Extra_bddSuppDifferentVars()

int Extra_bddSuppDifferentVars ( DdManager * dd,
DdNode * S1,
DdNode * S2,
int DiffMax )
extern

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

Synopsis [Returns the number of different vars in two supports.]

Description [Counts the number of variables that appear in one support and does not appear in other support. If the number exceeds DiffMax, returns DiffMax.]

SideEffects []

SeeAlso []

Definition at line 393 of file extraBddMisc.c.

394{
395 int Result = 0;
396 while ( S1->index != CUDD_CONST_INDEX && S2->index != CUDD_CONST_INDEX )
397 {
398 // if the top vars are the same, this var is the same
399 if ( S1->index == S2->index )
400 {
401 S1 = cuddT(S1);
402 S2 = cuddT(S2);
403 continue;
404 }
405 // the top var is different
406 Result++;
407
408 if ( Result >= DiffMax )
409 return DiffMax;
410
411 // if the top vars are different, skip the one, which is higher
412 if ( dd->perm[S1->index] < dd->perm[S2->index] )
413 S1 = cuddT(S1);
414 else
415 S2 = cuddT(S2);
416 }
417
418 // consider the remaining variables
419 if ( S1->index != CUDD_CONST_INDEX )
420 Result += Extra_bddSuppSize(dd,S1);
421 else if ( S2->index != CUDD_CONST_INDEX )
422 Result += Extra_bddSuppSize(dd,S2);
423
424 if ( Result >= DiffMax )
425 return DiffMax;
426 return Result;
427}
int Extra_bddSuppSize(DdManager *dd, DdNode *bSupp)
Here is the call graph for this function:

◆ Extra_bddSupportNegativeCube()

DdNode * Extra_bddSupportNegativeCube ( DdManager * dd,
DdNode * f )
extern

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

Synopsis [Finds the support as a negative polarity cube.]

Description [Finds the variables on which a DD depends. Returns a BDD consisting of the product of the variables in the negative polarity if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_VectorSupport Cudd_Support]

Definition at line 764 of file extraBddMisc.c.

765{
766 int *support;
767 DdNode *res, *tmp, *var;
768 int i, j;
769 int size;
770
771 /* Allocate and initialize support array for ddSupportStep. */
772 size = ddMax( dd->size, dd->sizeZ );
773 support = ABC_ALLOC( int, size );
774 if ( support == NULL )
775 {
776 dd->errorCode = CUDD_MEMORY_OUT;
777 return ( NULL );
778 }
779 for ( i = 0; i < size; i++ )
780 {
781 support[i] = 0;
782 }
783
784 /* Compute support and clean up markers. */
785 ddSupportStep2( Cudd_Regular( f ), support );
786 ddClearFlag2( Cudd_Regular( f ) );
787
788 /* Transform support from array to cube. */
789 do
790 {
791 dd->reordered = 0;
792 res = DD_ONE( dd );
793 cuddRef( res );
794 for ( j = size - 1; j >= 0; j-- )
795 { /* for each level bottom-up */
796 i = ( j >= dd->size ) ? j : dd->invperm[j];
797 if ( support[i] == 1 )
798 {
799 var = cuddUniqueInter( dd, i, dd->one, Cudd_Not( dd->one ) );
801 var = Cudd_Not(var);
803 cuddRef( var );
804 tmp = cuddBddAndRecur( dd, res, var );
805 if ( tmp == NULL )
806 {
807 Cudd_RecursiveDeref( dd, res );
808 Cudd_RecursiveDeref( dd, var );
809 res = NULL;
810 break;
811 }
812 cuddRef( tmp );
813 Cudd_RecursiveDeref( dd, res );
814 Cudd_RecursiveDeref( dd, var );
815 res = tmp;
816 }
817 }
818 }
819 while ( dd->reordered == 1 );
820
821 ABC_FREE( support );
822 if ( res != NULL )
823 cuddDeref( res );
824 return ( res );
825
826} /* end of Extra_SupportNeg */
void ddClearFlag2(DdNode *f)
void ddSupportStep2(DdNode *f, int *support)
unsigned long long size
Definition giaNewBdd.h:39
unsigned short var
Definition giaNewBdd.h:35
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_bddSuppOverlapping()

int Extra_bddSuppOverlapping ( DdManager * dd,
DdNode * S1,
DdNode * S2 )
extern

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

Synopsis [Returns 1 if two supports represented as BDD cubes are overlapping.]

Description []

SideEffects []

SeeAlso []

Definition at line 365 of file extraBddMisc.c.

366{
367 while ( S1->index != CUDD_CONST_INDEX && S2->index != CUDD_CONST_INDEX )
368 {
369 // if the top vars are the same, they intersect
370 if ( S1->index == S2->index )
371 return 1;
372 // if the top vars are different, skip the one, which is higher
373 if ( dd->perm[S1->index] < dd->perm[S2->index] )
374 S1 = cuddT(S1);
375 else
376 S2 = cuddT(S2);
377 }
378 return 0;
379}

◆ Extra_bddSuppSize()

int Extra_bddSuppSize ( DdManager * dd,
DdNode * bSupp )
extern

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

Synopsis [Returns the size of the support.]

Description []

SideEffects []

SeeAlso []

Definition at line 321 of file extraBddMisc.c.

322{
323 int Counter = 0;
324 while ( bSupp != b1 )
325 {
326 assert( !Cudd_IsComplement(bSupp) );
327 assert( cuddE(bSupp) == b0 );
328
329 bSupp = cuddT(bSupp);
330 Counter++;
331 }
332 return Counter;
333}
Here is the caller graph for this function:

◆ Extra_bddTuples()

DdNode * Extra_bddTuples ( DdManager * dd,
int K,
DdNode * VarsN )
extern

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

Synopsis [Builds BDD representing the set of fixed-size variable tuples.]

Description [Creates BDD of all combinations of variables in Support that have k vars in them.]

SideEffects []

SeeAlso []

Definition at line 2691 of file extraBddMisc.c.

2695{
2696 DdNode *res;
2697 int autoDyn;
2698
2699 /* it is important that reordering does not happen,
2700 otherwise, this methods will not work */
2701
2702 autoDyn = dd->autoDyn;
2703 dd->autoDyn = 0;
2704
2705 do {
2706 /* transform the numeric arguments (K) into a DdNode * argument;
2707 * this allows us to use the standard internal CUDD cache */
2708 DdNode *VarSet = VarsN, *VarsK = VarsN;
2709 int nVars = 0, i;
2710
2711 /* determine the number of variables in VarSet */
2712 while ( VarSet != b1 )
2713 {
2714 nVars++;
2715 /* make sure that the VarSet is a cube */
2716 if ( cuddE( VarSet ) != b0 )
2717 return NULL;
2718 VarSet = cuddT( VarSet );
2719 }
2720 /* make sure that the number of variables in VarSet is less or equal
2721 that the number of variables that should be present in the tuples
2722 */
2723 if ( K > nVars )
2724 return NULL;
2725
2726 /* the second argument in the recursive call stands for <n>;
2727 * create the first argument, which stands for <k>
2728 * as when we are talking about the tuple of <k> out of <n> */
2729 for ( i = 0; i < nVars-K; i++ )
2730 VarsK = cuddT( VarsK );
2731
2732 dd->reordered = 0;
2733 res = extraBddTuples(dd, VarsK, VarsN );
2734
2735 } while (dd->reordered == 1);
2736 dd->autoDyn = autoDyn;
2737 return(res);
2738
2739} /* end of Extra_bddTuples */
DdNode * extraBddTuples(DdManager *dd, DdNode *bVarsK, DdNode *bVarsN)
Here is the call graph for this function:

◆ Extra_bddVarIsInCube()

int Extra_bddVarIsInCube ( DdNode * bCube,
int iVar )
extern

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

Synopsis [Checks if the given variable belongs to the cube.]

Description [Return -1 if the var does not appear in the cube. Otherwise, returns polarity (0 or 1) of the var in the cube.]

SideEffects []

SeeAlso []

Definition at line 1056 of file extraBddMisc.c.

1057{
1058 DdNode * bCube0, * bCube1;
1059 while ( Cudd_Regular(bCube)->index != CUDD_CONST_INDEX )
1060 {
1061 bCube0 = Cudd_NotCond( cuddE(Cudd_Regular(bCube)), Cudd_IsComplement(bCube) );
1062 bCube1 = Cudd_NotCond( cuddT(Cudd_Regular(bCube)), Cudd_IsComplement(bCube) );
1063 // make sure it is a cube
1064 assert( (Cudd_IsComplement(bCube0) && Cudd_Regular(bCube0)->index == CUDD_CONST_INDEX) || // bCube0 == 0
1065 (Cudd_IsComplement(bCube1) && Cudd_Regular(bCube1)->index == CUDD_CONST_INDEX) ); // bCube1 == 0
1066 // quit if it is the last one
1067 if ( Cudd_Regular(bCube)->index == iVar )
1068 return (int)(Cudd_IsComplement(bCube0) && Cudd_Regular(bCube0)->index == CUDD_CONST_INDEX);
1069 // get the next cube
1070 if ( (Cudd_IsComplement(bCube0) && Cudd_Regular(bCube0)->index == CUDD_CONST_INDEX) )
1071 bCube = bCube1;
1072 else
1073 bCube = bCube0;
1074 }
1075 return -1;
1076}

◆ Extra_PrintKMap()

void Extra_PrintKMap ( FILE * Output,
DdManager * dd,
DdNode * OnSet,
DdNode * OffSet,
int nVars,
DdNode ** XVars,
int fSuppType,
char ** pVarNames )
extern

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

Synopsis [Prints the K-map of the function.]

Description [If the pointer to the array of variables XVars is NULL, fSuppType determines how the support will be determined. fSuppType == 0 – takes the first nVars of the manager fSuppType == 1 – takes the topmost nVars of the manager fSuppType == 2 – determines support from the on-set and the offset ]

SideEffects []

SeeAlso []

Definition at line 201 of file extraBddKmap.c.

210{
211 int fPrintTruth = 1;
212 int d, p, n, s, v, h, w;
213 int nVarsVer;
214 int nVarsHor;
215 int nCellsVer;
216 int nCellsHor;
217 int nSkipSpaces;
218
219 // make sure that on-set and off-set do not overlap
220 if ( !Cudd_bddLeq( dd, OnSet, Cudd_Not(OffSet) ) )
221 {
222 fprintf( Output, "PrintKMap(): The on-set and the off-set overlap\n" );
223 return;
224 }
225 if ( nVars == 0 )
226 { printf( "Function is constant %d.\n", !Cudd_IsComplement(OnSet) ); return; }
227
228 // print truth table for debugging
229 if ( fPrintTruth )
230 {
231 DdNode * bCube, * bPart;
232 printf( "Truth table: " );
233 if ( nVars == 0 )
234 printf( "Constant" );
235 else if ( nVars == 1 )
236 printf( "1-var function" );
237 else
238 {
239// printf( "0x" );
240 for ( d = (1<<(nVars-2)) - 1; d >= 0; d-- )
241 {
242 int Value = 0;
243 for ( s = 0; s < 4; s++ )
244 {
245 bCube = Extra_bddBitsToCube( dd, 4*d+s, nVars, dd->vars, 0 ); Cudd_Ref( bCube );
246 bPart = Cudd_Cofactor( dd, OnSet, bCube ); Cudd_Ref( bPart );
247 Value |= ((int)(bPart == b1) << s);
248 Cudd_RecursiveDeref( dd, bPart );
249 Cudd_RecursiveDeref( dd, bCube );
250 }
251 if ( Value < 10 )
252 fprintf( stdout, "%d", Value );
253 else
254 fprintf( stdout, "%c", 'a' + Value-10 );
255 }
256 }
257 printf( "\n" );
258 }
259
260
261/*
262 if ( OnSet == b1 )
263 {
264 fprintf( Output, "PrintKMap(): Constant 1\n" );
265 return;
266 }
267 if ( OffSet == b1 )
268 {
269 fprintf( Output, "PrintKMap(): Constant 0\n" );
270 return;
271 }
272*/
273 if ( nVars < 0 || nVars > MAXVARS )
274 {
275 fprintf( Output, "PrintKMap(): The number of variables is less than zero or more than %d\n", MAXVARS );
276 return;
277 }
278
279 // determine the support if it is not given
280 if ( XVars == NULL )
281 {
282 if ( fSuppType == 0 )
283 { // assume that the support includes the first nVars of the manager
284 assert( nVars );
285 for ( v = 0; v < nVars; v++ )
286 s_XVars[v] = Cudd_bddIthVar( dd, v );
287 }
288 else if ( fSuppType == 1 )
289 { // assume that the support includes the topmost nVars of the manager
290 assert( nVars );
291 for ( v = 0; v < nVars; v++ )
292 s_XVars[v] = Cudd_bddIthVar( dd, dd->invperm[v] );
293 }
294 else // determine the support
295 {
296 DdNode * SuppOn, * SuppOff, * Supp;
297 int cVars = 0;
298 DdNode * TempSupp;
299
300 // determine support
301 SuppOn = Cudd_Support( dd, OnSet ); Cudd_Ref( SuppOn );
302 SuppOff = Cudd_Support( dd, OffSet ); Cudd_Ref( SuppOff );
303 Supp = Cudd_bddAnd( dd, SuppOn, SuppOff ); Cudd_Ref( Supp );
304 Cudd_RecursiveDeref( dd, SuppOn );
305 Cudd_RecursiveDeref( dd, SuppOff );
306
307 nVars = Cudd_SupportSize( dd, Supp );
308 if ( nVars > MAXVARS )
309 {
310 fprintf( Output, "PrintKMap(): The number of variables is more than %d\n", MAXVARS );
311 Cudd_RecursiveDeref( dd, Supp );
312 return;
313 }
314
315 // assign variables
316 for ( TempSupp = Supp; TempSupp != dd->one; TempSupp = Cudd_T(TempSupp), cVars++ )
317 s_XVars[cVars] = Cudd_bddIthVar( dd, TempSupp->index );
318
319 Cudd_RecursiveDeref( dd, TempSupp );
320 }
321 }
322 else
323 {
324 // copy variables
325 assert( XVars );
326 for ( v = 0; v < nVars; v++ )
327 s_XVars[v] = XVars[v];
328 }
329
331 // determine the Karnaugh map parameters
332 nVarsVer = nVars/2;
333 nVarsHor = nVars - nVarsVer;
334
335 nCellsVer = (1<<nVarsVer);
336 nCellsHor = (1<<nVarsHor);
337 nSkipSpaces = nVarsVer + 1;
338
340 // print variable names
341 fprintf( Output, "\n" );
342 for ( w = 0; w < nVarsVer; w++ )
343 if ( pVarNames == NULL )
344 fprintf( Output, "%c", 'a'+nVarsHor+w );
345 else
346 fprintf( Output, " %s", pVarNames[nVarsHor+w] );
347
348 if ( fHorizontalVarNamesPrintedAbove )
349 {
350 fprintf( Output, " \\ " );
351 for ( w = 0; w < nVarsHor; w++ )
352 if ( pVarNames == NULL )
353 fprintf( Output, "%c", 'a'+w );
354 else
355 fprintf( Output, "%s ", pVarNames[w] );
356 }
357 fprintf( Output, "\n" );
358
359 if ( fHorizontalVarNamesPrintedAbove )
360 {
362 // print horizontal digits
363 for ( d = 0; d < nVarsHor; d++ )
364 {
365 for ( p = 0; p < nSkipSpaces + 2; p++, fprintf( Output, " " ) );
366 for ( n = 0; n < nCellsHor; n++ )
367 if ( GrayCode(n) & (1<<(nVarsHor-1-d)) )
368 fprintf( Output, "1 " );
369 else
370 fprintf( Output, "0 " );
371 fprintf( Output, "\n" );
372 }
373 }
374
376 // print the upper line
377 for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
378 fprintf( Output, "%c", DOUBLE_TOP_LEFT );
379 for ( s = 0; s < nCellsHor; s++ )
380 {
381 fprintf( Output, "%c", DOUBLE_HORIZONTAL );
382 fprintf( Output, "%c", DOUBLE_HORIZONTAL );
383 fprintf( Output, "%c", DOUBLE_HORIZONTAL );
384 if ( s != nCellsHor-1 )
385 {
386 if ( s&1 )
387 fprintf( Output, "%c", D_JOINS_D_HOR_BOT );
388 else
389 fprintf( Output, "%c", S_JOINS_D_HOR_BOT );
390 }
391 }
392 fprintf( Output, "%c", DOUBLE_TOP_RIGHT );
393 fprintf( Output, "\n" );
394
396 // print the map
397 for ( v = 0; v < nCellsVer; v++ )
398 {
399 DdNode * CubeVerBDD;
400
401 // print horizontal digits
402// for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
403 for ( n = 0; n < nVarsVer; n++ )
404 if ( GrayCode(v) & (1<<(nVarsVer-1-n)) )
405 fprintf( Output, "1" );
406 else
407 fprintf( Output, "0" );
408 fprintf( Output, " " );
409
410 // find vertical cube
411 CubeVerBDD = Extra_bddBitsToCube( dd, GrayCode(v), nVarsVer, s_XVars+nVarsHor, 1 ); Cudd_Ref( CubeVerBDD );
412
413 // print text line
414 fprintf( Output, "%c", DOUBLE_VERTICAL );
415 for ( h = 0; h < nCellsHor; h++ )
416 {
417 DdNode * CubeHorBDD, * Prod, * ValueOnSet, * ValueOffSet;
418
419 fprintf( Output, " " );
420// fprintf( Output, "x" );
422 // determine what should be printed
423 CubeHorBDD = Extra_bddBitsToCube( dd, GrayCode(h), nVarsHor, s_XVars, 1 ); Cudd_Ref( CubeHorBDD );
424 Prod = Cudd_bddAnd( dd, CubeHorBDD, CubeVerBDD ); Cudd_Ref( Prod );
425 Cudd_RecursiveDeref( dd, CubeHorBDD );
426
427 ValueOnSet = Cudd_Cofactor( dd, OnSet, Prod ); Cudd_Ref( ValueOnSet );
428 ValueOffSet = Cudd_Cofactor( dd, OffSet, Prod ); Cudd_Ref( ValueOffSet );
429 Cudd_RecursiveDeref( dd, Prod );
430
431#ifdef WIN32
432 {
433 HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
434 char Symb = 0, Color = 0;
435 if ( ValueOnSet == b1 && ValueOffSet == b0 )
436 Symb = SYMBOL_ONE, Color = 14; // yellow
437 else if ( ValueOnSet == b0 && ValueOffSet == b1 )
438 Symb = SYMBOL_ZERO, Color = 11; // blue
439 else if ( ValueOnSet == b0 && ValueOffSet == b0 )
440 Symb = SYMBOL_DC, Color = 10; // green
441 else if ( ValueOnSet == b1 && ValueOffSet == b1 )
442 Symb = SYMBOL_OVERLAP, Color = 12; // red
443 else
444 assert(0);
445 SetConsoleTextAttribute( hConsole, Color );
446 fprintf( Output, "%c", Symb );
447 SetConsoleTextAttribute( hConsole, 7 );
448 }
449#else
450 {
451 if ( ValueOnSet == b1 && ValueOffSet == b0 )
452 fprintf( Output, "%c", SYMBOL_ONE );
453 else if ( ValueOnSet == b0 && ValueOffSet == b1 )
454 fprintf( Output, "%c", SYMBOL_ZERO );
455 else if ( ValueOnSet == b0 && ValueOffSet == b0 )
456 fprintf( Output, "%c", SYMBOL_DC );
457 else if ( ValueOnSet == b1 && ValueOffSet == b1 )
458 fprintf( Output, "%c", SYMBOL_OVERLAP );
459 else
460 assert(0);
461 }
462#endif
463
464 Cudd_RecursiveDeref( dd, ValueOnSet );
465 Cudd_RecursiveDeref( dd, ValueOffSet );
467 fprintf( Output, " " );
468
469 if ( h != nCellsHor-1 )
470 {
471 if ( h&1 )
472 fprintf( Output, "%c", DOUBLE_VERTICAL );
473 else
474 fprintf( Output, "%c", SINGLE_VERTICAL );
475 }
476 }
477 fprintf( Output, "%c", DOUBLE_VERTICAL );
478 fprintf( Output, "\n" );
479
480 Cudd_RecursiveDeref( dd, CubeVerBDD );
481
482 if ( v != nCellsVer-1 )
483 // print separator line
484 {
485 for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
486 if ( v&1 )
487 {
488 fprintf( Output, "%c", D_JOINS_D_VER_RIGHT );
489 for ( s = 0; s < nCellsHor; s++ )
490 {
491 fprintf( Output, "%c", DOUBLE_HORIZONTAL );
492 fprintf( Output, "%c", DOUBLE_HORIZONTAL );
493 fprintf( Output, "%c", DOUBLE_HORIZONTAL );
494 if ( s != nCellsHor-1 )
495 {
496 if ( s&1 )
497 fprintf( Output, "%c", DOUBLES_CROSS );
498 else
499 fprintf( Output, "%c", S_VER_CROSS_D_HOR );
500 }
501 }
502 fprintf( Output, "%c", D_JOINS_D_VER_LEFT );
503 }
504 else
505 {
506 fprintf( Output, "%c", S_JOINS_D_VER_RIGHT );
507 for ( s = 0; s < nCellsHor; s++ )
508 {
509 fprintf( Output, "%c", SINGLE_HORIZONTAL );
510 fprintf( Output, "%c", SINGLE_HORIZONTAL );
511 fprintf( Output, "%c", SINGLE_HORIZONTAL );
512 if ( s != nCellsHor-1 )
513 {
514 if ( s&1 )
515 fprintf( Output, "%c", S_HOR_CROSS_D_VER );
516 else
517 fprintf( Output, "%c", SINGLES_CROSS );
518 }
519 }
520 fprintf( Output, "%c", S_JOINS_D_VER_LEFT );
521 }
522 fprintf( Output, "\n" );
523 }
524 }
525
527 // print the lower line
528 for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
529 fprintf( Output, "%c", DOUBLE_BOT_LEFT );
530 for ( s = 0; s < nCellsHor; s++ )
531 {
532 fprintf( Output, "%c", DOUBLE_HORIZONTAL );
533 fprintf( Output, "%c", DOUBLE_HORIZONTAL );
534 fprintf( Output, "%c", DOUBLE_HORIZONTAL );
535 if ( s != nCellsHor-1 )
536 {
537 if ( s&1 )
538 fprintf( Output, "%c", D_JOINS_D_HOR_TOP );
539 else
540 fprintf( Output, "%c", S_JOINS_D_HOR_TOP );
541 }
542 }
543 fprintf( Output, "%c", DOUBLE_BOT_RIGHT );
544 fprintf( Output, "\n" );
545
546 if ( !fHorizontalVarNamesPrintedAbove )
547 {
549 // print horizontal digits
550 for ( d = 0; d < nVarsHor; d++ )
551 {
552 for ( p = 0; p < nSkipSpaces + 2; p++, fprintf( Output, " " ) );
553 for ( n = 0; n < nCellsHor; n++ )
554 if ( GrayCode(n) & (1<<(nVarsHor-1-d)) )
555 fprintf( Output, "1 " );
556 else
557 fprintf( Output, "0 " );
558
560 fprintf( Output, "%c", (char)('a'+d) );
562 fprintf( Output, "\n" );
563 }
564 }
565}
int GrayCode(int BinCode)
Definition casCore.c:480
#define MAXVARS
#define S_VER_CROSS_D_HOR
#define SINGLES_CROSS
#define D_JOINS_D_VER_LEFT
#define SYMBOL_OVERLAP
#define D_JOINS_D_HOR_BOT
#define SYMBOL_DC
#define DOUBLE_HORIZONTAL
#define SYMBOL_ONE
#define DOUBLE_TOP_RIGHT
#define S_JOINS_D_HOR_TOP
#define SINGLE_VERTICAL
#define SINGLE_HORIZONTAL
#define S_JOINS_D_VER_LEFT
#define DOUBLE_BOT_LEFT
#define DOUBLE_BOT_RIGHT
#define DOUBLES_CROSS
#define S_JOINS_D_HOR_BOT
#define DOUBLE_VERTICAL
#define S_JOINS_D_VER_RIGHT
#define D_JOINS_D_VER_RIGHT
#define DOUBLE_TOP_LEFT
#define SYMBOL_ZERO
#define S_HOR_CROSS_D_VER
#define D_JOINS_D_HOR_TOP
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_PrintKMapRelation()

void Extra_PrintKMapRelation ( FILE * Output,
DdManager * dd,
DdNode * OnSet,
DdNode * OffSet,
int nXVars,
int nYVars,
DdNode ** XVars,
DdNode ** YVars )
extern

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

Synopsis [Prints the K-map of the relation.]

Description [Assumes that the relation depends the first nXVars of XVars and the first nYVars of YVars. Draws X and Y vars and vertical and horizontal vars.]

SideEffects []

SeeAlso []

Definition at line 581 of file extraBddKmap.c.

590{
591 int d, p, n, s, v, h, w;
592 int nVars;
593 int nVarsVer;
594 int nVarsHor;
595 int nCellsVer;
596 int nCellsHor;
597 int nSkipSpaces;
598
599 // make sure that on-set and off-set do not overlap
600 if ( !Cudd_bddLeq( dd, OnSet, Cudd_Not(OffSet) ) )
601 {
602 fprintf( Output, "PrintKMap(): The on-set and the off-set overlap\n" );
603 return;
604 }
605
606 if ( OnSet == b1 )
607 {
608 fprintf( Output, "PrintKMap(): Constant 1\n" );
609 return;
610 }
611 if ( OffSet == b1 )
612 {
613 fprintf( Output, "PrintKMap(): Constant 0\n" );
614 return;
615 }
616
617 nVars = nXVars + nYVars;
618 if ( nVars < 0 || nVars > MAXVARS )
619 {
620 fprintf( Output, "PrintKMap(): The number of variables is less than zero or more than %d\n", MAXVARS );
621 return;
622 }
623
624
626 // determine the Karnaugh map parameters
627 nVarsVer = nXVars;
628 nVarsHor = nYVars;
629 nCellsVer = (1<<nVarsVer);
630 nCellsHor = (1<<nVarsHor);
631 nSkipSpaces = nVarsVer + 1;
632
634 // print variable names
635 fprintf( Output, "\n" );
636 for ( w = 0; w < nVarsVer; w++ )
637 fprintf( Output, "%c", 'a'+nVarsHor+w );
638 if ( fHorizontalVarNamesPrintedAbove )
639 {
640 fprintf( Output, " \\ " );
641 for ( w = 0; w < nVarsHor; w++ )
642 fprintf( Output, "%c", 'a'+w );
643 }
644 fprintf( Output, "\n" );
645
646 if ( fHorizontalVarNamesPrintedAbove )
647 {
649 // print horizontal digits
650 for ( d = 0; d < nVarsHor; d++ )
651 {
652 for ( p = 0; p < nSkipSpaces + 2; p++, fprintf( Output, " " ) );
653 for ( n = 0; n < nCellsHor; n++ )
654 if ( GrayCode(n) & (1<<(nVarsHor-1-d)) )
655 fprintf( Output, "1 " );
656 else
657 fprintf( Output, "0 " );
658 fprintf( Output, "\n" );
659 }
660 }
661
663 // print the upper line
664 for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
665 fprintf( Output, "%c", DOUBLE_TOP_LEFT );
666 for ( s = 0; s < nCellsHor; s++ )
667 {
668 fprintf( Output, "%c", DOUBLE_HORIZONTAL );
669 fprintf( Output, "%c", DOUBLE_HORIZONTAL );
670 fprintf( Output, "%c", DOUBLE_HORIZONTAL );
671 if ( s != nCellsHor-1 )
672 {
673 if ( s&1 )
674 fprintf( Output, "%c", D_JOINS_D_HOR_BOT );
675 else
676 fprintf( Output, "%c", S_JOINS_D_HOR_BOT );
677 }
678 }
679 fprintf( Output, "%c", DOUBLE_TOP_RIGHT );
680 fprintf( Output, "\n" );
681
683 // print the map
684 for ( v = 0; v < nCellsVer; v++ )
685 {
686 DdNode * CubeVerBDD;
687
688 // print horizontal digits
689// for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
690 for ( n = 0; n < nVarsVer; n++ )
691 if ( GrayCode(v) & (1<<(nVarsVer-1-n)) )
692 fprintf( Output, "1" );
693 else
694 fprintf( Output, "0" );
695 fprintf( Output, " " );
696
697 // find vertical cube
698// CubeVerBDD = Extra_bddBitsToCube( dd, GrayCode(v), nVarsVer, s_XVars+nVarsHor ); Cudd_Ref( CubeVerBDD );
699 CubeVerBDD = Extra_bddBitsToCube( dd, GrayCode(v), nXVars, XVars, 1 ); Cudd_Ref( CubeVerBDD );
700
701 // print text line
702 fprintf( Output, "%c", DOUBLE_VERTICAL );
703 for ( h = 0; h < nCellsHor; h++ )
704 {
705 DdNode * CubeHorBDD, * Prod, * ValueOnSet, * ValueOffSet;
706
707 fprintf( Output, " " );
708// fprintf( Output, "x" );
710 // determine what should be printed
711// CubeHorBDD = Extra_bddBitsToCube( dd, GrayCode(h), nVarsHor, s_XVars ); Cudd_Ref( CubeHorBDD );
712 CubeHorBDD = Extra_bddBitsToCube( dd, GrayCode(h), nYVars, YVars, 1 ); Cudd_Ref( CubeHorBDD );
713 Prod = Cudd_bddAnd( dd, CubeHorBDD, CubeVerBDD ); Cudd_Ref( Prod );
714 Cudd_RecursiveDeref( dd, CubeHorBDD );
715
716 ValueOnSet = Cudd_Cofactor( dd, OnSet, Prod ); Cudd_Ref( ValueOnSet );
717 ValueOffSet = Cudd_Cofactor( dd, OffSet, Prod ); Cudd_Ref( ValueOffSet );
718 Cudd_RecursiveDeref( dd, Prod );
719
720 if ( ValueOnSet == b1 && ValueOffSet == b0 )
721 fprintf( Output, "%c", SYMBOL_ONE );
722 else if ( ValueOnSet == b0 && ValueOffSet == b1 )
723 fprintf( Output, "%c", SYMBOL_ZERO );
724 else if ( ValueOnSet == b0 && ValueOffSet == b0 )
725 fprintf( Output, "%c", SYMBOL_DC );
726 else if ( ValueOnSet == b1 && ValueOffSet == b1 )
727 fprintf( Output, "%c", SYMBOL_OVERLAP );
728 else
729 assert(0);
730
731 Cudd_RecursiveDeref( dd, ValueOnSet );
732 Cudd_RecursiveDeref( dd, ValueOffSet );
734 fprintf( Output, " " );
735
736 if ( h != nCellsHor-1 )
737 {
738 if ( h&1 )
739 fprintf( Output, "%c", DOUBLE_VERTICAL );
740 else
741 fprintf( Output, "%c", SINGLE_VERTICAL );
742 }
743 }
744 fprintf( Output, "%c", DOUBLE_VERTICAL );
745 fprintf( Output, "\n" );
746
747 Cudd_RecursiveDeref( dd, CubeVerBDD );
748
749 if ( v != nCellsVer-1 )
750 // print separator line
751 {
752 for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
753 if ( v&1 )
754 {
755 fprintf( Output, "%c", D_JOINS_D_VER_RIGHT );
756 for ( s = 0; s < nCellsHor; s++ )
757 {
758 fprintf( Output, "%c", DOUBLE_HORIZONTAL );
759 fprintf( Output, "%c", DOUBLE_HORIZONTAL );
760 fprintf( Output, "%c", DOUBLE_HORIZONTAL );
761 if ( s != nCellsHor-1 )
762 {
763 if ( s&1 )
764 fprintf( Output, "%c", DOUBLES_CROSS );
765 else
766 fprintf( Output, "%c", S_VER_CROSS_D_HOR );
767 }
768 }
769 fprintf( Output, "%c", D_JOINS_D_VER_LEFT );
770 }
771 else
772 {
773 fprintf( Output, "%c", S_JOINS_D_VER_RIGHT );
774 for ( s = 0; s < nCellsHor; s++ )
775 {
776 fprintf( Output, "%c", SINGLE_HORIZONTAL );
777 fprintf( Output, "%c", SINGLE_HORIZONTAL );
778 fprintf( Output, "%c", SINGLE_HORIZONTAL );
779 if ( s != nCellsHor-1 )
780 {
781 if ( s&1 )
782 fprintf( Output, "%c", S_HOR_CROSS_D_VER );
783 else
784 fprintf( Output, "%c", SINGLES_CROSS );
785 }
786 }
787 fprintf( Output, "%c", S_JOINS_D_VER_LEFT );
788 }
789 fprintf( Output, "\n" );
790 }
791 }
792
794 // print the lower line
795 for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
796 fprintf( Output, "%c", DOUBLE_BOT_LEFT );
797 for ( s = 0; s < nCellsHor; s++ )
798 {
799 fprintf( Output, "%c", DOUBLE_HORIZONTAL );
800 fprintf( Output, "%c", DOUBLE_HORIZONTAL );
801 fprintf( Output, "%c", DOUBLE_HORIZONTAL );
802 if ( s != nCellsHor-1 )
803 {
804 if ( s&1 )
805 fprintf( Output, "%c", D_JOINS_D_HOR_TOP );
806 else
807 fprintf( Output, "%c", S_JOINS_D_HOR_TOP );
808 }
809 }
810 fprintf( Output, "%c", DOUBLE_BOT_RIGHT );
811 fprintf( Output, "\n" );
812
813 if ( !fHorizontalVarNamesPrintedAbove )
814 {
816 // print horizontal digits
817 for ( d = 0; d < nVarsHor; d++ )
818 {
819 for ( p = 0; p < nSkipSpaces + 2; p++, fprintf( Output, " " ) );
820 for ( n = 0; n < nCellsHor; n++ )
821 if ( GrayCode(n) & (1<<(nVarsHor-1-d)) )
822 fprintf( Output, "1 " );
823 else
824 fprintf( Output, "0 " );
825
827 fprintf( Output, "%c", (char)('a'+d) );
829 fprintf( Output, "\n" );
830 }
831 }
832}
Here is the call graph for this function:

◆ Extra_ProfileWidth()

int Extra_ProfileWidth ( DdManager * dd,
DdNode * Func,
int * pProfile,
int CutLevel )
extern

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

Synopsis [Fast computation of the BDD profile.]

Description [The array to store the profile is given by the user and should contain at least as many entries as there is the maximum of the BDD/ZDD size of the manager PLUS ONE. When we say that the widths of the DD on level L is W, we mean the following. Let us create the cut between the level L-1 and the level L and count the number of different DD nodes pointed to across the cut. This number is the width W. From this it follows the on level 0, the width is equal to the number of external pointers to the considered DDs. If there is only one DD, then the profile on level 0 is always 1. If this DD is rooted in the topmost variable, then the width on level 1 is always 2, etc. The width at the level equal to dd->size is the number of terminal nodes in the DD. (Because we consider the first level #0 and the last level #dd->size, the profile array should contain dd->size+1 entries.) ]

SideEffects [This procedure will not work for BDDs w/ complement edges, only for ADDs and ZDDs]

SeeAlso []

Definition at line 519 of file extraBddCas.c.

520{
521 st__generator * gen;
522 st__table * tNodeTopRef; // this table stores the top level from which this node is pointed to
523 st__table * tNodes;
524 DdNode * node;
525 DdNode * nodeR;
526 int LevelStart, Limit;
527 int i, size;
528 int WidthMax;
529
530 // start the mapping table
531 tNodeTopRef = st__init_table( st__ptrcmp, st__ptrhash);;
532 // add the topmost node to the profile
533 extraProfileUpdateTopLevel( tNodeTopRef, 0, Func );
534
535 // collect all nodes
536 tNodes = Extra_CollectNodes( Func );
537 // go though all the nodes and set the top level the cofactors are pointed from
538// Cudd_ForeachNode( dd, Func, genDD, node )
539 st__foreach_item( tNodes, gen, (const char**)&node, NULL )
540 {
541// assert( Cudd_Regular(node) ); // this procedure works only with ADD/ZDD (not BDD w/ compl.edges)
542 nodeR = Cudd_Regular(node);
543 if ( cuddIsConstant(nodeR) )
544 continue;
545 // this node is not a constant - consider its cofactors
546 extraProfileUpdateTopLevel( tNodeTopRef, dd->perm[node->index]+1, cuddE(nodeR) );
547 extraProfileUpdateTopLevel( tNodeTopRef, dd->perm[node->index]+1, cuddT(nodeR) );
548 }
549 st__free_table( tNodes );
550
551 // clean the profile
552 size = ddMax(dd->size, dd->sizeZ) + 1;
553 for ( i = 0; i < size; i++ )
554 pProfile[i] = 0;
555
556 // create the profile
557 st__foreach_item( tNodeTopRef, gen, (const char**)&node, (char**)&LevelStart )
558 {
559 nodeR = Cudd_Regular(node);
560 Limit = (cuddIsConstant(nodeR))? dd->size: dd->perm[nodeR->index];
561 for ( i = LevelStart; i <= Limit; i++ )
562 pProfile[i]++;
563 }
564
565 if ( CutLevel != -1 && CutLevel != 0 )
566 size = CutLevel;
567
568 // get the max width
569 WidthMax = 0;
570 for ( i = 0; i < size; i++ )
571 if ( WidthMax < pProfile[i] )
572 WidthMax = pProfile[i];
573
574 // deref the table
575 st__free_table( tNodeTopRef );
576
577 return WidthMax;
578} /* end of Extra_ProfileWidth */
st__table * Extra_CollectNodes(DdNode *Func)
void extraProfileUpdateTopLevel(st__table *tNodeTopRef, int TopLevelNew, DdNode *node)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_StopManager()

void Extra_StopManager ( DdManager * dd)
extern

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 223 of file extraBddMisc.c.

224{
225 int RetValue;
226 // check for remaining references in the package
227 RetValue = Cudd_CheckZeroRef( dd );
228 if ( RetValue > 10 )
229// if ( RetValue )
230 printf( "\nThe number of referenced nodes = %d\n\n", RetValue );
231// Cudd_PrintInfo( dd, stdout );
232 Cudd_Quit( dd );
233}
Here is the caller graph for this function:

◆ Extra_SupportArray()

int * Extra_SupportArray ( DdManager * dd,
DdNode * f,
int * support )
extern

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

Synopsis [Finds variables on which the DD depends and returns them as am array.]

Description [Finds the variables on which the DD depends. Returns an array with entries set to 1 for those variables that belong to the support; NULL otherwise. The array is allocated by the user and should have at least as many entries as the maximum number of variables in BDD and ZDD parts of the manager.]

SideEffects [None]

SeeAlso [Cudd_Support Cudd_VectorSupport Cudd_ClassifySupport]

Definition at line 537 of file extraBddMisc.c.

541{
542 int i, size;
543
544 /* Initialize support array for ddSupportStep. */
545 size = ddMax(dd->size, dd->sizeZ);
546 for (i = 0; i < size; i++)
547 support[i] = 0;
548
549 /* Compute support and clean up markers. */
550 ddSupportStep2(Cudd_Regular(f),support);
551 ddClearFlag2(Cudd_Regular(f));
552
553 return(support);
554
555} /* end of Extra_SupportArray */
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_SymmPairsAllocate()

Extra_SymmInfo_t * Extra_SymmPairsAllocate ( int nVars)
extern

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

Synopsis [Allocates symmetry information structure.]

Description []

SideEffects []

SeeAlso []

Definition at line 207 of file extraBddSymm.c.

208{
209 int i;
211
212 // allocate and clean the storage for symmetry info
214 memset( p, 0, sizeof(Extra_SymmInfo_t) );
215 p->nVars = nVars;
216 p->pVars = ABC_ALLOC( int, nVars );
217 p->pSymms = ABC_ALLOC( char *, nVars );
218 p->pSymms[0] = ABC_ALLOC( char , nVars * nVars );
219 memset( p->pSymms[0], 0, nVars * nVars * sizeof(char) );
220
221 for ( i = 1; i < nVars; i++ )
222 p->pSymms[i] = p->pSymms[i-1] + nVars;
223
224 return p;
225} /* end of Extra_SymmPairsAllocate */
struct Extra_SymmInfo_t_ Extra_SymmInfo_t
Definition extraBdd.h:256
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_SymmPairsCompute()

Extra_SymmInfo_t * Extra_SymmPairsCompute ( DdManager * dd,
DdNode * bFunc )
extern

AutomaticStart AutomaticEnd Function********************************************************************

Synopsis [Computes the classical symmetry information for the function.]

Description [Returns the symmetry information in the form of Extra_SymmInfo_t structure.]

SideEffects [If the ZDD variables are not derived from BDD variables with multiplicity 2, this function may derive them in a wrong way.]

SeeAlso []

Definition at line 73 of file extraBddSymm.c.

76{
77 DdNode * bSupp;
78 DdNode * zRes;
80
81 bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupp );
82 zRes = Extra_zddSymmPairsCompute( dd, bFunc, bSupp ); Cudd_Ref( zRes );
83
84 p = Extra_SymmPairsCreateFromZdd( dd, zRes, bSupp );
85
86 Cudd_RecursiveDeref( dd, bSupp );
87 Cudd_RecursiveDerefZdd( dd, zRes );
88
89 return p;
90
91} /* end of Extra_SymmPairsCompute */
DdNode * Extra_zddSymmPairsCompute(DdManager *dd, DdNode *bF, DdNode *bVars)
Extra_SymmInfo_t * Extra_SymmPairsCreateFromZdd(DdManager *dd, DdNode *zPairs, DdNode *bSupp)
Here is the call graph for this function:

◆ Extra_SymmPairsComputeNaive()

Extra_SymmInfo_t * Extra_SymmPairsComputeNaive ( DdManager * dd,
DdNode * bFunc )
extern

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

Synopsis [Computes the classical symmetry information for the function.]

Description [Uses the naive way of comparing cofactors.]

SideEffects []

SeeAlso []

Definition at line 396 of file extraBddSymm.c.

397{
398 DdNode * bSupp, * bTemp;
399 int nSuppSize;
401 int i, k;
402
403 // compute the support
404 bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupp );
405 nSuppSize = Extra_bddSuppSize( dd, bSupp );
406//printf( "Support = %d. ", nSuppSize );
407//Extra_bddPrint( dd, bSupp );
408//printf( "%d ", nSuppSize );
409
410 // allocate the storage for symmetry info
411 p = Extra_SymmPairsAllocate( nSuppSize );
412
413 // assign the variables
414 p->nVarsMax = dd->size;
415 for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ )
416 p->pVars[i] = bTemp->index;
417
418 // go through the candidate pairs and check using Idea1
419 for ( i = 0; i < nSuppSize; i++ )
420 for ( k = i+1; k < nSuppSize; k++ )
421 {
422 p->pSymms[k][i] = p->pSymms[i][k] = Extra_bddCheckVarsSymmetricNaive( dd, bFunc, p->pVars[i], p->pVars[k] );
423 if ( p->pSymms[i][k] )
424 p->nSymms++;
425 }
426
427 Cudd_RecursiveDeref( dd, bSupp );
428 return p;
429
430} /* end of Extra_SymmPairsComputeNaive */
int Extra_bddCheckVarsSymmetricNaive(DdManager *dd, DdNode *bF, int iVar1, int iVar2)
Extra_SymmInfo_t * Extra_SymmPairsAllocate(int nVars)
int Extra_bddSuppSize(DdManager *dd, DdNode *bSupp)
Here is the call graph for this function:

◆ Extra_SymmPairsCreateFromZdd()

Extra_SymmInfo_t * Extra_SymmPairsCreateFromZdd ( DdManager * dd,
DdNode * zPairs,
DdNode * bSupp )
extern

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

Synopsis [Creates the symmetry information structure from ZDD.]

Description [ZDD representation of symmetries is the set of cubes, each of which has two variables in the positive polarity. These variables correspond to the symmetric variable pair.]

SideEffects []

SeeAlso []

Definition at line 288 of file extraBddSymm.c.

289{
290 int i;
291 int nSuppSize;
293 int * pMapVars2Nums;
294 DdNode * bTemp;
295 DdNode * zSet, * zCube, * zTemp;
296 int iVar1, iVar2;
297
298 nSuppSize = Extra_bddSuppSize( dd, bSupp );
299
300 // allocate and clean the storage for symmetry info
301 p = Extra_SymmPairsAllocate( nSuppSize );
302
303 // allocate the storage for the temporary map
304 pMapVars2Nums = ABC_ALLOC( int, dd->size );
305 memset( pMapVars2Nums, 0, dd->size * sizeof(int) );
306
307 // assign the variables
308 p->nVarsMax = dd->size;
309// p->nNodes = Cudd_DagSize( zPairs );
310 p->nNodes = 0;
311 for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ )
312 {
313 p->pVars[i] = bTemp->index;
314 pMapVars2Nums[bTemp->index] = i;
315 }
316
317 // write the symmetry info into the structure
318 zSet = zPairs; Cudd_Ref( zSet );
319 while ( zSet != z0 )
320 {
321 // get the next cube
322 zCube = Extra_zddSelectOneSubset( dd, zSet ); Cudd_Ref( zCube );
323
324 // add these two variables to the data structure
325 assert( cuddT( cuddT(zCube) ) == z1 );
326 iVar1 = zCube->index/2;
327 iVar2 = cuddT(zCube)->index/2;
328 if ( pMapVars2Nums[iVar1] < pMapVars2Nums[iVar2] )
329 p->pSymms[ pMapVars2Nums[iVar1] ][ pMapVars2Nums[iVar2] ] = 1;
330 else
331 p->pSymms[ pMapVars2Nums[iVar2] ][ pMapVars2Nums[iVar1] ] = 1;
332 // count the symmetric pairs
333 p->nSymms ++;
334
335 // update the cuver and deref the cube
336 zSet = Cudd_zddDiff( dd, zTemp = zSet, zCube ); Cudd_Ref( zSet );
337 Cudd_RecursiveDerefZdd( dd, zTemp );
338 Cudd_RecursiveDerefZdd( dd, zCube );
339
340 } // for each cube
341 Cudd_RecursiveDerefZdd( dd, zSet );
342
343 ABC_FREE( pMapVars2Nums );
344 return p;
345
346} /* end of Extra_SymmPairsCreateFromZdd */
DdNode * Extra_zddSelectOneSubset(DdManager *dd, DdNode *zS)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_SymmPairsDissolve()

void Extra_SymmPairsDissolve ( Extra_SymmInfo_t * p)
extern

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

Synopsis [Deallocates symmetry information structure.]

Description []

SideEffects []

SeeAlso []

Definition at line 238 of file extraBddSymm.c.

239{
240 ABC_FREE( p->pVars );
241 ABC_FREE( p->pSymms[0] );
242 ABC_FREE( p->pSymms );
243 ABC_FREE( p );
244} /* end of Extra_SymmPairsDissolve */

◆ Extra_SymmPairsPrint()

void Extra_SymmPairsPrint ( Extra_SymmInfo_t * p)
extern

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

Synopsis [Allocates symmetry information structure.]

Description []

SideEffects []

SeeAlso []

Definition at line 257 of file extraBddSymm.c.

258{
259 int i, k;
260 printf( "\n" );
261 for ( i = 0; i < p->nVars; i++ )
262 {
263 for ( k = 0; k <= i; k++ )
264 printf( " " );
265 for ( k = i+1; k < p->nVars; k++ )
266 if ( p->pSymms[i][k] )
267 printf( "1" );
268 else
269 printf( "." );
270 printf( "\n" );
271 }
272} /* end of Extra_SymmPairsPrint */

◆ Extra_TransferLevelByLevel()

DdNode * Extra_TransferLevelByLevel ( DdManager * ddSource,
DdManager * ddDestination,
DdNode * f )
extern

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

Synopsis [Transfers the BDD from one manager into another level by level.]

Description [Transfers the BDD from one manager into another while preserving the correspondence between variables level by level.]

SideEffects [None]

SeeAlso []

Definition at line 112 of file extraBddMisc.c.

113{
114 DdNode * bRes;
115 int * pPermute;
116 int nMin, nMax, i;
117
118 nMin = ddMin(ddSource->size, ddDestination->size);
119 nMax = ddMax(ddSource->size, ddDestination->size);
120 pPermute = ABC_ALLOC( int, nMax );
121 // set up the variable permutation
122 for ( i = 0; i < nMin; i++ )
123 pPermute[ ddSource->invperm[i] ] = ddDestination->invperm[i];
124 if ( ddSource->size > ddDestination->size )
125 {
126 for ( ; i < nMax; i++ )
127 pPermute[ ddSource->invperm[i] ] = -1;
128 }
129 bRes = Extra_TransferPermute( ddSource, ddDestination, f, pPermute );
130 ABC_FREE( pPermute );
131 return bRes;
132}
DdNode * Extra_TransferPermute(DdManager *ddSource, DdManager *ddDestination, DdNode *f, int *Permute)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_TransferPermute()

DdNode * Extra_TransferPermute ( DdManager * ddSource,
DdManager * ddDestination,
DdNode * f,
int * Permute )
extern

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

Synopsis [Convert a {A,B}DD from a manager to another with variable remapping.]

Description [Convert a {A,B}DD from a manager to another one. The orders of the variables in the two managers may be different. Returns a pointer to the {A,B}DD in the destination manager if successful; NULL otherwise. The i-th entry in the array Permute tells what is the index of the i-th variable from the old manager in the new manager.]

SideEffects [None]

SeeAlso []

Definition at line 87 of file extraBddMisc.c.

88{
89 DdNode * bRes;
90 do
91 {
92 ddDestination->reordered = 0;
93 bRes = extraTransferPermute( ddSource, ddDestination, f, Permute );
94 }
95 while ( ddDestination->reordered == 1 );
96 return ( bRes );
97
98} /* end of Extra_TransferPermute */
Here is the caller graph for this function:

◆ Extra_TransferPermuteTime()

DdNode * Extra_TransferPermuteTime ( DdManager * ddSource,
DdManager * ddDestination,
DdNode * f,
int * Permute,
int TimeOut )
extern

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

Synopsis [Convert a {A,B}DD from a manager to another with variable remapping.]

Description [Convert a {A,B}DD from a manager to another one. The orders of the variables in the two managers may be different. Returns a pointer to the {A,B}DD in the destination manager if successful; NULL otherwise. The i-th entry in the array Permute tells what is the index of the i-th variable from the old manager in the new manager.]

SideEffects [None]

SeeAlso []

Definition at line 150 of file extraBddTime.c.

151{
152 DdNode * bRes;
153 do
154 {
155 ddDestination->reordered = 0;
156 bRes = extraTransferPermuteTime( ddSource, ddDestination, f, Permute, TimeOut );
157 }
158 while ( ddDestination->reordered == 1 );
159 return ( bRes );
160
161} /* end of Extra_TransferPermuteTime */

◆ Extra_UnateComputeFast()

Extra_UnateInfo_t * Extra_UnateComputeFast ( DdManager * dd,
DdNode * bFunc )
extern

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

FileName [extraBddUnate.c]

PackageName [extra]

Synopsis [Efficient methods to compute the information about unate variables using an algorithm that is conceptually similar to the algorithm for two-variable symmetry computation presented in: A. Mishchenko. Fast Computation of Symmetries in Boolean Functions. Transactions on CAD, Nov. 2003.]

Author [Alan Mishchenko]

Affiliation [UC Berkeley]

Date [Ver. 2.0. Started - September 1, 2003.]

Revision [

Id
extraBddUnate.c,v 1.0 2003/09/01 00:00:00 alanmi Exp

] AutomaticStart AutomaticEnd Function********************************************************************

Synopsis [Computes the classical symmetry information for the function.]

Description [Returns the symmetry information in the form of Extra_UnateInfo_t structure.]

SideEffects [If the ZDD variables are not derived from BDD variables with multiplicity 2, this function may derive them in a wrong way.]

SeeAlso []

Definition at line 73 of file extraBddUnate.c.

76{
77 DdNode * bSupp;
78 DdNode * zRes;
80
81 bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupp );
82 zRes = Extra_zddUnateInfoCompute( dd, bFunc, bSupp ); Cudd_Ref( zRes );
83
84 p = Extra_UnateInfoCreateFromZdd( dd, zRes, bSupp );
85
86 Cudd_RecursiveDeref( dd, bSupp );
87 Cudd_RecursiveDerefZdd( dd, zRes );
88
89 return p;
90
91} /* end of Extra_UnateInfoCompute */
Extra_UnateInfo_t * Extra_UnateInfoCreateFromZdd(DdManager *dd, DdNode *zPairs, DdNode *bSupp)
DdNode * Extra_zddUnateInfoCompute(DdManager *dd, DdNode *bF, DdNode *bVars)
struct Extra_UnateInfo_t_ Extra_UnateInfo_t
Definition extraBdd.h:320
Here is the call graph for this function:

◆ Extra_UnateComputeSlow()

Extra_UnateInfo_t * Extra_UnateComputeSlow ( DdManager * dd,
DdNode * bFunc )
extern

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

Synopsis [Computes the classical unateness information for the function.]

Description [Uses the naive way of comparing cofactors.]

SideEffects []

SeeAlso []

Definition at line 293 of file extraBddUnate.c.

294{
295 int nSuppSize;
296 DdNode * bSupp, * bTemp;
298 int i, Res;
299
300 // compute the support
301 bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupp );
302 nSuppSize = Extra_bddSuppSize( dd, bSupp );
303//printf( "Support = %d. ", nSuppSize );
304//Extra_bddPrint( dd, bSupp );
305//printf( "%d ", nSuppSize );
306
307 // allocate the storage for symmetry info
308 p = Extra_UnateInfoAllocate( nSuppSize );
309
310 // assign the variables
311 p->nVarsMax = dd->size;
312 for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ )
313 {
314 Res = Extra_bddCheckUnateNaive( dd, bFunc, bTemp->index );
315 p->pVars[i].iVar = bTemp->index;
316 if ( Res == -1 )
317 p->pVars[i].Neg = 1;
318 else if ( Res == 1 )
319 p->pVars[i].Pos = 1;
320 p->nUnate += (Res != 0);
321 }
322 Cudd_RecursiveDeref( dd, bSupp );
323 return p;
324
325} /* end of Extra_UnateComputeSlow */
int Extra_bddCheckUnateNaive(DdManager *dd, DdNode *bF, int iVar)
Extra_UnateInfo_t * Extra_UnateInfoAllocate(int nVars)
Here is the call graph for this function:

◆ Extra_UnateInfoAllocate()

Extra_UnateInfo_t * Extra_UnateInfoAllocate ( int nVars)
extern

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

Synopsis [Allocates unateness information structure.]

Description []

SideEffects []

SeeAlso []

Definition at line 155 of file extraBddUnate.c.

156{
158 // allocate and clean the storage for unateness info
160 memset( p, 0, sizeof(Extra_UnateInfo_t) );
161 p->nVars = nVars;
162 p->pVars = ABC_ALLOC( Extra_UnateVar_t, nVars );
163 memset( p->pVars, 0, nVars * sizeof(Extra_UnateVar_t) );
164 return p;
165} /* end of Extra_UnateInfoAllocate */
struct Extra_UnateVar_t_ Extra_UnateVar_t
Definition extraBdd.h:313
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_UnateInfoCreateFromZdd()

Extra_UnateInfo_t * Extra_UnateInfoCreateFromZdd ( DdManager * dd,
DdNode * zPairs,
DdNode * bSupp )
extern

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

Synopsis [Creates the symmetry information structure from ZDD.]

Description [ZDD representation of symmetries is the set of cubes, each of which has two variables in the positive polarity. These variables correspond to the symmetric variable pair.]

SideEffects []

SeeAlso []

Definition at line 227 of file extraBddUnate.c.

228{
230 DdNode * bTemp, * zSet, * zCube, * zTemp;
231 int * pMapVars2Nums;
232 int i, nSuppSize;
233
234 nSuppSize = Extra_bddSuppSize( dd, bSupp );
235
236 // allocate and clean the storage for symmetry info
237 p = Extra_UnateInfoAllocate( nSuppSize );
238
239 // allocate the storage for the temporary map
240 pMapVars2Nums = ABC_ALLOC( int, dd->size );
241 memset( pMapVars2Nums, 0, dd->size * sizeof(int) );
242
243 // assign the variables
244 p->nVarsMax = dd->size;
245 for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ )
246 {
247 p->pVars[i].iVar = bTemp->index;
248 pMapVars2Nums[bTemp->index] = i;
249 }
250
251 // write the symmetry info into the structure
252 zSet = zPairs; Cudd_Ref( zSet );
253// Cudd_zddPrintCover( dd, zPairs ); printf( "\n" );
254 while ( zSet != z0 )
255 {
256 // get the next cube
257 zCube = Extra_zddSelectOneSubset( dd, zSet ); Cudd_Ref( zCube );
258
259 // add this var to the data structure
260 assert( cuddT(zCube) == z1 && cuddE(zCube) == z0 );
261 if ( zCube->index & 1 ) // neg
262 p->pVars[ pMapVars2Nums[zCube->index/2] ].Neg = 1;
263 else
264 p->pVars[ pMapVars2Nums[zCube->index/2] ].Pos = 1;
265 // count the unate vars
266 p->nUnate++;
267
268 // update the cuver and deref the cube
269 zSet = Cudd_zddDiff( dd, zTemp = zSet, zCube ); Cudd_Ref( zSet );
270 Cudd_RecursiveDerefZdd( dd, zTemp );
271 Cudd_RecursiveDerefZdd( dd, zCube );
272
273 } // for each cube
274 Cudd_RecursiveDerefZdd( dd, zSet );
275 ABC_FREE( pMapVars2Nums );
276 return p;
277
278} /* end of Extra_UnateInfoCreateFromZdd */
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_UnateInfoDissolve()

void Extra_UnateInfoDissolve ( Extra_UnateInfo_t * p)
extern

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

Synopsis [Deallocates symmetry information structure.]

Description []

SideEffects []

SeeAlso []

Definition at line 178 of file extraBddUnate.c.

179{
180 ABC_FREE( p->pVars );
181 ABC_FREE( p );
182} /* end of Extra_UnateInfoDissolve */

◆ Extra_UnateInfoPrint()

void Extra_UnateInfoPrint ( Extra_UnateInfo_t * p)
extern

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

Synopsis [Allocates symmetry information structure.]

Description []

SideEffects []

SeeAlso []

Definition at line 195 of file extraBddUnate.c.

196{
197 char * pBuffer;
198 int i;
199 pBuffer = ABC_ALLOC( char, p->nVarsMax+1 );
200 memset( pBuffer, ' ', (size_t)p->nVarsMax );
201 pBuffer[p->nVarsMax] = 0;
202 for ( i = 0; i < p->nVars; i++ )
203 if ( p->pVars[i].Neg )
204 pBuffer[ p->pVars[i].iVar ] = 'n';
205 else if ( p->pVars[i].Pos )
206 pBuffer[ p->pVars[i].iVar ] = 'p';
207 else
208 pBuffer[ p->pVars[i].iVar ] = '.';
209 printf( "%s\n", pBuffer );
210 ABC_FREE( pBuffer );
211} /* end of Extra_UnateInfoPrint */
Here is the call graph for this function:

◆ Extra_VectorSupportArray()

int * Extra_VectorSupportArray ( DdManager * dd,
DdNode ** F,
int n,
int * support )
extern

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

Synopsis [Finds the variables on which a set of DDs depends.]

Description [Finds the variables on which a set of DDs depends. The set must contain either BDDs and ADDs, or ZDDs. Returns a BDD consisting of the product of the variables if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_Support Cudd_ClassifySupport]

Definition at line 572 of file extraBddMisc.c.

577{
578 int i, size;
579
580 /* Allocate and initialize support array for ddSupportStep. */
581 size = ddMax( dd->size, dd->sizeZ );
582 for ( i = 0; i < size; i++ )
583 support[i] = 0;
584
585 /* Compute support and clean up markers. */
586 for ( i = 0; i < n; i++ )
587 ddSupportStep2( Cudd_Regular(F[i]), support );
588 for ( i = 0; i < n; i++ )
589 ddClearFlag2( Cudd_Regular(F[i]) );
590
591 return support;
592}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_zddCrossProduct()

DdNode * Extra_zddCrossProduct ( DdManager * dd,
DdNode * S,
DdNode * T )
extern

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

Synopsis [Computes the cross product of two sets of subsets represented by ZDDs.]

Description [The cross product is defined as a set of pair-wise intersections of subsets belonging to the arguments.]

SideEffects []

SeeAlso [Extra_zddDotProduct]

Definition at line 236 of file extraBddMaxMin.c.

240{
241 DdNode *res;
242 do {
243 dd->reordered = 0;
244 res = extraZddCrossProduct(dd, S, T);
245 } while (dd->reordered == 1);
246 return(res);
247
248} /* end of Extra_zddCrossProduct */
DdNode * extraZddCrossProduct(DdManager *dd, DdNode *S, DdNode *T)
Here is the call graph for this function:

◆ Extra_zddDotProduct()

DdNode * Extra_zddDotProduct ( DdManager * dd,
DdNode * S,
DdNode * T )
extern

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

Synopsis [Computes the dot product of two sets of subsets represented by ZDDs.]

Description [The dot product is defined as a set of pair-wise unions of subsets belonging to the arguments.]

SideEffects []

SeeAlso [Extra_zddCrossProduct]

Definition at line 208 of file extraBddMaxMin.c.

212{
213 DdNode *res;
214 do {
215 dd->reordered = 0;
216 res = extraZddDotProduct(dd, S, T);
217 } while (dd->reordered == 1);
218 return(res);
219
220} /* end of Extra_zddDotProduct */
DdNode * extraZddDotProduct(DdManager *dd, DdNode *S, DdNode *T)
Here is the call graph for this function:

◆ Extra_zddDumpPla()

void Extra_zddDumpPla ( DdManager * dd,
DdNode * F,
int nVars,
char * pFileName )
extern

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

Synopsis [Writes ZDD into a PLA file.]

Description []

SideEffects []

SeeAlso []

Definition at line 2307 of file extraBddMisc.c.

2308{
2309 DdGen *gen;
2310 char * pCube;
2311 int * pPath, i;
2312 FILE * pFile = fopen( pFileName, "wb" );
2313 if ( pFile == NULL )
2314 {
2315 printf( "Cannot open file \"%s\" for writing.\n", pFileName );
2316 return;
2317 }
2318 fprintf( pFile, "# PLA file dumped by Extra_zddDumpPla() in ABC\n" );
2319 fprintf( pFile, ".i %d\n", nVars );
2320 fprintf( pFile, ".o 1\n" );
2321 pCube = ABC_CALLOC( char, dd->sizeZ );
2322 Cudd_zddForeachPath( dd, F, gen, pPath )
2323 {
2324 for ( i = 0; i < nVars; i++ )
2325 pCube[i] = '-';
2326 for ( i = 0; i < nVars; i++ )
2327 if ( pPath[2*i] == 1 || pPath[2*i+1] == 1 )
2328 pCube[i] = '0' + (pPath[2*i] == 1);
2329 fprintf( pFile, "%s 1\n", pCube );
2330 }
2331 fprintf( pFile, ".e\n\n" );
2332 fclose( pFile );
2333 ABC_FREE( pCube );
2334}
#define ABC_CALLOC(type, num)
Definition abc_global.h:265

◆ Extra_zddEmptyBelongs()

int Extra_zddEmptyBelongs ( DdManager * dd,
DdNode * zS )
extern

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

Synopsis [Returns 1 if ZDD contains the empty combination; 0 otherwise.]

Description []

SideEffects []

SeeAlso []

Definition at line 265 of file extraBddSet.c.

268{
269 while ( zS->index != CUDD_MAXINDEX )
270 zS = cuddE( zS );
271 return (int)( zS == z1 );
272
273} /* end of Extra_zddEmptyBelongs */
Here is the caller graph for this function:

◆ Extra_zddGetSingletons()

DdNode * Extra_zddGetSingletons ( DdManager * dd,
DdNode * bVars )
extern

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

Synopsis [Converts a set of variables into a set of singleton subsets.]

Description []

SideEffects []

SeeAlso []

Definition at line 157 of file extraBddSymm.c.

160{
161 DdNode * res;
162 do {
163 dd->reordered = 0;
164 res = extraZddGetSingletons( dd, bVars );
165 } while (dd->reordered == 1);
166 return(res);
167
168} /* end of Extra_zddGetSingletons */
DdNode * extraZddGetSingletons(DdManager *dd, DdNode *bVars)
Here is the call graph for this function:

◆ Extra_zddGetSingletonsBoth()

DdNode * Extra_zddGetSingletonsBoth ( DdManager * dd,
DdNode * bVars )
extern

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

Synopsis [Converts a set of variables into a set of singleton subsets.]

Description []

SideEffects []

SeeAlso []

Definition at line 131 of file extraBddUnate.c.

134{
135 DdNode * res;
136 do {
137 dd->reordered = 0;
138 res = extraZddGetSingletonsBoth( dd, bVars );
139 } while (dd->reordered == 1);
140 return(res);
141
142} /* end of Extra_zddGetSingletonsBoth */
DdNode * extraZddGetSingletonsBoth(DdManager *dd, DdNode *bVars)
Here is the call graph for this function:

◆ Extra_zddGetSymmetricVars()

DdNode * Extra_zddGetSymmetricVars ( DdManager * dd,
DdNode * bF,
DdNode * bG,
DdNode * bVars )
extern

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

Synopsis [Returns a singleton-set ZDD containing all variables that are symmetric with the given one.]

Description []

SideEffects []

SeeAlso []

Definition at line 130 of file extraBddSymm.c.

135{
136 DdNode * res;
137 do {
138 dd->reordered = 0;
139 res = extraZddGetSymmetricVars( dd, bF, bG, bVars );
140 } while (dd->reordered == 1);
141 return(res);
142
143} /* end of Extra_zddGetSymmetricVars */
DdNode * extraZddGetSymmetricVars(DdManager *dd, DdNode *bF, DdNode *bG, DdNode *bVars)
Here is the call graph for this function:

◆ Extra_zddIsOneSubset()

int Extra_zddIsOneSubset ( DdManager * dd,
DdNode * zS )
extern

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

Synopsis [Returns 1 if the set is empty or consists of one subset only.]

Description []

SideEffects []

SeeAlso []

Definition at line 288 of file extraBddSet.c.

291{
292 while ( zS->index != CUDD_MAXINDEX )
293 {
294 assert( cuddT(zS) != z0 );
295 if ( cuddE(zS) != z0 )
296 return 0;
297 zS = cuddT( zS );
298 }
299 return (int)( zS == z1 );
300
301} /* end of Extra_zddEmptyBelongs */

◆ Extra_zddMaxDotProduct()

DdNode * Extra_zddMaxDotProduct ( DdManager * dd,
DdNode * S,
DdNode * T )
extern

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

Synopsis [Computes the maximal of the DotProduct of the union of two sets represented by ZDDs.]

Description []

SideEffects []

SeeAlso [Extra_zddDotProduct Extra_zddMaximal Extra_zddMinCrossProduct]

Definition at line 263 of file extraBddMaxMin.c.

267{
268 DdNode *res;
269 do {
270 dd->reordered = 0;
271 res = extraZddMaxDotProduct(dd, S, T);
272 } while (dd->reordered == 1);
273 return(res);
274
275} /* end of Extra_zddMaxDotProduct */
DdNode * extraZddMaxDotProduct(DdManager *dd, DdNode *S, DdNode *T)
Here is the call graph for this function:

◆ Extra_zddMaximal()

DdNode * Extra_zddMaximal ( DdManager * dd,
DdNode * S )
extern

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

FileName [zMaxMin.c]

PackageName [extra]

Synopsis [Experimental version of some ZDD operators.]

Description [External procedures included in this module:

Internal procedures included in this module:

StaTc procedures included in this module:

DotProduct and MaxDotProduct were introduced by O.Coudert to solve problems arising in two-level planar routing See O. Coudert, C.-J. R. Shi. Exact Multi-Layer Topological Planar Routing. Proc. of IEEE Custom Integrated Circuit Conference '96, pp. 179-182. ]

SeeAlso []

Author [Alan Mishchenko]

Copyright []

ReviSon [$zMaxMin.c, v.1.2, November 26, 2000, alanmi $] AutomaTcStart AutomaTcEnd Function********************************************************************

Synopsis [Computes the maximal of a set represented by its ZDD.]

Description []

SideEffects []

SeeAlso [Extra_zddMinimal]

Definition at line 101 of file extraBddMaxMin.c.

104{
105 DdNode *res;
106 do {
107 dd->reordered = 0;
108 res = extraZddMaximal(dd, S);
109 } while (dd->reordered == 1);
110 return(res);
111
112} /* end of Extra_zddMaximal */
DdNode * extraZddMaximal(DdManager *dd, DdNode *zSet)
Here is the call graph for this function:

◆ Extra_zddMaxNotSupSet()

DdNode * Extra_zddMaxNotSupSet ( DdManager * dd,
DdNode * X,
DdNode * Y )
extern

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

Synopsis [Computes the maximal of subsets in X not contained in any of the subsets of Y.]

Description []

SideEffects []

SeeAlso [Extra_zddSubSet, Extra_zddSupSet, Extra_zddSubSet, Extra_zddNotSupSet]

Definition at line 232 of file extraBddSet.c.

236{
237 DdNode *res;
238 int autoDynZ;
239
240 autoDynZ = dd->autoDynZ;
241 dd->autoDynZ = 0;
242
243 do {
244 dd->reordered = 0;
245 res = extraZddMaxNotSupSet(dd, X, Y);
246 } while (dd->reordered == 1);
247 dd->autoDynZ = autoDynZ;
248 return(res);
249
250} /* end of Extra_zddMaxNotSupSet */
DdNode * extraZddMaxNotSupSet(DdManager *dd, DdNode *X, DdNode *Y)
Here is the call graph for this function:

◆ Extra_zddMaxUnion()

DdNode * Extra_zddMaxUnion ( DdManager * dd,
DdNode * S,
DdNode * T )
extern

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

Synopsis [Computes the maximal of the union of two sets represented by ZDDs.]

Description []

SideEffects []

SeeAlso [Extra_zddMaximal Extra_zddMimimal Extra_zddMinUnion]

Definition at line 153 of file extraBddMaxMin.c.

157{
158 DdNode *res;
159 do {
160 dd->reordered = 0;
161 res = extraZddMaxUnion(dd, S, T);
162 } while (dd->reordered == 1);
163 return(res);
164
165} /* end of Extra_zddMaxUnion */
DdNode * extraZddMaxUnion(DdManager *dd, DdNode *S, DdNode *T)
Here is the call graph for this function:

◆ Extra_zddMinimal()

DdNode * Extra_zddMinimal ( DdManager * dd,
DdNode * S )
extern

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

Synopsis [Computes the minimal of a set represented by its ZDD.]

Description []

SideEffects []

SeeAlso [Extra_zddMaximal]

Definition at line 127 of file extraBddMaxMin.c.

130{
131 DdNode *res;
132 do {
133 dd->reordered = 0;
134 res = extraZddMinimal(dd, S);
135 } while (dd->reordered == 1);
136 return(res);
137
138} /* end of Extra_zddMinimal */
DdNode * extraZddMinimal(DdManager *dd, DdNode *zSet)
Here is the call graph for this function:

◆ Extra_zddMinUnion()

DdNode * Extra_zddMinUnion ( DdManager * dd,
DdNode * S,
DdNode * T )
extern

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

Synopsis [Computes the minimal of the union of two sets represented by ZDDs.]

Description []

SideEffects []

SeeAlso [Extra_zddMaximal Extra_zddMimimal Extra_zddMaxUnion]

Definition at line 180 of file extraBddMaxMin.c.

184{
185 DdNode *res;
186 do {
187 dd->reordered = 0;
188 res = extraZddMinUnion(dd, S, T);
189 } while (dd->reordered == 1);
190 return(res);
191
192} /* end of Extra_zddMinUnion */
DdNode * extraZddMinUnion(DdManager *dd, DdNode *S, DdNode *T)
Here is the call graph for this function:

◆ Extra_zddNotSubSet()

DdNode * Extra_zddNotSubSet ( DdManager * dd,
DdNode * X,
DdNode * Y )
extern

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

Synopsis [Computes subsets in X that are not contained in any of the subsets of Y.]

Description []

SideEffects []

SeeAlso [Extra_zddSubSet, Extra_zddSupSet, Extra_zddNotSupSet]

Definition at line 165 of file extraBddSet.c.

169{
170 DdNode *res;
171 int autoDynZ;
172
173 autoDynZ = dd->autoDynZ;
174 dd->autoDynZ = 0;
175
176 do {
177 dd->reordered = 0;
178 res = extraZddNotSubSet(dd, X, Y);
179 } while (dd->reordered == 1);
180 dd->autoDynZ = autoDynZ;
181 return(res);
182
183} /* end of Extra_zddNotSubSet */
DdNode * extraZddNotSubSet(DdManager *dd, DdNode *X, DdNode *Y)
Here is the call graph for this function:

◆ Extra_zddNotSupSet()

DdNode * Extra_zddNotSupSet ( DdManager * dd,
DdNode * X,
DdNode * Y )
extern

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

Synopsis [Computes subsets in X that do not contain any of the subsets of Y.]

Description []

SideEffects []

SeeAlso [Extra_zddSubSet, Extra_zddSupSet, Extra_zddNotSubSet]

Definition at line 198 of file extraBddSet.c.

202{
203 DdNode *res;
204 int autoDynZ;
205
206 autoDynZ = dd->autoDynZ;
207 dd->autoDynZ = 0;
208
209 do {
210 dd->reordered = 0;
211 res = extraZddNotSupSet(dd, X, Y);
212 } while (dd->reordered == 1);
213 dd->autoDynZ = autoDynZ;
214 return(res);
215
216} /* end of Extra_zddNotSupSet */
DdNode * extraZddNotSupSet(DdManager *dd, DdNode *X, DdNode *Y)
Here is the call graph for this function:

◆ Extra_zddPrimes()

DdNode * Extra_zddPrimes ( DdManager * dd,
DdNode * F )
extern

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

Synopsis [Computes the set of primes as a ZDD.]

Description []

SideEffects []

SeeAlso []

Definition at line 933 of file extraBddMisc.c.

934{
935 DdNode *res;
936 do {
937 dd->reordered = 0;
938 res = extraZddPrimes(dd, F);
939 if ( dd->reordered == 1 )
940 printf("\nReordering in Extra_zddPrimes()\n");
941 } while (dd->reordered == 1);
942 return(res);
943
944} /* end of Extra_zddPrimes */

◆ Extra_zddSelectOneSubset()

DdNode * Extra_zddSelectOneSubset ( DdManager * dd,
DdNode * zS )
extern

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

Synopsis [Selects one subset from the set of subsets represented by a ZDD.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 546 of file extraBddSymm.c.

549{
550 DdNode *res;
551 do {
552 dd->reordered = 0;
553 res = extraZddSelectOneSubset(dd, zS);
554 } while (dd->reordered == 1);
555 return(res);
556
557} /* end of Extra_zddSelectOneSubset */
DdNode * extraZddSelectOneSubset(DdManager *dd, DdNode *zS)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_zddSubSet()

DdNode * Extra_zddSubSet ( DdManager * dd,
DdNode * X,
DdNode * Y )
extern

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

FileName [zSubSet.c]

PackageName [extra]

Synopsis [Experimental version of some ZDD operators.]

Description [External procedures included in this module:

Internal procedures included in this module:

Static procedures included in this module:

SubSet, SupSet, NotSubSet, NotSupSet were introduced by O.Coudert to solve problems arising in two-level SOP minimization. See O. Coudert, "Two-Level Logic Minimization: An Overview", Integration. Vol. 17, No. 2, pp. 97-140, Oct 1994. ]

SeeAlso []

Author [Alan Mishchenko]

Copyright []

Revision [$zSubSet.c, v.1.2, November 16, 2000, alanmi $] AutomaticStart AutomaticEnd Function********************************************************************

Synopsis [Computes subsets in X that are contained in some of the subsets of Y.]

Description []

SideEffects []

SeeAlso [Extra_zddNotSubSet, Extra_zddSupSet, Extra_zddNotSupSet]

Definition at line 100 of file extraBddSet.c.

104{
105 DdNode *res;
106 int autoDynZ;
107
108 autoDynZ = dd->autoDynZ;
109 dd->autoDynZ = 0;
110
111 do {
112 dd->reordered = 0;
113 res = extraZddSubSet(dd, X, Y);
114 } while (dd->reordered == 1);
115 dd->autoDynZ = autoDynZ;
116 return(res);
117
118} /* end of Extra_zddSubSet */
DdNode * extraZddSubSet(DdManager *dd, DdNode *X, DdNode *Y)
Here is the call graph for this function:

◆ Extra_zddSupSet()

DdNode * Extra_zddSupSet ( DdManager * dd,
DdNode * X,
DdNode * Y )
extern

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

Synopsis [Computes subsets in X that contain some of the subsets of Y.]

Description []

SideEffects []

SeeAlso [Extra_zddSubSet, Extra_zddNotSubSet, Extra_zddNotSupSet]

Definition at line 133 of file extraBddSet.c.

137{
138 DdNode *res;
139 int autoDynZ;
140
141 autoDynZ = dd->autoDynZ;
142 dd->autoDynZ = 0;
143
144 do {
145 dd->reordered = 0;
146 res = extraZddSupSet(dd, X, Y);
147 } while (dd->reordered == 1);
148 dd->autoDynZ = autoDynZ;
149 return(res);
150
151} /* end of Extra_zddSupSet */
DdNode * extraZddSupSet(DdManager *dd, DdNode *X, DdNode *Y)
Here is the call graph for this function:

◆ Extra_zddSymmPairsCompute()

DdNode * Extra_zddSymmPairsCompute ( DdManager * dd,
DdNode * bF,
DdNode * bVars )
extern

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

Synopsis [Computes the classical symmetry information as a ZDD.]

Description []

SideEffects []

SeeAlso []

Definition at line 105 of file extraBddSymm.c.

109{
110 DdNode * res;
111 do {
112 dd->reordered = 0;
113 res = extraZddSymmPairsCompute( dd, bF, bVars );
114 } while (dd->reordered == 1);
115 return(res);
116
117} /* end of Extra_zddSymmPairsCompute */
DdNode * extraZddSymmPairsCompute(DdManager *dd, DdNode *bFunc, DdNode *bVars)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_zddTuplesFromBdd()

DdNode * Extra_zddTuplesFromBdd ( DdManager * dd,
int K,
DdNode * bVarsN )
extern

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

Synopsis [Builds ZDD representing the set of fixed-size variable tuples.]

Description [Creates ZDD of all combinations of variables in Support that is represented by a BDD.]

SideEffects [New ZDD variables are created if indices of the variables present in the combination are larger than the currently allocated number of ZDD variables.]

SeeAlso []

Definition at line 488 of file extraBddSymm.c.

492{
493 DdNode *zRes;
494 int autoDynZ;
495
496 autoDynZ = dd->autoDynZ;
497 dd->autoDynZ = 0;
498
499 do {
500 /* transform the numeric arguments (K) into a DdNode* argument;
501 * this allows us to use the standard internal CUDD cache */
502 DdNode *bVarSet = bVarsN, *bVarsK = bVarsN;
503 int nVars = 0, i;
504
505 /* determine the number of variables in VarSet */
506 while ( bVarSet != b1 )
507 {
508 nVars++;
509 /* make sure that the VarSet is a cube */
510 if ( cuddE( bVarSet ) != b0 )
511 return NULL;
512 bVarSet = cuddT( bVarSet );
513 }
514 /* make sure that the number of variables in VarSet is less or equal
515 that the number of variables that should be present in the tuples
516 */
517 if ( K > nVars )
518 return NULL;
519
520 /* the second argument in the recursive call stannds for <n>;
521 * reate the first argument, which stands for <k>
522 * as when we are talking about the tuple of <k> out of <n> */
523 for ( i = 0; i < nVars-K; i++ )
524 bVarsK = cuddT( bVarsK );
525
526 dd->reordered = 0;
527 zRes = extraZddTuplesFromBdd(dd, bVarsK, bVarsN );
528
529 } while (dd->reordered == 1);
530 dd->autoDynZ = autoDynZ;
531 return zRes;
532
533} /* end of Extra_zddTuplesFromBdd */
DdNode * extraZddTuplesFromBdd(DdManager *dd, DdNode *bVarsK, DdNode *bVarsN)
Here is the call graph for this function:

◆ Extra_zddUnateInfoCompute()

DdNode * Extra_zddUnateInfoCompute ( DdManager * dd,
DdNode * bF,
DdNode * bVars )
extern

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

Synopsis [Computes the classical symmetry information as a ZDD.]

Description []

SideEffects []

SeeAlso []

Definition at line 105 of file extraBddUnate.c.

109{
110 DdNode * res;
111 do {
112 dd->reordered = 0;
113 res = extraZddUnateInfoCompute( dd, bF, bVars );
114 } while (dd->reordered == 1);
115 return(res);
116
117} /* end of Extra_zddUnateInfoCompute */
DdNode * extraZddUnateInfoCompute(DdManager *dd, DdNode *bFunc, DdNode *bVars)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraBddChangePolarity()

DdNode * extraBddChangePolarity ( DdManager * dd,
DdNode * bFunc,
DdNode * bVars )
extern

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

Synopsis [Performs the reordering-sensitive step of Extra_bddChangePolarity().]

Description []

SideEffects []

SeeAlso []

Definition at line 2041 of file extraBddMisc.c.

2045{
2046 DdNode * bRes;
2047
2048 if ( bVars == b1 )
2049 return bFunc;
2050 if ( Cudd_IsConstant(bFunc) )
2051 return bFunc;
2052
2053 if ( (bRes = cuddCacheLookup2(dd, extraBddChangePolarity, bFunc, bVars)) )
2054 return bRes;
2055 else
2056 {
2057 DdNode * bFR = Cudd_Regular(bFunc);
2058 int LevelF = dd->perm[bFR->index];
2059 int LevelV = dd->perm[bVars->index];
2060
2061 if ( LevelV < LevelF )
2062 bRes = extraBddChangePolarity( dd, bFunc, cuddT(bVars) );
2063 else // if ( LevelF <= LevelV )
2064 {
2065 DdNode * bRes0, * bRes1;
2066 DdNode * bF0, * bF1;
2067 DdNode * bVarsNext;
2068
2069 // cofactor the functions
2070 if ( bFR != bFunc ) // bFunc is complemented
2071 {
2072 bF0 = Cudd_Not( cuddE(bFR) );
2073 bF1 = Cudd_Not( cuddT(bFR) );
2074 }
2075 else
2076 {
2077 bF0 = cuddE(bFR);
2078 bF1 = cuddT(bFR);
2079 }
2080
2081 if ( LevelF == LevelV )
2082 bVarsNext = cuddT(bVars);
2083 else
2084 bVarsNext = bVars;
2085
2086 bRes0 = extraBddChangePolarity( dd, bF0, bVarsNext );
2087 if ( bRes0 == NULL )
2088 return NULL;
2089 cuddRef( bRes0 );
2090
2091 bRes1 = extraBddChangePolarity( dd, bF1, bVarsNext );
2092 if ( bRes1 == NULL )
2093 {
2094 Cudd_RecursiveDeref( dd, bRes0 );
2095 return NULL;
2096 }
2097 cuddRef( bRes1 );
2098
2099 if ( LevelF == LevelV )
2100 { // swap the cofactors
2101 DdNode * bTemp;
2102 bTemp = bRes0;
2103 bRes0 = bRes1;
2104 bRes1 = bTemp;
2105 }
2106
2107 /* only aRes0 and aRes1 are referenced at this point */
2108
2109 /* consider the case when Res0 and Res1 are the same node */
2110 if ( bRes0 == bRes1 )
2111 bRes = bRes1;
2112 /* consider the case when Res1 is complemented */
2113 else if ( Cudd_IsComplement(bRes1) )
2114 {
2115 bRes = cuddUniqueInter(dd, bFR->index, Cudd_Not(bRes1), Cudd_Not(bRes0));
2116 if ( bRes == NULL )
2117 {
2118 Cudd_RecursiveDeref(dd,bRes0);
2119 Cudd_RecursiveDeref(dd,bRes1);
2120 return NULL;
2121 }
2122 bRes = Cudd_Not(bRes);
2123 }
2124 else
2125 {
2126 bRes = cuddUniqueInter( dd, bFR->index, bRes1, bRes0 );
2127 if ( bRes == NULL )
2128 {
2129 Cudd_RecursiveDeref(dd,bRes0);
2130 Cudd_RecursiveDeref(dd,bRes1);
2131 return NULL;
2132 }
2133 }
2134 cuddDeref( bRes0 );
2135 cuddDeref( bRes1 );
2136 }
2137
2138 /* insert the result into cache */
2139 cuddCacheInsert2(dd, extraBddChangePolarity, bFunc, bVars, bRes);
2140 return bRes;
2141 }
2142} /* end of extraBddChangePolarity */
DdNode * extraBddChangePolarity(DdManager *dd, DdNode *bFunc, DdNode *bVars)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraBddCheckVarsSymmetric()

DdNode * extraBddCheckVarsSymmetric ( DdManager * dd,
DdNode * bF,
DdNode * bVars )
extern

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

Synopsis [Performs the recursive step of Extra_bddCheckVarsSymmetric().]

Description [Returns b0 if the variables are not symmetric. Returns b1 if the variables can be symmetric. The variables are represented in the form of a two-variable cube. In case the cube contains one variable (below Var1 level), the cube's pointer is complemented if the variable Var1 occurred on the current path; otherwise, the cube's pointer is regular. Uses additional complemented bit (Hash_Not) to mark the result if in the BDD rooted that this node there is a branch passing though the node labeled with Var2.]

SideEffects []

SeeAlso []

Definition at line 1169 of file extraBddSymm.c.

1173{
1174 DdNode * bRes;
1175
1176 if ( bF == b0 )
1177 return b1;
1178
1179 assert( bVars != b1 );
1180
1181 if ( (bRes = cuddCacheLookup2(dd, extraBddCheckVarsSymmetric, bF, bVars)) )
1182 return bRes;
1183 else
1184 {
1185 DdNode * bRes0, * bRes1;
1186 DdNode * bF0, * bF1;
1187 DdNode * bFR = Cudd_Regular(bF);
1188 int LevelF = cuddI(dd,bFR->index);
1189
1190 DdNode * bVarsR = Cudd_Regular(bVars);
1191 int fVar1Pres;
1192 int iLev1;
1193 int iLev2;
1194
1195 if ( bVarsR != bVars ) // cube's pointer is complemented
1196 {
1197 assert( cuddT(bVarsR) == b1 );
1198 fVar1Pres = 1; // the first var is present on the path
1199 iLev1 = -1; // we are already below the first var level
1200 iLev2 = dd->perm[bVarsR->index]; // the level of the second var
1201 }
1202 else // cube's pointer is NOT complemented
1203 {
1204 fVar1Pres = 0; // the first var is absent on the path
1205 if ( cuddT(bVars) == b1 )
1206 {
1207 iLev1 = -1; // we are already below the first var level
1208 iLev2 = dd->perm[bVars->index]; // the level of the second var
1209 }
1210 else
1211 {
1212 assert( cuddT(cuddT(bVars)) == b1 );
1213 iLev1 = dd->perm[bVars->index]; // the level of the first var
1214 iLev2 = dd->perm[cuddT(bVars)->index]; // the level of the second var
1215 }
1216 }
1217
1218 // cofactor the function
1219 // the cofactors are needed only if we are above the second level
1220 if ( LevelF < iLev2 )
1221 {
1222 if ( bFR != bF ) // bFunc is complemented
1223 {
1224 bF0 = Cudd_Not( cuddE(bFR) );
1225 bF1 = Cudd_Not( cuddT(bFR) );
1226 }
1227 else
1228 {
1229 bF0 = cuddE(bFR);
1230 bF1 = cuddT(bFR);
1231 }
1232 }
1233 else
1234 bF0 = bF1 = NULL;
1235
1236 // consider five cases:
1237 // (1) F is above iLev1
1238 // (2) F is on the level iLev1
1239 // (3) F is between iLev1 and iLev2
1240 // (4) F is on the level iLev2
1241 // (5) F is below iLev2
1242
1243 // (1) F is above iLev1
1244 if ( LevelF < iLev1 )
1245 {
1246 // the returned result cannot have the hash attribute
1247 // because we still did not reach the level of Var1;
1248 // the attribute never travels above the level of Var1
1249 bRes0 = extraBddCheckVarsSymmetric( dd, bF0, bVars );
1250// assert( !Hash_IsComplement( bRes0 ) );
1251 assert( bRes0 != z0 );
1252 if ( bRes0 == b0 )
1253 bRes = b0;
1254 else
1255 bRes = extraBddCheckVarsSymmetric( dd, bF1, bVars );
1256// assert( !Hash_IsComplement( bRes ) );
1257 assert( bRes != z0 );
1258 }
1259 // (2) F is on the level iLev1
1260 else if ( LevelF == iLev1 )
1261 {
1262 bRes0 = extraBddCheckVarsSymmetric( dd, bF0, Cudd_Not( cuddT(bVars) ) );
1263 if ( bRes0 == b0 )
1264 bRes = b0;
1265 else
1266 {
1267 bRes1 = extraBddCheckVarsSymmetric( dd, bF1, Cudd_Not( cuddT(bVars) ) );
1268 if ( bRes1 == b0 )
1269 bRes = b0;
1270 else
1271 {
1272// if ( Hash_IsComplement( bRes0 ) || Hash_IsComplement( bRes1 ) )
1273 if ( bRes0 == z0 || bRes1 == z0 )
1274 bRes = b1;
1275 else
1276 bRes = b0;
1277 }
1278 }
1279 }
1280 // (3) F is between iLev1 and iLev2
1281 else if ( LevelF < iLev2 )
1282 {
1283 bRes0 = extraBddCheckVarsSymmetric( dd, bF0, bVars );
1284 if ( bRes0 == b0 )
1285 bRes = b0;
1286 else
1287 {
1288 bRes1 = extraBddCheckVarsSymmetric( dd, bF1, bVars );
1289 if ( bRes1 == b0 )
1290 bRes = b0;
1291 else
1292 {
1293// if ( Hash_IsComplement( bRes0 ) || Hash_IsComplement( bRes1 ) )
1294// bRes = Hash_Not( b1 );
1295 if ( bRes0 == z0 || bRes1 == z0 )
1296 bRes = z0;
1297 else
1298 bRes = b1;
1299 }
1300 }
1301 }
1302 // (4) F is on the level iLev2
1303 else if ( LevelF == iLev2 )
1304 {
1305 // this is the only place where the hash attribute (Hash_Not) can be added
1306 // to the result; it can be added only if the path came through the node
1307 // lebeled with Var1; therefore, the hash attribute cannot be returned
1308 // to the caller function
1309 if ( fVar1Pres )
1310// bRes = Hash_Not( b1 );
1311 bRes = z0;
1312 else
1313 bRes = b0;
1314 }
1315 // (5) F is below iLev2
1316 else // if ( LevelF > iLev2 )
1317 {
1318 // it is possible that the path goes through the node labeled by Var1
1319 // and still everything is okay; we do not label with Hash_Not here
1320 // because the path does not go through node labeled by Var2
1321 bRes = b1;
1322 }
1323
1324 cuddCacheInsert2(dd, extraBddCheckVarsSymmetric, bF, bVars, bRes);
1325 return bRes;
1326 }
1327} /* end of extraBddCheckVarsSymmetric */
DdNode * extraBddCheckVarsSymmetric(DdManager *dd, DdNode *bF, DdNode *bVars)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraBddMove()

DdNode * extraBddMove ( DdManager * dd,
DdNode * bF,
DdNode * bDist )
extern

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

Synopsis [Performs the reordering-sensitive step of Extra_bddMove().]

Description []

SideEffects []

SeeAlso []

Definition at line 1128 of file extraBddMisc.c.

1132{
1133 DdNode * bRes;
1134
1135 if ( Cudd_IsConstant(bF) )
1136 return bF;
1137
1138 if ( (bRes = cuddCacheLookup2(dd, extraBddMove, bF, bDist)) )
1139 return bRes;
1140 else
1141 {
1142 DdNode * bRes0, * bRes1;
1143 DdNode * bF0, * bF1;
1144 DdNode * bFR = Cudd_Regular(bF);
1145 int VarNew;
1146
1147 if ( Cudd_IsComplement(bDist) )
1148 VarNew = bFR->index - Cudd_Not(bDist)->index;
1149 else
1150 VarNew = bFR->index + bDist->index;
1151 assert( VarNew < dd->size );
1152
1153 // cofactor the functions
1154 if ( bFR != bF ) // bFunc is complemented
1155 {
1156 bF0 = Cudd_Not( cuddE(bFR) );
1157 bF1 = Cudd_Not( cuddT(bFR) );
1158 }
1159 else
1160 {
1161 bF0 = cuddE(bFR);
1162 bF1 = cuddT(bFR);
1163 }
1164
1165 bRes0 = extraBddMove( dd, bF0, bDist );
1166 if ( bRes0 == NULL )
1167 return NULL;
1168 cuddRef( bRes0 );
1169
1170 bRes1 = extraBddMove( dd, bF1, bDist );
1171 if ( bRes1 == NULL )
1172 {
1173 Cudd_RecursiveDeref( dd, bRes0 );
1174 return NULL;
1175 }
1176 cuddRef( bRes1 );
1177
1178 /* only bRes0 and bRes1 are referenced at this point */
1179 bRes = cuddBddIteRecur( dd, dd->vars[VarNew], bRes1, bRes0 );
1180 if ( bRes == NULL )
1181 {
1182 Cudd_RecursiveDeref( dd, bRes0 );
1183 Cudd_RecursiveDeref( dd, bRes1 );
1184 return NULL;
1185 }
1186 cuddRef( bRes );
1187 Cudd_RecursiveDeref( dd, bRes0 );
1188 Cudd_RecursiveDeref( dd, bRes1 );
1189
1190 /* insert the result into cache */
1191 cuddCacheInsert2( dd, extraBddMove, bF, bDist, bRes );
1192 cuddDeref( bRes );
1193 return bRes;
1194 }
1195} /* end of extraBddMove */
DdNode * extraBddMove(DdManager *dd, DdNode *bF, DdNode *bFlag)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraBddReduceVarSet()

DdNode * extraBddReduceVarSet ( DdManager * dd,
DdNode * bVars,
DdNode * bF )
extern

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

Synopsis [Performs a recursive step of Extra_bddReduceVarSet.]

Description [Returns the set of all variables in the given set that are not in the support of the given function.]

SideEffects []

SeeAlso []

Definition at line 1062 of file extraBddSymm.c.

1066{
1067 DdNode * bRes;
1068 DdNode * bFR = Cudd_Regular(bF);
1069
1070 if ( cuddIsConstant(bFR) || bVars == b1 )
1071 return bVars;
1072
1073 if ( (bRes = cuddCacheLookup2(dd, extraBddReduceVarSet, bVars, bF)) )
1074 return bRes;
1075 else
1076 {
1077 DdNode * bF0, * bF1;
1078 DdNode * bVarsThis, * bVarsLower, * bTemp;
1079 int LevelF;
1080
1081 // if LevelF is below LevelV, scroll through the vars in bVars
1082 LevelF = dd->perm[bFR->index];
1083 for ( bVarsThis = bVars; LevelF > cuddI(dd,bVarsThis->index); bVarsThis = cuddT(bVarsThis) );
1084 // scroll also through the current var, because it should be not be added
1085 if ( LevelF == cuddI(dd,bVarsThis->index) )
1086 bVarsLower = cuddT(bVarsThis);
1087 else
1088 bVarsLower = bVarsThis;
1089
1090 // cofactor the function
1091 if ( bFR != bF ) // bFunc is complemented
1092 {
1093 bF0 = Cudd_Not( cuddE(bFR) );
1094 bF1 = Cudd_Not( cuddT(bFR) );
1095 }
1096 else
1097 {
1098 bF0 = cuddE(bFR);
1099 bF1 = cuddT(bFR);
1100 }
1101
1102 // solve subproblems
1103 bRes = extraBddReduceVarSet( dd, bVarsLower, bF0 );
1104 if ( bRes == NULL )
1105 return NULL;
1106 cuddRef( bRes );
1107
1108 bRes = extraBddReduceVarSet( dd, bTemp = bRes, bF1 );
1109 if ( bRes == NULL )
1110 {
1111 Cudd_RecursiveDeref( dd, bTemp );
1112 return NULL;
1113 }
1114 cuddRef( bRes );
1115 Cudd_RecursiveDeref( dd, bTemp );
1116
1117 // the current var should not be added
1118 // add the skipped vars
1119 if ( bVarsThis != bVars )
1120 {
1121 DdNode * bVarsExtra;
1122
1123 // extract the skipped variables
1124 bVarsExtra = cuddBddExistAbstractRecur( dd, bVars, bVarsThis );
1125 if ( bVarsExtra == NULL )
1126 {
1127 Cudd_RecursiveDeref( dd, bRes );
1128 return NULL;
1129 }
1130 cuddRef( bVarsExtra );
1131
1132 // add these variables
1133 bRes = cuddBddAndRecur( dd, bTemp = bRes, bVarsExtra );
1134 if ( bRes == NULL )
1135 {
1136 Cudd_RecursiveDeref( dd, bTemp );
1137 Cudd_RecursiveDeref( dd, bVarsExtra );
1138 return NULL;
1139 }
1140 cuddRef( bRes );
1141 Cudd_RecursiveDeref( dd, bTemp );
1142 Cudd_RecursiveDeref( dd, bVarsExtra );
1143 }
1144 cuddDeref( bRes );
1145
1146 cuddCacheInsert2( dd, extraBddReduceVarSet, bVars, bF, bRes );
1147 return bRes;
1148 }
1149} /* end of extraBddReduceVarSet */
DdNode * extraBddReduceVarSet(DdManager *dd, DdNode *bVars, DdNode *bF)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraBddSpaceCanonVars()

DdNode * extraBddSpaceCanonVars ( DdManager * dd,
DdNode * bF )
extern

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

Synopsis [Performs the recursive step of Extra_bddSpaceCanonVars().]

Description []

SideEffects []

SeeAlso []

Definition at line 1000 of file extraBddAuto.c.

1001{
1002 DdNode * bRes, * bFR;
1003 statLine( dd );
1004
1005 bFR = Cudd_Regular(bF);
1006 if ( cuddIsConstant(bFR) )
1007 return bF;
1008
1009 if ( (bRes = cuddCacheLookup1(dd, extraBddSpaceCanonVars, bF)) )
1010 return bRes;
1011 else
1012 {
1013 DdNode * bF0, * bF1;
1014 DdNode * bRes, * bRes0;
1015
1016 if ( bFR != bF ) // bF is complemented
1017 {
1018 bF0 = Cudd_Not( cuddE(bFR) );
1019 bF1 = Cudd_Not( cuddT(bFR) );
1020 }
1021 else
1022 {
1023 bF0 = cuddE(bFR);
1024 bF1 = cuddT(bFR);
1025 }
1026
1027 if ( bF0 == b0 )
1028 {
1029 bRes = extraBddSpaceCanonVars( dd, bF1 );
1030 if ( bRes == NULL )
1031 return NULL;
1032 }
1033 else if ( bF1 == b0 )
1034 {
1035 bRes = extraBddSpaceCanonVars( dd, bF0 );
1036 if ( bRes == NULL )
1037 return NULL;
1038 }
1039 else
1040 {
1041 bRes0 = extraBddSpaceCanonVars( dd, bF0 );
1042 if ( bRes0 == NULL )
1043 return NULL;
1044 cuddRef( bRes0 );
1045
1046 bRes = cuddUniqueInter( dd, bFR->index, bRes0, b0 );
1047 if ( bRes == NULL )
1048 {
1049 Cudd_RecursiveDeref( dd,bRes0 );
1050 return NULL;
1051 }
1052 cuddDeref( bRes0 );
1053 }
1054
1055 cuddCacheInsert1( dd, extraBddSpaceCanonVars, bF, bRes );
1056 return bRes;
1057 }
1058}
DdNode * extraBddSpaceCanonVars(DdManager *dd, DdNode *bSpace)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraBddSpaceEquationsNeg()

DdNode * extraBddSpaceEquationsNeg ( DdManager * dd,
DdNode * bF )
extern

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

Synopsis [Performs the recursive step of Extra_bddSpaceEquationsNev().]

Description []

SideEffects []

SeeAlso []

Definition at line 1201 of file extraBddAuto.c.

1202{
1203 DdNode * zRes;
1204 statLine( dd );
1205
1206 if ( bF == b0 )
1207 return z1;
1208 if ( bF == b1 )
1209 return z0;
1210
1211 if ( (zRes = cuddCacheLookup1Zdd(dd, extraBddSpaceEquationsNeg, bF)) )
1212 return zRes;
1213 else
1214 {
1215 DdNode * bFR, * bF0, * bF1;
1216 DdNode * zPos0, * zPos1, * zNeg1;
1217 DdNode * zRes, * zRes0, * zRes1;
1218
1219 bFR = Cudd_Regular(bF);
1220 if ( bFR != bF ) // bF is complemented
1221 {
1222 bF0 = Cudd_Not( cuddE(bFR) );
1223 bF1 = Cudd_Not( cuddT(bFR) );
1224 }
1225 else
1226 {
1227 bF0 = cuddE(bFR);
1228 bF1 = cuddT(bFR);
1229 }
1230
1231 if ( bF0 == b0 )
1232 {
1233 zRes = extraBddSpaceEquationsNeg( dd, bF1 );
1234 if ( zRes == NULL )
1235 return NULL;
1236 }
1237 else if ( bF1 == b0 )
1238 {
1239 zRes0 = extraBddSpaceEquationsNeg( dd, bF0 );
1240 if ( zRes0 == NULL )
1241 return NULL;
1242 cuddRef( zRes0 );
1243
1244 // add the current element to the set
1245 zRes = cuddZddGetNode( dd, 2*bFR->index, z1, zRes0 );
1246 if ( zRes == NULL )
1247 {
1248 Cudd_RecursiveDerefZdd(dd, zRes0);
1249 return NULL;
1250 }
1251 cuddDeref( zRes0 );
1252 }
1253 else
1254 {
1255 zPos0 = extraBddSpaceEquationsNeg( dd, bF0 );
1256 if ( zPos0 == NULL )
1257 return NULL;
1258 cuddRef( zPos0 );
1259
1260 zPos1 = extraBddSpaceEquationsNeg( dd, bF1 );
1261 if ( zPos1 == NULL )
1262 {
1263 Cudd_RecursiveDerefZdd(dd, zPos0);
1264 return NULL;
1265 }
1266 cuddRef( zPos1 );
1267
1268 zNeg1 = extraBddSpaceEquationsPos( dd, bF1 );
1269 if ( zNeg1 == NULL )
1270 {
1271 Cudd_RecursiveDerefZdd(dd, zPos0);
1272 Cudd_RecursiveDerefZdd(dd, zPos1);
1273 return NULL;
1274 }
1275 cuddRef( zNeg1 );
1276
1277
1278 zRes0 = cuddZddIntersect( dd, zPos0, zPos1 );
1279 if ( zRes0 == NULL )
1280 {
1281 Cudd_RecursiveDerefZdd(dd, zNeg1);
1282 Cudd_RecursiveDerefZdd(dd, zPos0);
1283 Cudd_RecursiveDerefZdd(dd, zPos1);
1284 return NULL;
1285 }
1286 cuddRef( zRes0 );
1287
1288 zRes1 = cuddZddIntersect( dd, zPos0, zNeg1 );
1289 if ( zRes1 == NULL )
1290 {
1291 Cudd_RecursiveDerefZdd(dd, zRes0);
1292 Cudd_RecursiveDerefZdd(dd, zNeg1);
1293 Cudd_RecursiveDerefZdd(dd, zPos0);
1294 Cudd_RecursiveDerefZdd(dd, zPos1);
1295 return NULL;
1296 }
1297 cuddRef( zRes1 );
1298 Cudd_RecursiveDerefZdd(dd, zNeg1);
1299 Cudd_RecursiveDerefZdd(dd, zPos0);
1300 Cudd_RecursiveDerefZdd(dd, zPos1);
1301 // only zRes0 and zRes1 are refed at this point
1302
1303 zRes = cuddZddGetNode( dd, 2*bFR->index, zRes1, zRes0 );
1304 if ( zRes == NULL )
1305 {
1306 Cudd_RecursiveDerefZdd(dd, zRes0);
1307 Cudd_RecursiveDerefZdd(dd, zRes1);
1308 return NULL;
1309 }
1310 cuddDeref( zRes0 );
1311 cuddDeref( zRes1 );
1312 }
1313
1314 cuddCacheInsert1( dd, extraBddSpaceEquationsNeg, bF, zRes );
1315 return zRes;
1316 }
1317}
DdNode * extraBddSpaceEquationsNeg(DdManager *dd, DdNode *bSpace)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraBddSpaceEquationsPos()

DdNode * extraBddSpaceEquationsPos ( DdManager * dd,
DdNode * bF )
extern

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

Synopsis [Performs the recursive step of Extra_bddSpaceEquationsPos().]

Description []

SideEffects []

SeeAlso []

Definition at line 1071 of file extraBddAuto.c.

1072{
1073 DdNode * zRes;
1074 statLine( dd );
1075
1076 if ( bF == b0 )
1077 return z1;
1078 if ( bF == b1 )
1079 return z0;
1080
1081 if ( (zRes = cuddCacheLookup1Zdd(dd, extraBddSpaceEquationsPos, bF)) )
1082 return zRes;
1083 else
1084 {
1085 DdNode * bFR, * bF0, * bF1;
1086 DdNode * zPos0, * zPos1, * zNeg1;
1087 DdNode * zRes, * zRes0, * zRes1;
1088
1089 bFR = Cudd_Regular(bF);
1090 if ( bFR != bF ) // bF is complemented
1091 {
1092 bF0 = Cudd_Not( cuddE(bFR) );
1093 bF1 = Cudd_Not( cuddT(bFR) );
1094 }
1095 else
1096 {
1097 bF0 = cuddE(bFR);
1098 bF1 = cuddT(bFR);
1099 }
1100
1101 if ( bF0 == b0 )
1102 {
1103 zRes1 = extraBddSpaceEquationsPos( dd, bF1 );
1104 if ( zRes1 == NULL )
1105 return NULL;
1106 cuddRef( zRes1 );
1107
1108 // add the current element to the set
1109 zRes = cuddZddGetNode( dd, 2*bFR->index, z1, zRes1 );
1110 if ( zRes == NULL )
1111 {
1112 Cudd_RecursiveDerefZdd(dd, zRes1);
1113 return NULL;
1114 }
1115 cuddDeref( zRes1 );
1116 }
1117 else if ( bF1 == b0 )
1118 {
1119 zRes = extraBddSpaceEquationsPos( dd, bF0 );
1120 if ( zRes == NULL )
1121 return NULL;
1122 }
1123 else
1124 {
1125 zPos0 = extraBddSpaceEquationsPos( dd, bF0 );
1126 if ( zPos0 == NULL )
1127 return NULL;
1128 cuddRef( zPos0 );
1129
1130 zPos1 = extraBddSpaceEquationsPos( dd, bF1 );
1131 if ( zPos1 == NULL )
1132 {
1133 Cudd_RecursiveDerefZdd(dd, zPos0);
1134 return NULL;
1135 }
1136 cuddRef( zPos1 );
1137
1138 zNeg1 = extraBddSpaceEquationsNeg( dd, bF1 );
1139 if ( zNeg1 == NULL )
1140 {
1141 Cudd_RecursiveDerefZdd(dd, zPos0);
1142 Cudd_RecursiveDerefZdd(dd, zPos1);
1143 return NULL;
1144 }
1145 cuddRef( zNeg1 );
1146
1147
1148 zRes0 = cuddZddIntersect( dd, zPos0, zPos1 );
1149 if ( zRes0 == NULL )
1150 {
1151 Cudd_RecursiveDerefZdd(dd, zNeg1);
1152 Cudd_RecursiveDerefZdd(dd, zPos0);
1153 Cudd_RecursiveDerefZdd(dd, zPos1);
1154 return NULL;
1155 }
1156 cuddRef( zRes0 );
1157
1158 zRes1 = cuddZddIntersect( dd, zPos0, zNeg1 );
1159 if ( zRes1 == NULL )
1160 {
1161 Cudd_RecursiveDerefZdd(dd, zRes0);
1162 Cudd_RecursiveDerefZdd(dd, zNeg1);
1163 Cudd_RecursiveDerefZdd(dd, zPos0);
1164 Cudd_RecursiveDerefZdd(dd, zPos1);
1165 return NULL;
1166 }
1167 cuddRef( zRes1 );
1168 Cudd_RecursiveDerefZdd(dd, zNeg1);
1169 Cudd_RecursiveDerefZdd(dd, zPos0);
1170 Cudd_RecursiveDerefZdd(dd, zPos1);
1171 // only zRes0 and zRes1 are refed at this point
1172
1173 zRes = cuddZddGetNode( dd, 2*bFR->index, zRes1, zRes0 );
1174 if ( zRes == NULL )
1175 {
1176 Cudd_RecursiveDerefZdd(dd, zRes0);
1177 Cudd_RecursiveDerefZdd(dd, zRes1);
1178 return NULL;
1179 }
1180 cuddDeref( zRes0 );
1181 cuddDeref( zRes1 );
1182 }
1183
1184 cuddCacheInsert1( dd, extraBddSpaceEquationsPos, bF, zRes );
1185 return zRes;
1186 }
1187}
DdNode * extraBddSpaceEquationsPos(DdManager *dd, DdNode *bSpace)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraBddSpaceFromFunction()

DdNode * extraBddSpaceFromFunction ( DdManager * dd,
DdNode * bF,
DdNode * bG )
extern

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

Synopsis [Performs the recursive steps of Extra_bddSpaceFromFunction.]

Description []

SideEffects []

SeeAlso []

Definition at line 562 of file extraBddAuto.c.

563{
564 DdNode * bRes;
565 DdNode * bFR, * bGR;
566
567 bFR = Cudd_Regular( bF );
568 bGR = Cudd_Regular( bG );
569 if ( cuddIsConstant(bFR) )
570 {
571 if ( bF == bG )
572 return b1;
573 else
574 return b0;
575 }
576 if ( cuddIsConstant(bGR) )
577 return b0;
578 // both bFunc and bCore are not constants
579
580 // the operation is commutative - normalize the problem
581 if ( (unsigned)(ABC_PTRUINT_T)bF > (unsigned)(ABC_PTRUINT_T)bG )
582 return extraBddSpaceFromFunction(dd, bG, bF);
583
584
585 if ( (bRes = cuddCacheLookup2(dd, extraBddSpaceFromFunction, bF, bG)) )
586 return bRes;
587 else
588 {
589 DdNode * bF0, * bF1;
590 DdNode * bG0, * bG1;
591 DdNode * bTemp1, * bTemp2;
592 DdNode * bRes0, * bRes1;
593 int LevelF, LevelG;
594 int index;
595
596 LevelF = dd->perm[bFR->index];
597 LevelG = dd->perm[bGR->index];
598 if ( LevelF <= LevelG )
599 {
600 index = dd->invperm[LevelF];
601 if ( bFR != bF )
602 {
603 bF0 = Cudd_Not( cuddE(bFR) );
604 bF1 = Cudd_Not( cuddT(bFR) );
605 }
606 else
607 {
608 bF0 = cuddE(bFR);
609 bF1 = cuddT(bFR);
610 }
611 }
612 else
613 {
614 index = dd->invperm[LevelG];
615 bF0 = bF1 = bF;
616 }
617
618 if ( LevelG <= LevelF )
619 {
620 if ( bGR != bG )
621 {
622 bG0 = Cudd_Not( cuddE(bGR) );
623 bG1 = Cudd_Not( cuddT(bGR) );
624 }
625 else
626 {
627 bG0 = cuddE(bGR);
628 bG1 = cuddT(bGR);
629 }
630 }
631 else
632 bG0 = bG1 = bG;
633
634 bTemp1 = extraBddSpaceFromFunction( dd, bF0, bG0 );
635 if ( bTemp1 == NULL )
636 return NULL;
637 cuddRef( bTemp1 );
638
639 bTemp2 = extraBddSpaceFromFunction( dd, bF1, bG1 );
640 if ( bTemp2 == NULL )
641 {
642 Cudd_RecursiveDeref( dd, bTemp1 );
643 return NULL;
644 }
645 cuddRef( bTemp2 );
646
647
648 bRes0 = cuddBddAndRecur( dd, bTemp1, bTemp2 );
649 if ( bRes0 == NULL )
650 {
651 Cudd_RecursiveDeref( dd, bTemp1 );
652 Cudd_RecursiveDeref( dd, bTemp2 );
653 return NULL;
654 }
655 cuddRef( bRes0 );
656 Cudd_RecursiveDeref( dd, bTemp1 );
657 Cudd_RecursiveDeref( dd, bTemp2 );
658
659
660 bTemp1 = extraBddSpaceFromFunction( dd, bF0, bG1 );
661 if ( bTemp1 == NULL )
662 {
663 Cudd_RecursiveDeref( dd, bRes0 );
664 return NULL;
665 }
666 cuddRef( bTemp1 );
667
668 bTemp2 = extraBddSpaceFromFunction( dd, bF1, bG0 );
669 if ( bTemp2 == NULL )
670 {
671 Cudd_RecursiveDeref( dd, bRes0 );
672 Cudd_RecursiveDeref( dd, bTemp1 );
673 return NULL;
674 }
675 cuddRef( bTemp2 );
676
677 bRes1 = cuddBddAndRecur( dd, bTemp1, bTemp2 );
678 if ( bRes1 == NULL )
679 {
680 Cudd_RecursiveDeref( dd, bRes0 );
681 Cudd_RecursiveDeref( dd, bTemp1 );
682 Cudd_RecursiveDeref( dd, bTemp2 );
683 return NULL;
684 }
685 cuddRef( bRes1 );
686 Cudd_RecursiveDeref( dd, bTemp1 );
687 Cudd_RecursiveDeref( dd, bTemp2 );
688
689
690
691 // consider the case when Res0 and Res1 are the same node
692 if ( bRes0 == bRes1 )
693 bRes = bRes1;
694 // consider the case when Res1 is complemented
695 else if ( Cudd_IsComplement(bRes1) )
696 {
697 bRes = cuddUniqueInter(dd, index, Cudd_Not(bRes1), Cudd_Not(bRes0));
698 if ( bRes == NULL )
699 {
700 Cudd_RecursiveDeref(dd,bRes0);
701 Cudd_RecursiveDeref(dd,bRes1);
702 return NULL;
703 }
704 bRes = Cudd_Not(bRes);
705 }
706 else
707 {
708 bRes = cuddUniqueInter( dd, index, bRes1, bRes0 );
709 if ( bRes == NULL )
710 {
711 Cudd_RecursiveDeref(dd,bRes0);
712 Cudd_RecursiveDeref(dd,bRes1);
713 return NULL;
714 }
715 }
716 cuddDeref( bRes0 );
717 cuddDeref( bRes1 );
718
719 // insert the result into cache
720 cuddCacheInsert2(dd, extraBddSpaceFromFunction, bF, bG, bRes);
721 return bRes;
722 }
723} /* end of extraBddSpaceFromFunction */
DdNode * extraBddSpaceFromFunction(DdManager *dd, DdNode *bF, DdNode *bG)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraBddSpaceFromFunctionNeg()

DdNode * extraBddSpaceFromFunctionNeg ( DdManager * dd,
DdNode * bF )
extern

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

Synopsis [Performs the recursive step of Extra_bddSpaceFromFunctionPos().]

Description []

SideEffects []

SeeAlso []

Definition at line 869 of file extraBddAuto.c.

870{
871 DdNode * bRes, * bFR;
872 statLine( dd );
873
874 bFR = Cudd_Regular(bF);
875 if ( cuddIsConstant(bFR) )
876 return b0;
877
878 if ( (bRes = cuddCacheLookup1(dd, extraBddSpaceFromFunctionNeg, bF)) )
879 return bRes;
880 else
881 {
882 DdNode * bF0, * bF1;
883 DdNode * bPos0, * bPos1;
884 DdNode * bNeg0, * bNeg1;
885 DdNode * bRes0, * bRes1;
886
887 if ( bFR != bF ) // bF is complemented
888 {
889 bF0 = Cudd_Not( cuddE(bFR) );
890 bF1 = Cudd_Not( cuddT(bFR) );
891 }
892 else
893 {
894 bF0 = cuddE(bFR);
895 bF1 = cuddT(bFR);
896 }
897
898
899 bPos0 = extraBddSpaceFromFunctionNeg( dd, bF0 );
900 if ( bPos0 == NULL )
901 return NULL;
902 cuddRef( bPos0 );
903
904 bPos1 = extraBddSpaceFromFunctionNeg( dd, bF1 );
905 if ( bPos1 == NULL )
906 {
907 Cudd_RecursiveDeref( dd, bPos0 );
908 return NULL;
909 }
910 cuddRef( bPos1 );
911
912 bRes0 = cuddBddAndRecur( dd, bPos0, bPos1 );
913 if ( bRes0 == NULL )
914 {
915 Cudd_RecursiveDeref( dd, bPos0 );
916 Cudd_RecursiveDeref( dd, bPos1 );
917 return NULL;
918 }
919 cuddRef( bRes0 );
920 Cudd_RecursiveDeref( dd, bPos0 );
921 Cudd_RecursiveDeref( dd, bPos1 );
922
923
924 bNeg0 = extraBddSpaceFromFunctionPos( dd, bF0 );
925 if ( bNeg0 == NULL )
926 {
927 Cudd_RecursiveDeref( dd, bRes0 );
928 return NULL;
929 }
930 cuddRef( bNeg0 );
931
932 bNeg1 = extraBddSpaceFromFunctionPos( dd, bF1 );
933 if ( bNeg1 == NULL )
934 {
935 Cudd_RecursiveDeref( dd, bRes0 );
936 Cudd_RecursiveDeref( dd, bNeg0 );
937 return NULL;
938 }
939 cuddRef( bNeg1 );
940
941 bRes1 = cuddBddAndRecur( dd, bNeg0, bNeg1 );
942 if ( bRes1 == NULL )
943 {
944 Cudd_RecursiveDeref( dd, bRes0 );
945 Cudd_RecursiveDeref( dd, bNeg0 );
946 Cudd_RecursiveDeref( dd, bNeg1 );
947 return NULL;
948 }
949 cuddRef( bRes1 );
950 Cudd_RecursiveDeref( dd, bNeg0 );
951 Cudd_RecursiveDeref( dd, bNeg1 );
952
953
954 // consider the case when Res0 and Res1 are the same node
955 if ( bRes0 == bRes1 )
956 bRes = bRes1;
957 // consider the case when Res1 is complemented
958 else if ( Cudd_IsComplement(bRes1) )
959 {
960 bRes = cuddUniqueInter( dd, bFR->index, Cudd_Not(bRes1), Cudd_Not(bRes0) );
961 if ( bRes == NULL )
962 {
963 Cudd_RecursiveDeref(dd,bRes0);
964 Cudd_RecursiveDeref(dd,bRes1);
965 return NULL;
966 }
967 bRes = Cudd_Not(bRes);
968 }
969 else
970 {
971 bRes = cuddUniqueInter( dd, bFR->index, bRes1, bRes0 );
972 if ( bRes == NULL )
973 {
974 Cudd_RecursiveDeref(dd,bRes0);
975 Cudd_RecursiveDeref(dd,bRes1);
976 return NULL;
977 }
978 }
979 cuddDeref( bRes0 );
980 cuddDeref( bRes1 );
981
982 cuddCacheInsert1( dd, extraBddSpaceFromFunctionNeg, bF, bRes );
983 return bRes;
984 }
985}
DdNode * extraBddSpaceFromFunctionNeg(DdManager *dd, DdNode *bFunc)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraBddSpaceFromFunctionPos()

DdNode * extraBddSpaceFromFunctionPos ( DdManager * dd,
DdNode * bF )
extern

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

Synopsis [Performs the recursive step of Extra_bddSpaceFromFunctionPos().]

Description []

SideEffects []

SeeAlso []

Definition at line 738 of file extraBddAuto.c.

739{
740 DdNode * bRes, * bFR;
741 statLine( dd );
742
743 bFR = Cudd_Regular(bF);
744 if ( cuddIsConstant(bFR) )
745 return b1;
746
747 if ( (bRes = cuddCacheLookup1(dd, extraBddSpaceFromFunctionPos, bF)) )
748 return bRes;
749 else
750 {
751 DdNode * bF0, * bF1;
752 DdNode * bPos0, * bPos1;
753 DdNode * bNeg0, * bNeg1;
754 DdNode * bRes0, * bRes1;
755
756 if ( bFR != bF ) // bF is complemented
757 {
758 bF0 = Cudd_Not( cuddE(bFR) );
759 bF1 = Cudd_Not( cuddT(bFR) );
760 }
761 else
762 {
763 bF0 = cuddE(bFR);
764 bF1 = cuddT(bFR);
765 }
766
767
768 bPos0 = extraBddSpaceFromFunctionPos( dd, bF0 );
769 if ( bPos0 == NULL )
770 return NULL;
771 cuddRef( bPos0 );
772
773 bPos1 = extraBddSpaceFromFunctionPos( dd, bF1 );
774 if ( bPos1 == NULL )
775 {
776 Cudd_RecursiveDeref( dd, bPos0 );
777 return NULL;
778 }
779 cuddRef( bPos1 );
780
781 bRes0 = cuddBddAndRecur( dd, bPos0, bPos1 );
782 if ( bRes0 == NULL )
783 {
784 Cudd_RecursiveDeref( dd, bPos0 );
785 Cudd_RecursiveDeref( dd, bPos1 );
786 return NULL;
787 }
788 cuddRef( bRes0 );
789 Cudd_RecursiveDeref( dd, bPos0 );
790 Cudd_RecursiveDeref( dd, bPos1 );
791
792
793 bNeg0 = extraBddSpaceFromFunctionNeg( dd, bF0 );
794 if ( bNeg0 == NULL )
795 {
796 Cudd_RecursiveDeref( dd, bRes0 );
797 return NULL;
798 }
799 cuddRef( bNeg0 );
800
801 bNeg1 = extraBddSpaceFromFunctionNeg( dd, bF1 );
802 if ( bNeg1 == NULL )
803 {
804 Cudd_RecursiveDeref( dd, bRes0 );
805 Cudd_RecursiveDeref( dd, bNeg0 );
806 return NULL;
807 }
808 cuddRef( bNeg1 );
809
810 bRes1 = cuddBddAndRecur( dd, bNeg0, bNeg1 );
811 if ( bRes1 == NULL )
812 {
813 Cudd_RecursiveDeref( dd, bRes0 );
814 Cudd_RecursiveDeref( dd, bNeg0 );
815 Cudd_RecursiveDeref( dd, bNeg1 );
816 return NULL;
817 }
818 cuddRef( bRes1 );
819 Cudd_RecursiveDeref( dd, bNeg0 );
820 Cudd_RecursiveDeref( dd, bNeg1 );
821
822
823 // consider the case when Res0 and Res1 are the same node
824 if ( bRes0 == bRes1 )
825 bRes = bRes1;
826 // consider the case when Res1 is complemented
827 else if ( Cudd_IsComplement(bRes1) )
828 {
829 bRes = cuddUniqueInter( dd, bFR->index, Cudd_Not(bRes1), Cudd_Not(bRes0) );
830 if ( bRes == NULL )
831 {
832 Cudd_RecursiveDeref(dd,bRes0);
833 Cudd_RecursiveDeref(dd,bRes1);
834 return NULL;
835 }
836 bRes = Cudd_Not(bRes);
837 }
838 else
839 {
840 bRes = cuddUniqueInter( dd, bFR->index, bRes1, bRes0 );
841 if ( bRes == NULL )
842 {
843 Cudd_RecursiveDeref(dd,bRes0);
844 Cudd_RecursiveDeref(dd,bRes1);
845 return NULL;
846 }
847 }
848 cuddDeref( bRes0 );
849 cuddDeref( bRes1 );
850
851 cuddCacheInsert1( dd, extraBddSpaceFromFunctionPos, bF, bRes );
852 return bRes;
853 }
854}
DdNode * extraBddSpaceFromFunctionPos(DdManager *dd, DdNode *bFunc)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraBddSpaceFromMatrixNeg()

DdNode * extraBddSpaceFromMatrixNeg ( DdManager * dd,
DdNode * zA )
extern

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

Synopsis [Performs the recursive step of Extra_bddSpaceFromFunctionPos().]

Description []

SideEffects []

SeeAlso []

Definition at line 1451 of file extraBddAuto.c.

1452{
1453 DdNode * bRes;
1454 statLine( dd );
1455
1456 if ( zA == z0 )
1457 return b1;
1458 if ( zA == z1 )
1459 return b0;
1460
1461 if ( (bRes = cuddCacheLookup1(dd, extraBddSpaceFromMatrixNeg, zA)) )
1462 return bRes;
1463 else
1464 {
1465 DdNode * bP0, * bP1;
1466 DdNode * bN0, * bN1;
1467 DdNode * bRes0, * bRes1;
1468
1469 bP0 = extraBddSpaceFromMatrixNeg( dd, cuddE(zA) );
1470 if ( bP0 == NULL )
1471 return NULL;
1472 cuddRef( bP0 );
1473
1474 bP1 = extraBddSpaceFromMatrixNeg( dd, cuddT(zA) );
1475 if ( bP1 == NULL )
1476 {
1477 Cudd_RecursiveDeref( dd, bP0 );
1478 return NULL;
1479 }
1480 cuddRef( bP1 );
1481
1482 bRes0 = cuddBddAndRecur( dd, bP0, bP1 );
1483 if ( bRes0 == NULL )
1484 {
1485 Cudd_RecursiveDeref( dd, bP0 );
1486 Cudd_RecursiveDeref( dd, bP1 );
1487 return NULL;
1488 }
1489 cuddRef( bRes0 );
1490 Cudd_RecursiveDeref( dd, bP0 );
1491 Cudd_RecursiveDeref( dd, bP1 );
1492
1493
1494 bN0 = extraBddSpaceFromMatrixNeg( dd, cuddE(zA) );
1495 if ( bN0 == NULL )
1496 {
1497 Cudd_RecursiveDeref( dd, bRes0 );
1498 return NULL;
1499 }
1500 cuddRef( bN0 );
1501
1502 bN1 = extraBddSpaceFromMatrixPos( dd, cuddT(zA) );
1503 if ( bN1 == NULL )
1504 {
1505 Cudd_RecursiveDeref( dd, bRes0 );
1506 Cudd_RecursiveDeref( dd, bN0 );
1507 return NULL;
1508 }
1509 cuddRef( bN1 );
1510
1511 bRes1 = cuddBddAndRecur( dd, bN0, bN1 );
1512 if ( bRes1 == NULL )
1513 {
1514 Cudd_RecursiveDeref( dd, bRes0 );
1515 Cudd_RecursiveDeref( dd, bN0 );
1516 Cudd_RecursiveDeref( dd, bN1 );
1517 return NULL;
1518 }
1519 cuddRef( bRes1 );
1520 Cudd_RecursiveDeref( dd, bN0 );
1521 Cudd_RecursiveDeref( dd, bN1 );
1522
1523
1524 // consider the case when Res0 and Res1 are the same node
1525 if ( bRes0 == bRes1 )
1526 bRes = bRes1;
1527 // consider the case when Res1 is complemented
1528 else if ( Cudd_IsComplement(bRes1) )
1529 {
1530 bRes = cuddUniqueInter( dd, zA->index/2, Cudd_Not(bRes1), Cudd_Not(bRes0) );
1531 if ( bRes == NULL )
1532 {
1533 Cudd_RecursiveDeref(dd,bRes0);
1534 Cudd_RecursiveDeref(dd,bRes1);
1535 return NULL;
1536 }
1537 bRes = Cudd_Not(bRes);
1538 }
1539 else
1540 {
1541 bRes = cuddUniqueInter( dd, zA->index/2, bRes1, bRes0 );
1542 if ( bRes == NULL )
1543 {
1544 Cudd_RecursiveDeref(dd,bRes0);
1545 Cudd_RecursiveDeref(dd,bRes1);
1546 return NULL;
1547 }
1548 }
1549 cuddDeref( bRes0 );
1550 cuddDeref( bRes1 );
1551
1552 cuddCacheInsert1( dd, extraBddSpaceFromMatrixNeg, zA, bRes );
1553 return bRes;
1554 }
1555}
DdNode * extraBddSpaceFromMatrixNeg(DdManager *dd, DdNode *zA)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraBddSpaceFromMatrixPos()

DdNode * extraBddSpaceFromMatrixPos ( DdManager * dd,
DdNode * zA )
extern

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

Synopsis [Performs the recursive step of Extra_bddSpaceFromFunctionPos().]

Description []

SideEffects []

SeeAlso []

Definition at line 1333 of file extraBddAuto.c.

1334{
1335 DdNode * bRes;
1336 statLine( dd );
1337
1338 if ( zA == z0 )
1339 return b1;
1340 if ( zA == z1 )
1341 return b1;
1342
1343 if ( (bRes = cuddCacheLookup1(dd, extraBddSpaceFromMatrixPos, zA)) )
1344 return bRes;
1345 else
1346 {
1347 DdNode * bP0, * bP1;
1348 DdNode * bN0, * bN1;
1349 DdNode * bRes0, * bRes1;
1350
1351 bP0 = extraBddSpaceFromMatrixPos( dd, cuddE(zA) );
1352 if ( bP0 == NULL )
1353 return NULL;
1354 cuddRef( bP0 );
1355
1356 bP1 = extraBddSpaceFromMatrixPos( dd, cuddT(zA) );
1357 if ( bP1 == NULL )
1358 {
1359 Cudd_RecursiveDeref( dd, bP0 );
1360 return NULL;
1361 }
1362 cuddRef( bP1 );
1363
1364 bRes0 = cuddBddAndRecur( dd, bP0, bP1 );
1365 if ( bRes0 == NULL )
1366 {
1367 Cudd_RecursiveDeref( dd, bP0 );
1368 Cudd_RecursiveDeref( dd, bP1 );
1369 return NULL;
1370 }
1371 cuddRef( bRes0 );
1372 Cudd_RecursiveDeref( dd, bP0 );
1373 Cudd_RecursiveDeref( dd, bP1 );
1374
1375
1376 bN0 = extraBddSpaceFromMatrixPos( dd, cuddE(zA) );
1377 if ( bN0 == NULL )
1378 {
1379 Cudd_RecursiveDeref( dd, bRes0 );
1380 return NULL;
1381 }
1382 cuddRef( bN0 );
1383
1384 bN1 = extraBddSpaceFromMatrixNeg( dd, cuddT(zA) );
1385 if ( bN1 == NULL )
1386 {
1387 Cudd_RecursiveDeref( dd, bRes0 );
1388 Cudd_RecursiveDeref( dd, bN0 );
1389 return NULL;
1390 }
1391 cuddRef( bN1 );
1392
1393 bRes1 = cuddBddAndRecur( dd, bN0, bN1 );
1394 if ( bRes1 == NULL )
1395 {
1396 Cudd_RecursiveDeref( dd, bRes0 );
1397 Cudd_RecursiveDeref( dd, bN0 );
1398 Cudd_RecursiveDeref( dd, bN1 );
1399 return NULL;
1400 }
1401 cuddRef( bRes1 );
1402 Cudd_RecursiveDeref( dd, bN0 );
1403 Cudd_RecursiveDeref( dd, bN1 );
1404
1405
1406 // consider the case when Res0 and Res1 are the same node
1407 if ( bRes0 == bRes1 )
1408 bRes = bRes1;
1409 // consider the case when Res1 is complemented
1410 else if ( Cudd_IsComplement(bRes1) )
1411 {
1412 bRes = cuddUniqueInter( dd, zA->index/2, Cudd_Not(bRes1), Cudd_Not(bRes0) );
1413 if ( bRes == NULL )
1414 {
1415 Cudd_RecursiveDeref(dd,bRes0);
1416 Cudd_RecursiveDeref(dd,bRes1);
1417 return NULL;
1418 }
1419 bRes = Cudd_Not(bRes);
1420 }
1421 else
1422 {
1423 bRes = cuddUniqueInter( dd, zA->index/2, bRes1, bRes0 );
1424 if ( bRes == NULL )
1425 {
1426 Cudd_RecursiveDeref(dd,bRes0);
1427 Cudd_RecursiveDeref(dd,bRes1);
1428 return NULL;
1429 }
1430 }
1431 cuddDeref( bRes0 );
1432 cuddDeref( bRes1 );
1433
1434 cuddCacheInsert1( dd, extraBddSpaceFromMatrixPos, zA, bRes );
1435 return bRes;
1436 }
1437}
DdNode * extraBddSpaceFromMatrixPos(DdManager *dd, DdNode *zA)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraBddTuples()

DdNode * extraBddTuples ( DdManager * dd,
DdNode * bVarsK,
DdNode * bVarsN )
extern

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

Synopsis [Performs the reordering-sensitive step of Extra_bddTuples().]

Description [Generates in a bottom-up fashion BDD for all combinations composed of k variables out of variables belonging to bVarsN.]

SideEffects []

SeeAlso []

Definition at line 2597 of file extraBddMisc.c.

2601{
2602 DdNode *bRes, *bRes0, *bRes1;
2603 statLine(dd);
2604
2605 /* terminal cases */
2606/* if ( k < 0 || k > n )
2607 * return dd->zero;
2608 * if ( n == 0 )
2609 * return dd->one;
2610 */
2611 if ( cuddI( dd, bVarsK->index ) < cuddI( dd, bVarsN->index ) )
2612 return b0;
2613 if ( bVarsN == b1 )
2614 return b1;
2615
2616 /* check cache */
2617 bRes = cuddCacheLookup2(dd, extraBddTuples, bVarsK, bVarsN);
2618 if (bRes)
2619 return(bRes);
2620
2621 /* ZDD in which is variable is 0 */
2622/* bRes0 = extraBddTuples( dd, k, n-1 ); */
2623 bRes0 = extraBddTuples( dd, bVarsK, cuddT(bVarsN) );
2624 if ( bRes0 == NULL )
2625 return NULL;
2626 cuddRef( bRes0 );
2627
2628 /* ZDD in which is variable is 1 */
2629/* bRes1 = extraBddTuples( dd, k-1, n-1 ); */
2630 if ( bVarsK == b1 )
2631 {
2632 bRes1 = b0;
2633 cuddRef( bRes1 );
2634 }
2635 else
2636 {
2637 bRes1 = extraBddTuples( dd, cuddT(bVarsK), cuddT(bVarsN) );
2638 if ( bRes1 == NULL )
2639 {
2640 Cudd_RecursiveDeref( dd, bRes0 );
2641 return NULL;
2642 }
2643 cuddRef( bRes1 );
2644 }
2645
2646 /* consider the case when Res0 and Res1 are the same node */
2647 if ( bRes0 == bRes1 )
2648 bRes = bRes1;
2649 /* consider the case when Res1 is complemented */
2650 else if ( Cudd_IsComplement(bRes1) )
2651 {
2652 bRes = cuddUniqueInter(dd, bVarsN->index, Cudd_Not(bRes1), Cudd_Not(bRes0));
2653 if ( bRes == NULL )
2654 {
2655 Cudd_RecursiveDeref(dd,bRes0);
2656 Cudd_RecursiveDeref(dd,bRes1);
2657 return NULL;
2658 }
2659 bRes = Cudd_Not(bRes);
2660 }
2661 else
2662 {
2663 bRes = cuddUniqueInter( dd, bVarsN->index, bRes1, bRes0 );
2664 if ( bRes == NULL )
2665 {
2666 Cudd_RecursiveDeref(dd,bRes0);
2667 Cudd_RecursiveDeref(dd,bRes1);
2668 return NULL;
2669 }
2670 }
2671 cuddDeref( bRes0 );
2672 cuddDeref( bRes1 );
2673
2674 /* insert the result into cache */
2675 cuddCacheInsert2(dd, extraBddTuples, bVarsK, bVarsN, bRes);
2676 return bRes;
2677
2678} /* end of extraBddTuples */
DdNode * extraBddTuples(DdManager *dd, DdNode *bVarsK, DdNode *bVarsN)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraDecomposeCover()

void extraDecomposeCover ( DdManager * dd,
DdNode * zC,
DdNode ** zC0,
DdNode ** zC1,
DdNode ** zC2 )
extern

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

Synopsis [Finds three cofactors of the cover w.r.t. to the topmost variable.]

Description [Finds three cofactors of the cover w.r.t. to the topmost variable. Does not check the cover for being a constant. Assumes that ZDD variables encoding positive and negative polarities are adjacent in the variable order. Is different from cuddZddGetCofactors3() in that it does not compute the cofactors w.r.t. the given variable but takes the cofactors with respent to the topmost variable. This function is more efficient when used in recursive procedures because it does not require referencing of the resulting cofactors (compare cuddZddProduct() and extraZddPrimeProduct()).]

SideEffects [None]

SeeAlso [cuddZddGetCofactors3]

Definition at line 1217 of file extraBddMisc.c.

1223{
1224 if ( (zC->index & 1) == 0 )
1225 { /* the top variable is present in positive polarity and maybe in negative */
1226
1227 DdNode *Temp = cuddE( zC );
1228 *zC1 = cuddT( zC );
1229 if ( cuddIZ(dd,Temp->index) == cuddIZ(dd,zC->index) + 1 )
1230 { /* Temp is not a terminal node
1231 * top var is present in negative polarity */
1232 *zC2 = cuddE( Temp );
1233 *zC0 = cuddT( Temp );
1234 }
1235 else
1236 { /* top var is not present in negative polarity */
1237 *zC2 = Temp;
1238 *zC0 = dd->zero;
1239 }
1240 }
1241 else
1242 { /* the top variable is present only in negative */
1243 *zC1 = dd->zero;
1244 *zC2 = cuddE( zC );
1245 *zC0 = cuddT( zC );
1246 }
1247} /* extraDecomposeCover */

◆ extraZddCrossProduct()

DdNode * extraZddCrossProduct ( DdManager * dd,
DdNode * S,
DdNode * T )
extern

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

Synopsis [Performs the recursive step of Extra_zddCrossProduct.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 799 of file extraBddMaxMin.c.

803{
804 DdNode *zRes;
805 int TopS, TopT;
806 statLine(dd);
807
808 /* consider terminal cases */
809 if ( S == z0 || T == z0 )
810 return z0;
811 if ( S == z1 || T == z1 )
812 return z1;
813
814 /* the operation is commutative - normalize the problem */
815 TopS = dd->permZ[S->index];
816 TopT = dd->permZ[T->index];
817
818 if ( TopS > TopT || (TopS == TopT && S > T) )
819 return extraZddCrossProduct(dd, T, S);
820
821 /* check cache */
822 zRes = cuddCacheLookup2Zdd(dd, extraZddCrossProduct, S, T);
823 if (zRes)
824 return zRes;
825 else
826 {
827 DdNode *zSet0, *zSet1, *zRes0, *zRes1, *zTemp;
828
829 if ( TopS == TopT )
830 {
831 /* compute the union of two cofactors of T (T0+T1) */
832 zTemp = cuddZddUnion(dd, cuddE(T), cuddT(T) );
833 if ( zTemp == NULL )
834 return NULL;
835 cuddRef( zTemp );
836
837 /* compute CrossProduct without the top element for subsets (S0, T0+T1) */
838 zSet0 = extraZddCrossProduct(dd, cuddE(S), zTemp );
839 if ( zSet0 == NULL )
840 {
841 Cudd_RecursiveDerefZdd(dd, zTemp);
842 return NULL;
843 }
844 cuddRef( zSet0 );
845 Cudd_RecursiveDerefZdd(dd, zTemp);
846
847 /* compute CrossProduct without the top element for subsets (S1, T0) */
848 zSet1 = extraZddCrossProduct(dd, cuddT(S), cuddE(T) );
849 if ( zSet1 == NULL )
850 {
851 Cudd_RecursiveDerefZdd(dd, zSet0);
852 return NULL;
853 }
854 cuddRef( zSet1 );
855
856 /* compute the union of these two partial results (zSet0 + zSet1) */
857 zRes0 = cuddZddUnion(dd, zSet0, zSet1 );
858 if ( zRes0 == NULL )
859 {
860 Cudd_RecursiveDerefZdd(dd, zSet0);
861 Cudd_RecursiveDerefZdd(dd, zSet1);
862 return NULL;
863 }
864 cuddRef( zRes0 );
865 Cudd_RecursiveDerefZdd(dd, zSet0);
866 Cudd_RecursiveDerefZdd(dd, zSet1);
867
868 /* compute CrossProduct for subsets with the top-most element */
869 zRes1 = extraZddCrossProduct(dd, cuddT(S), cuddT(T) );
870 if ( zRes1 == NULL )
871 {
872 Cudd_RecursiveDerefZdd(dd, zRes0);
873 return NULL;
874 }
875 cuddRef( zRes1 );
876
877 /* create the new node */
878 zRes = cuddZddGetNode( dd, S->index, zRes1, zRes0 );
879 if ( zRes == NULL )
880 {
881 Cudd_RecursiveDerefZdd( dd, zRes0 );
882 Cudd_RecursiveDerefZdd( dd, zRes1 );
883 return NULL;
884 }
885 cuddDeref( zRes0 );
886 cuddDeref( zRes1 );
887 }
888 else /* if ( TopS < TopT ) */
889 {
890 /* compute CrossProduct without the top element (S0, T) */
891 zSet0 = extraZddCrossProduct(dd, cuddE(S), T );
892 if ( zSet0 == NULL )
893 return NULL;
894 cuddRef( zSet0 );
895
896 /* compute CrossProduct without the top element (S1, T) */
897 zSet1 = extraZddCrossProduct(dd, cuddT(S), T );
898 if ( zSet1 == NULL )
899 {
900 Cudd_RecursiveDerefZdd(dd, zSet0);
901 return NULL;
902 }
903 cuddRef( zSet1 );
904
905 /* compute the union of these two partial results (zSet0 + zSet1) */
906 zRes = cuddZddUnion(dd, zSet0, zSet1 );
907 if ( zRes == NULL )
908 {
909 Cudd_RecursiveDerefZdd(dd, zSet0);
910 Cudd_RecursiveDerefZdd(dd, zSet1);
911 return NULL;
912 }
913 cuddRef( zRes );
914 Cudd_RecursiveDerefZdd(dd, zSet0);
915 Cudd_RecursiveDerefZdd(dd, zSet1);
916 cuddDeref( zRes );
917 }
918
919 /* insert the result into cache */
920 cuddCacheInsert2(dd, extraZddCrossProduct, S, T, zRes);
921 return zRes;
922 }
923} /* end of extraZddCrossProduct */
DdNode * extraZddCrossProduct(DdManager *dd, DdNode *S, DdNode *T)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraZddDotProduct()

DdNode * extraZddDotProduct ( DdManager * dd,
DdNode * S,
DdNode * T )
extern

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

Synopsis [Performs the recursive step of Extra_zddDotProduct.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 672 of file extraBddMaxMin.c.

676{
677 DdNode *zRes;
678 int TopS, TopT;
679 statLine(dd);
680
681 /* consider terminal cases */
682 if ( S == z0 || T == z0 )
683 return z0;
684 if ( S == z1 )
685 return T;
686 if ( T == z1 )
687 return S;
688
689 /* the operation is commutative - normalize the problem */
690 TopS = dd->permZ[S->index];
691 TopT = dd->permZ[T->index];
692
693 if ( TopS > TopT || (TopS == TopT && S > T) )
694 return extraZddDotProduct(dd, T, S);
695
696 /* check cache */
697 zRes = cuddCacheLookup2Zdd(dd, extraZddDotProduct, S, T);
698 if (zRes)
699 return zRes;
700 else
701 {
702 DdNode *zSet0, *zSet1, *zRes0, *zRes1, *zTemp;
703 if ( TopS == TopT )
704 {
705 /* compute the union of two cofactors of T (T0+T1) */
706 zTemp = cuddZddUnion(dd, cuddE(T), cuddT(T) );
707 if ( zTemp == NULL )
708 return NULL;
709 cuddRef( zTemp );
710
711 /* compute DotProduct with the top element for subsets (S1, T0+T1) */
712 zSet0 = extraZddDotProduct(dd, cuddT(S), zTemp );
713 if ( zSet0 == NULL )
714 {
715 Cudd_RecursiveDerefZdd(dd, zTemp);
716 return NULL;
717 }
718 cuddRef( zSet0 );
719 Cudd_RecursiveDerefZdd(dd, zTemp);
720
721 /* compute DotProduct with the top element for subsets (S0, T1) */
722 zSet1 = extraZddDotProduct(dd, cuddE(S), cuddT(T) );
723 if ( zSet1 == NULL )
724 {
725 Cudd_RecursiveDerefZdd(dd, zSet0);
726 return NULL;
727 }
728 cuddRef( zSet1 );
729
730 /* compute the union of these two partial results (zSet0 + zSet1) */
731 zRes1 = cuddZddUnion(dd, zSet0, zSet1 );
732 if ( zRes1 == NULL )
733 {
734 Cudd_RecursiveDerefZdd(dd, zSet0);
735 Cudd_RecursiveDerefZdd(dd, zSet1);
736 return NULL;
737 }
738 cuddRef( zRes1 );
739 Cudd_RecursiveDerefZdd(dd, zSet0);
740 Cudd_RecursiveDerefZdd(dd, zSet1);
741
742 /* compute DotProduct for subsets without the top-most element */
743 zRes0 = extraZddDotProduct(dd, cuddE(S), cuddE(T) );
744 if ( zRes0 == NULL )
745 {
746 Cudd_RecursiveDerefZdd(dd, zRes1);
747 return NULL;
748 }
749 cuddRef( zRes0 );
750 }
751 else /* if ( TopS < TopT ) */
752 {
753 /* compute DotProduct with the top element for subsets (S1, T) */
754 zRes1 = extraZddDotProduct(dd, cuddT(S), T );
755 if ( zRes1 == NULL )
756 return NULL;
757 cuddRef( zRes1 );
758
759 /* compute DotProduct for subsets without the top-most element */
760 zRes0 = extraZddDotProduct(dd, cuddE(S), T );
761 if ( zRes0 == NULL )
762 {
763 Cudd_RecursiveDerefZdd(dd, zRes1);
764 return NULL;
765 }
766 cuddRef( zRes0 );
767 }
768
769 /* create the new node */
770 zRes = cuddZddGetNode( dd, S->index, zRes1, zRes0 );
771 if ( zRes == NULL )
772 {
773 Cudd_RecursiveDerefZdd( dd, zRes0 );
774 Cudd_RecursiveDerefZdd( dd, zRes1 );
775 return NULL;
776 }
777 cuddDeref( zRes0 );
778 cuddDeref( zRes1 );
779
780 /* insert the result into cache */
781 cuddCacheInsert2(dd, extraZddDotProduct, S, T, zRes);
782 return zRes;
783 }
784} /* end of extraZddDotProduct */
DdNode * extraZddDotProduct(DdManager *dd, DdNode *S, DdNode *T)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraZddGetSingletons()

DdNode * extraZddGetSingletons ( DdManager * dd,
DdNode * bVars )
extern

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

Synopsis [Performs a recursive step of Extra_zddGetSingletons.]

Description [Returns the set of ZDD singletons, containing those positive polarity ZDD variables that correspond to the BDD variables in bVars.]

SideEffects []

SeeAlso []

Definition at line 1001 of file extraBddSymm.c.

1004{
1005 DdNode * zRes;
1006
1007 if ( bVars == b1 )
1008// if ( bVars == b0 ) // bug fixed by Jin Zhang, Jan 23, 2004
1009 return z1;
1010
1011 if ( (zRes = cuddCacheLookup1Zdd(dd, extraZddGetSingletons, bVars)) )
1012 return zRes;
1013 else
1014 {
1015 DdNode * zTemp, * zPlus;
1016
1017 // solve subproblem
1018 zRes = extraZddGetSingletons( dd, cuddT(bVars) );
1019 if ( zRes == NULL )
1020 return NULL;
1021 cuddRef( zRes );
1022
1023 zPlus = cuddZddGetNode( dd, 2*bVars->index, z1, z0 );
1024 if ( zPlus == NULL )
1025 {
1026 Cudd_RecursiveDerefZdd( dd, zRes );
1027 return NULL;
1028 }
1029 cuddRef( zPlus );
1030
1031 // add these to the result
1032 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
1033 if ( zRes == NULL )
1034 {
1035 Cudd_RecursiveDerefZdd( dd, zTemp );
1036 Cudd_RecursiveDerefZdd( dd, zPlus );
1037 return NULL;
1038 }
1039 cuddRef( zRes );
1040 Cudd_RecursiveDerefZdd( dd, zTemp );
1041 Cudd_RecursiveDerefZdd( dd, zPlus );
1042 cuddDeref( zRes );
1043
1044 cuddCacheInsert1( dd, extraZddGetSingletons, bVars, zRes );
1045 return zRes;
1046 }
1047} /* end of extraZddGetSingletons */
DdNode * extraZddGetSingletons(DdManager *dd, DdNode *bVars)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraZddGetSingletonsBoth()

DdNode * extraZddGetSingletonsBoth ( DdManager * dd,
DdNode * bVars )
extern

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

Synopsis [Performs a recursive step of Extra_zddGetSingletons.]

Description [Returns the set of ZDD singletons, containing those pos/neg polarity ZDD variables that correspond to the BDD variables in bVars.]

SideEffects []

SeeAlso []

Definition at line 570 of file extraBddUnate.c.

573{
574 DdNode * zRes;
575
576 if ( bVars == b1 )
577 return z1;
578
579 if ( (zRes = cuddCacheLookup1Zdd(dd, extraZddGetSingletonsBoth, bVars)) )
580 return zRes;
581 else
582 {
583 DdNode * zTemp, * zPlus;
584
585 // solve subproblem
586 zRes = extraZddGetSingletonsBoth( dd, cuddT(bVars) );
587 if ( zRes == NULL )
588 return NULL;
589 cuddRef( zRes );
590
591
592 // create the negative singleton
593 zPlus = cuddZddGetNode( dd, 2*bVars->index+1, z1, z0 );
594 if ( zPlus == NULL )
595 {
596 Cudd_RecursiveDerefZdd( dd, zRes );
597 return NULL;
598 }
599 cuddRef( zPlus );
600
601 // add these to the result
602 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
603 if ( zRes == NULL )
604 {
605 Cudd_RecursiveDerefZdd( dd, zTemp );
606 Cudd_RecursiveDerefZdd( dd, zPlus );
607 return NULL;
608 }
609 cuddRef( zRes );
610 Cudd_RecursiveDerefZdd( dd, zTemp );
611 Cudd_RecursiveDerefZdd( dd, zPlus );
612
613
614 // create the positive singleton
615 zPlus = cuddZddGetNode( dd, 2*bVars->index, z1, z0 );
616 if ( zPlus == NULL )
617 {
618 Cudd_RecursiveDerefZdd( dd, zRes );
619 return NULL;
620 }
621 cuddRef( zPlus );
622
623 // add these to the result
624 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
625 if ( zRes == NULL )
626 {
627 Cudd_RecursiveDerefZdd( dd, zTemp );
628 Cudd_RecursiveDerefZdd( dd, zPlus );
629 return NULL;
630 }
631 cuddRef( zRes );
632 Cudd_RecursiveDerefZdd( dd, zTemp );
633 Cudd_RecursiveDerefZdd( dd, zPlus );
634
635 cuddDeref( zRes );
636 cuddCacheInsert1( dd, extraZddGetSingletonsBoth, bVars, zRes );
637 return zRes;
638 }
639} /* end of extraZddGetSingletonsBoth */
DdNode * extraZddGetSingletonsBoth(DdManager *dd, DdNode *bVars)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraZddGetSymmetricVars()

DdNode * extraZddGetSymmetricVars ( DdManager * dd,
DdNode * bF,
DdNode * bG,
DdNode * bVars )
extern

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

Synopsis [Performs a recursive step of Extra_zddGetSymmetricVars.]

Description [Returns the set of ZDD singletons, containing those positive ZDD variables that correspond to BDD variables x, for which it is true that bF(x=0) == bG(x=1).]

SideEffects []

SeeAlso []

Definition at line 804 of file extraBddSymm.c.

809{
810 DdNode * zRes;
811 DdNode * bFR = Cudd_Regular(bF);
812 DdNode * bGR = Cudd_Regular(bG);
813
814 if ( cuddIsConstant(bFR) && cuddIsConstant(bGR) )
815 {
816 if ( bF == bG )
817 return extraZddGetSingletons( dd, bVars );
818 else
819 return z0;
820 }
821 assert( bVars != b1 );
822
823 if ( (zRes = cuddCacheLookupZdd(dd, DD_GET_SYMM_VARS_TAG, bF, bG, bVars)) )
824 return zRes;
825 else
826 {
827 DdNode * zRes0, * zRes1;
828 DdNode * zPlus, * zTemp;
829 DdNode * bF0, * bF1;
830 DdNode * bG0, * bG1;
831 DdNode * bVarsNew;
832
833 int LevelF = cuddI(dd,bFR->index);
834 int LevelG = cuddI(dd,bGR->index);
835 int LevelFG;
836
837 if ( LevelF < LevelG )
838 LevelFG = LevelF;
839 else
840 LevelFG = LevelG;
841
842 // at least one of the arguments is not a constant
843 assert( LevelFG < dd->size );
844
845 // every variable in bF and bG should be also in bVars, therefore LevelFG cannot be above LevelV
846 // if LevelFG is below LevelV, scroll through the vars in bVars to the same level as LevelFG
847 for ( bVarsNew = bVars; LevelFG > dd->perm[bVarsNew->index]; bVarsNew = cuddT(bVarsNew) );
848 assert( LevelFG == dd->perm[bVarsNew->index] );
849
850 // cofactor the functions
851 if ( LevelF == LevelFG )
852 {
853 if ( bFR != bF ) // bF is complemented
854 {
855 bF0 = Cudd_Not( cuddE(bFR) );
856 bF1 = Cudd_Not( cuddT(bFR) );
857 }
858 else
859 {
860 bF0 = cuddE(bFR);
861 bF1 = cuddT(bFR);
862 }
863 }
864 else
865 bF0 = bF1 = bF;
866
867 if ( LevelG == LevelFG )
868 {
869 if ( bGR != bG ) // bG is complemented
870 {
871 bG0 = Cudd_Not( cuddE(bGR) );
872 bG1 = Cudd_Not( cuddT(bGR) );
873 }
874 else
875 {
876 bG0 = cuddE(bGR);
877 bG1 = cuddT(bGR);
878 }
879 }
880 else
881 bG0 = bG1 = bG;
882
883 // solve subproblems
884 zRes0 = extraZddGetSymmetricVars( dd, bF0, bG0, cuddT(bVarsNew) );
885 if ( zRes0 == NULL )
886 return NULL;
887 cuddRef( zRes0 );
888
889 // if there is not symmetries in the negative cofactor
890 // there is no need to test the positive cofactor
891 if ( zRes0 == z0 )
892 zRes = zRes0; // zRes takes reference
893 else
894 {
895 zRes1 = extraZddGetSymmetricVars( dd, bF1, bG1, cuddT(bVarsNew) );
896 if ( zRes1 == NULL )
897 {
898 Cudd_RecursiveDerefZdd( dd, zRes0 );
899 return NULL;
900 }
901 cuddRef( zRes1 );
902
903 // only those variables should belong to the resulting set
904 // for which the property is true for both cofactors
905 zRes = cuddZddIntersect( dd, zRes0, zRes1 );
906 if ( zRes == NULL )
907 {
908 Cudd_RecursiveDerefZdd( dd, zRes0 );
909 Cudd_RecursiveDerefZdd( dd, zRes1 );
910 return NULL;
911 }
912 cuddRef( zRes );
913 Cudd_RecursiveDerefZdd( dd, zRes0 );
914 Cudd_RecursiveDerefZdd( dd, zRes1 );
915 }
916
917 // add one more singleton if the property is true for this variable
918 if ( bF0 == bG1 )
919 {
920 zPlus = cuddZddGetNode( dd, 2*bVarsNew->index, z1, z0 );
921 if ( zPlus == NULL )
922 {
923 Cudd_RecursiveDerefZdd( dd, zRes );
924 return NULL;
925 }
926 cuddRef( zPlus );
927
928 // add these variable pairs to the result
929 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
930 if ( zRes == NULL )
931 {
932 Cudd_RecursiveDerefZdd( dd, zTemp );
933 Cudd_RecursiveDerefZdd( dd, zPlus );
934 return NULL;
935 }
936 cuddRef( zRes );
937 Cudd_RecursiveDerefZdd( dd, zTemp );
938 Cudd_RecursiveDerefZdd( dd, zPlus );
939 }
940
941 if ( bF == bG && bVars != bVarsNew )
942 {
943 // if the functions are equal, so are their cofactors
944 // add those variables from V that are above F and G
945
946 DdNode * bVarsExtra;
947
948 assert( LevelFG > dd->perm[bVars->index] );
949
950 // create the BDD of the extra variables
951 bVarsExtra = cuddBddExistAbstractRecur( dd, bVars, bVarsNew );
952 if ( bVarsExtra == NULL )
953 {
954 Cudd_RecursiveDerefZdd( dd, zRes );
955 return NULL;
956 }
957 cuddRef( bVarsExtra );
958
959 zPlus = extraZddGetSingletons( dd, bVarsExtra );
960 if ( zPlus == NULL )
961 {
962 Cudd_RecursiveDeref( dd, bVarsExtra );
963 Cudd_RecursiveDerefZdd( dd, zRes );
964 return NULL;
965 }
966 cuddRef( zPlus );
967 Cudd_RecursiveDeref( dd, bVarsExtra );
968
969 // add these to the result
970 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
971 if ( zRes == NULL )
972 {
973 Cudd_RecursiveDerefZdd( dd, zTemp );
974 Cudd_RecursiveDerefZdd( dd, zPlus );
975 return NULL;
976 }
977 cuddRef( zRes );
978 Cudd_RecursiveDerefZdd( dd, zTemp );
979 Cudd_RecursiveDerefZdd( dd, zPlus );
980 }
981 cuddDeref( zRes );
982
983 cuddCacheInsert( dd, DD_GET_SYMM_VARS_TAG, bF, bG, bVars, zRes );
984 return zRes;
985 }
986} /* end of extraZddGetSymmetricVars */
#define DD_GET_SYMM_VARS_TAG
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraZddMaxDotProduct()

DdNode * extraZddMaxDotProduct ( DdManager * dd,
DdNode * S,
DdNode * T )
extern

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

Synopsis [Performs the recursive step of Extra_zddMaxDotProduct.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 938 of file extraBddMaxMin.c.

942{
943 DdNode *zRes;
944 int TopS, TopT;
945 statLine(dd);
946
947 /* consider terminal cases */
948 if ( S == z0 || T == z0 )
949 return z0;
950 if ( S == z1 )
951 return T;
952 if ( T == z1 )
953 return S;
954
955 /* the operation is commutative - normalize the problem */
956 TopS = dd->permZ[S->index];
957 TopT = dd->permZ[T->index];
958
959 if ( TopS > TopT || (TopS == TopT && S > T) )
960 return extraZddMaxDotProduct(dd, T, S);
961
962 /* check cache */
963 zRes = cuddCacheLookup2Zdd(dd, extraZddMaxDotProduct, S, T);
964 if (zRes)
965 return zRes;
966 else
967 {
968 DdNode *zSet0, *zSet1, *zRes0, *zRes1, *zTemp;
969 if ( TopS == TopT )
970 {
971 /* compute the union of two cofactors of T (T0+T1) */
972 zTemp = extraZddMaxUnion(dd, cuddE(T), cuddT(T) );
973 if ( zTemp == NULL )
974 return NULL;
975 cuddRef( zTemp );
976
977 /* compute MaxDotProduct with the top element for subsets (S1, T0+T1) */
978 zSet0 = extraZddMaxDotProduct(dd, cuddT(S), zTemp );
979 if ( zSet0 == NULL )
980 {
981 Cudd_RecursiveDerefZdd(dd, zTemp);
982 return NULL;
983 }
984 cuddRef( zSet0 );
985 Cudd_RecursiveDerefZdd(dd, zTemp);
986
987 /* compute MaxDotProduct with the top element for subsets (S0, T1) */
988 zSet1 = extraZddMaxDotProduct(dd, cuddE(S), cuddT(T) );
989 if ( zSet1 == NULL )
990 {
991 Cudd_RecursiveDerefZdd(dd, zSet0);
992 return NULL;
993 }
994 cuddRef( zSet1 );
995
996 /* compute the union of these two partial results (zSet0 + zSet1) */
997 zRes1 = extraZddMaxUnion(dd, zSet0, zSet1 );
998 if ( zRes1 == NULL )
999 {
1000 Cudd_RecursiveDerefZdd(dd, zSet0);
1001 Cudd_RecursiveDerefZdd(dd, zSet1);
1002 return NULL;
1003 }
1004 cuddRef( zRes1 );
1005 Cudd_RecursiveDerefZdd(dd, zSet0);
1006 Cudd_RecursiveDerefZdd(dd, zSet1);
1007
1008 /* compute MaxDotProduct for subsets without the top-most element */
1009 zRes0 = extraZddMaxDotProduct(dd, cuddE(S), cuddE(T) );
1010 if ( zRes0 == NULL )
1011 {
1012 Cudd_RecursiveDerefZdd(dd, zRes1);
1013 return NULL;
1014 }
1015 cuddRef( zRes0 );
1016 }
1017 else /* if ( TopS < TopT ) */
1018 {
1019 /* compute MaxDotProduct with the top element for subsets (S1, T) */
1020 zRes1 = extraZddMaxDotProduct(dd, cuddT(S), T );
1021 if ( zRes1 == NULL )
1022 return NULL;
1023 cuddRef( zRes1 );
1024
1025 /* compute MaxDotProduct for subsets without the top-most element */
1026 zRes0 = extraZddMaxDotProduct(dd, cuddE(S), T );
1027 if ( zRes0 == NULL )
1028 {
1029 Cudd_RecursiveDerefZdd(dd, zRes1);
1030 return NULL;
1031 }
1032 cuddRef( zRes0 );
1033 }
1034
1035 /* remove subsets without this element covered by subsets with this element */
1036 zRes0 = extraZddNotSubSet(dd, zTemp = zRes0, zRes1);
1037 if ( zRes0 == NULL )
1038 {
1039 Cudd_RecursiveDerefZdd(dd, zTemp);
1040 Cudd_RecursiveDerefZdd(dd, zRes1);
1041 return NULL;
1042 }
1043 cuddRef( zRes0 );
1044 Cudd_RecursiveDerefZdd(dd, zTemp);
1045
1046 /* create the new node */
1047 zRes = cuddZddGetNode( dd, S->index, zRes1, zRes0 );
1048 if ( zRes == NULL )
1049 {
1050 Cudd_RecursiveDerefZdd( dd, zRes0 );
1051 Cudd_RecursiveDerefZdd( dd, zRes1 );
1052 return NULL;
1053 }
1054 cuddDeref( zRes0 );
1055 cuddDeref( zRes1 );
1056
1057 /* insert the result into cache */
1058 cuddCacheInsert2(dd, extraZddMaxDotProduct, S, T, zRes);
1059 return zRes;
1060 }
1061} /* end of extraZddMaxDotProduct */
DdNode * extraZddMaxDotProduct(DdManager *dd, DdNode *S, DdNode *T)
DdNode * extraZddNotSubSet(DdManager *dd, DdNode *X, DdNode *Y)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraZddMaximal()

DdNode * extraZddMaximal ( DdManager * dd,
DdNode * zSet )
extern

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

Synopsis [Performs the recursive step of Extra_zddMaximal.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 294 of file extraBddMaxMin.c.

297{
298 DdNode *zRes;
299 statLine(dd);
300
301 /* consider terminal cases */
302 if ( zSet == z0 || zSet == z1 )
303 return zSet;
304
305 /* check cache */
306 zRes = cuddCacheLookup1Zdd(dd, extraZddMaximal, zSet);
307 if (zRes)
308 return(zRes);
309 else
310 {
311 DdNode *zSet0, *zSet1, *zRes0, *zRes1;
312
313 /* compute maximal for subsets without the top-most element */
314 zSet0 = extraZddMaximal(dd, cuddE(zSet));
315 if ( zSet0 == NULL )
316 return NULL;
317 cuddRef( zSet0 );
318
319 /* compute maximal for subsets with the top-most element */
320 zSet1 = extraZddMaximal(dd, cuddT(zSet));
321 if ( zSet1 == NULL )
322 {
323 Cudd_RecursiveDerefZdd(dd, zSet0);
324 return NULL;
325 }
326 cuddRef( zSet1 );
327
328 /* remove subsets without this element covered by subsets with this element */
329 zRes0 = extraZddNotSubSet(dd, zSet0, zSet1);
330 if ( zRes0 == NULL )
331 {
332 Cudd_RecursiveDerefZdd(dd, zSet0);
333 Cudd_RecursiveDerefZdd(dd, zSet1);
334 return NULL;
335 }
336 cuddRef( zRes0 );
337 Cudd_RecursiveDerefZdd(dd, zSet0);
338
339 /* subset with this element remains unchanged */
340 zRes1 = zSet1;
341
342 /* create the new node */
343 zRes = cuddZddGetNode( dd, zSet->index, zRes1, zRes0 );
344 if ( zRes == NULL )
345 {
346 Cudd_RecursiveDerefZdd( dd, zRes0 );
347 Cudd_RecursiveDerefZdd( dd, zRes1 );
348 return NULL;
349 }
350 cuddDeref( zRes0 );
351 cuddDeref( zRes1 );
352
353 /* insert the result into cache */
354 cuddCacheInsert1(dd, extraZddMaximal, zSet, zRes);
355 return zRes;
356 }
357} /* end of extraZddMaximal */
DdNode * extraZddMaximal(DdManager *dd, DdNode *S)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraZddMaxNotSupSet()

DdNode * extraZddMaxNotSupSet ( DdManager * dd,
DdNode * X,
DdNode * Y )
extern

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

Synopsis [Performs the recursive step of Extra_zddMaxNotSupSet.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 799 of file extraBddSet.c.

800{
801 DdNode *zRes;
802 statLine(dd);
803 /* any comb is a superset of itself */
804 if ( X == Y )
805 return z0;
806 /* no comb in X is superset of non-existing combs */
807 if ( Y == z0 )
808 return extraZddMaximal( dd, X );
809 /* any comb in X is the superset of the empty comb */
810 if ( Extra_zddEmptyBelongs( dd, Y ) )
811 return z0;
812 /* if X is empty, the result is empty */
813 if ( X == z0 )
814 return z0;
815 /* if X is the empty comb (and Y does not contain it!), return it */
816 if ( X == z1 )
817 return z1;
818
819 /* check cache */
820 zRes = cuddCacheLookup2Zdd(dd, extraZddMaxNotSupSet, X, Y);
821 if (zRes)
822 return(zRes);
823 else
824 {
825 DdNode *zRes0, *zRes1, *zTemp;
826 int TopLevelX = dd->permZ[ X->index ];
827 int TopLevelY = dd->permZ[ Y->index ];
828
829 if ( TopLevelX < TopLevelY )
830 {
831 /* combinations of X without label that are supersets of combinations with Y */
832 zRes0 = extraZddMaxNotSupSet( dd, cuddE( X ), Y );
833 if ( zRes0 == NULL )
834 return NULL;
835 cuddRef( zRes0 );
836
837 /* combinations of X with label that are supersets of combinations with Y */
838 zRes1 = extraZddMaxNotSupSet( dd, cuddT( X ), Y );
839 if ( zRes1 == NULL )
840 {
841 Cudd_RecursiveDerefZdd( dd, zRes0 );
842 return NULL;
843 }
844 cuddRef( zRes1 );
845
846 /* ---------------------------------------------------- */
847 /* remove subsets without this element covered by subsets with this element */
848 zRes0 = extraZddNotSubSet(dd, zTemp = zRes0, zRes1);
849 if ( zRes0 == NULL )
850 {
851 Cudd_RecursiveDerefZdd(dd, zTemp);
852 Cudd_RecursiveDerefZdd(dd, zRes1);
853 return NULL;
854 }
855 cuddRef( zRes0 );
856 Cudd_RecursiveDerefZdd(dd, zTemp);
857 /* ---------------------------------------------------- */
858
859 /* compose Res0 and Res1 with the given ZDD variable */
860 zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 );
861 if ( zRes == NULL )
862 {
863 Cudd_RecursiveDerefZdd( dd, zRes0 );
864 Cudd_RecursiveDerefZdd( dd, zRes1 );
865 return NULL;
866 }
867 cuddDeref( zRes0 );
868 cuddDeref( zRes1 );
869 }
870 else if ( TopLevelX == TopLevelY )
871 {
872 /* combs of X without var that are supersets of combs of Y without var */
873 zRes0 = extraZddMaxNotSupSet( dd, cuddE( X ), cuddE( Y ) );
874 if ( zRes0 == NULL )
875 return NULL;
876 cuddRef( zRes0 );
877
878 /* merge combs of Y with and without var */
879 zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) );
880 if ( zTemp == NULL )
881 {
882 Cudd_RecursiveDerefZdd( dd, zRes0 );
883 return NULL;
884 }
885 cuddRef( zTemp );
886
887 /* combs of X with label that are supersets of combs in Temp */
888 zRes1 = extraZddMaxNotSupSet( dd, cuddT( X ), zTemp );
889 if ( zRes1 == NULL )
890 {
891 Cudd_RecursiveDerefZdd( dd, zRes0 );
892 Cudd_RecursiveDerefZdd( dd, zTemp );
893 return NULL;
894 }
895 cuddRef( zRes1 );
896 Cudd_RecursiveDerefZdd( dd, zTemp );
897
898 /* ---------------------------------------------------- */
899 /* remove subsets without this element covered by subsets with this element */
900 zRes0 = extraZddNotSubSet(dd, zTemp = zRes0, zRes1);
901 if ( zRes0 == NULL )
902 {
903 Cudd_RecursiveDerefZdd(dd, zTemp);
904 Cudd_RecursiveDerefZdd(dd, zRes1);
905 return NULL;
906 }
907 cuddRef( zRes0 );
908 Cudd_RecursiveDerefZdd(dd, zTemp);
909 /* ---------------------------------------------------- */
910
911 /* compose Res0 and Res1 with the given ZDD variable */
912 zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 );
913 if ( zRes == NULL )
914 {
915 Cudd_RecursiveDerefZdd( dd, zRes0 );
916 Cudd_RecursiveDerefZdd( dd, zRes1 );
917 return NULL;
918 }
919 cuddDeref( zRes0 );
920 cuddDeref( zRes1 );
921 }
922 else /* if ( TopLevelX > TopLevelY ) */
923 {
924 /* combs of X that are supersets of combs of Y without label */
925 zRes = extraZddMaxNotSupSet( dd, X, cuddE( Y ) );
926 if ( zRes == NULL ) return NULL;
927 }
928
929 /* insert the result into cache */
930 cuddCacheInsert2(dd, extraZddMaxNotSupSet, X, Y, zRes);
931 return zRes;
932 }
933} /* end of extraZddMaxNotSupSet */
int Extra_zddEmptyBelongs(DdManager *dd, DdNode *zS)
DdNode * extraZddMaxNotSupSet(DdManager *dd, DdNode *X, DdNode *Y)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraZddMaxUnion()

DdNode * extraZddMaxUnion ( DdManager * dd,
DdNode * S,
DdNode * T )
extern

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

Synopsis [Performs the recursive step of Extra_zddMaxUnion.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 454 of file extraBddMaxMin.c.

458{
459 DdNode *zRes;
460 int TopS, TopT;
461 statLine(dd);
462
463 /* consider terminal cases */
464 if ( S == z0 )
465 return T;
466 if ( T == z0 )
467 return S;
468 if ( S == T )
469 return S;
470 if ( S == z1 )
471 return T;
472 if ( T == z1 )
473 return S;
474
475 /* the operation is commutative - normalize the problem */
476 TopS = dd->permZ[S->index];
477 TopT = dd->permZ[T->index];
478
479 if ( TopS > TopT || (TopS == TopT && S > T) )
480 return extraZddMaxUnion(dd, T, S);
481
482 /* check cache */
483 zRes = cuddCacheLookup2Zdd(dd, extraZddMaxUnion, S, T);
484 if (zRes)
485 return zRes;
486 else
487 {
488 DdNode *zSet0, *zSet1, *zRes0, *zRes1;
489
490 if ( TopS == TopT )
491 {
492 /* compute maximal for subsets without the top-most element */
493 zSet0 = extraZddMaxUnion(dd, cuddE(S), cuddE(T) );
494 if ( zSet0 == NULL )
495 return NULL;
496 cuddRef( zSet0 );
497
498 /* compute maximal for subsets with the top-most element */
499 zSet1 = extraZddMaxUnion(dd, cuddT(S), cuddT(T) );
500 if ( zSet1 == NULL )
501 {
502 Cudd_RecursiveDerefZdd(dd, zSet0);
503 return NULL;
504 }
505 cuddRef( zSet1 );
506 }
507 else /* if ( TopS < TopT ) */
508 {
509 /* compute maximal for subsets without the top-most element */
510 zSet0 = extraZddMaxUnion(dd, cuddE(S), T );
511 if ( zSet0 == NULL )
512 return NULL;
513 cuddRef( zSet0 );
514
515 /* subset with this element is just the cofactor of S */
516 zSet1 = cuddT(S);
517 cuddRef( zSet1 );
518 }
519
520 /* remove subsets without this element covered by subsets with this element */
521 zRes0 = extraZddNotSubSet(dd, zSet0, zSet1);
522 if ( zRes0 == NULL )
523 {
524 Cudd_RecursiveDerefZdd(dd, zSet0);
525 Cudd_RecursiveDerefZdd(dd, zSet1);
526 return NULL;
527 }
528 cuddRef( zRes0 );
529 Cudd_RecursiveDerefZdd(dd, zSet0);
530
531 /* subset with this element remains unchanged */
532 zRes1 = zSet1;
533
534 /* create the new node */
535 zRes = cuddZddGetNode( dd, S->index, zRes1, zRes0 );
536 if ( zRes == NULL )
537 {
538 Cudd_RecursiveDerefZdd( dd, zRes0 );
539 Cudd_RecursiveDerefZdd( dd, zRes1 );
540 return NULL;
541 }
542 cuddDeref( zRes0 );
543 cuddDeref( zRes1 );
544
545 /* insert the result into cache */
546 cuddCacheInsert2(dd, extraZddMaxUnion, S, T, zRes);
547 return zRes;
548 }
549} /* end of extraZddMaxUnion */
DdNode * extraZddMaxUnion(DdManager *dd, DdNode *S, DdNode *T)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraZddMinimal()

DdNode * extraZddMinimal ( DdManager * dd,
DdNode * zSet )
extern

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

Synopsis [Performs the recursive step of Extra_zddMinimal.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 373 of file extraBddMaxMin.c.

376{
377 DdNode *zRes;
378 statLine(dd);
379
380 /* consider terminal cases */
381 if ( zSet == z0 )
382 return zSet;
383 /* the empty combinaTon, if present, is the only minimal combinaTon */
384 if ( Extra_zddEmptyBelongs(dd, zSet) )
385 return z1;
386
387 /* check cache */
388 zRes = cuddCacheLookup1Zdd(dd, extraZddMinimal, zSet);
389 if (zRes)
390 return(zRes);
391 else
392 {
393 DdNode *zSet0, *zSet1, *zRes0, *zRes1;
394
395 /* compute minimal for subsets without the top-most element */
396 zSet0 = extraZddMinimal(dd, cuddE(zSet));
397 if ( zSet0 == NULL )
398 return NULL;
399 cuddRef( zSet0 );
400
401 /* compute minimal for subsets with the top-most element */
402 zSet1 = extraZddMinimal(dd, cuddT(zSet));
403 if ( zSet1 == NULL )
404 {
405 Cudd_RecursiveDerefZdd(dd, zSet0);
406 return NULL;
407 }
408 cuddRef( zSet1 );
409
410 /* subset without this element remains unchanged */
411 zRes0 = zSet0;
412
413 /* remove subsets with this element that contain subsets without this element */
414 zRes1 = extraZddNotSupSet(dd, zSet1, zSet0);
415 if ( zRes1 == NULL )
416 {
417 Cudd_RecursiveDerefZdd(dd, zSet0);
418 Cudd_RecursiveDerefZdd(dd, zSet1);
419 return NULL;
420 }
421 cuddRef( zRes1 );
422 Cudd_RecursiveDerefZdd(dd, zSet1);
423
424 /* create the new node */
425 zRes = cuddZddGetNode( dd, zSet->index, zRes1, zRes0 );
426 if ( zRes == NULL )
427 {
428 Cudd_RecursiveDerefZdd( dd, zRes0 );
429 Cudd_RecursiveDerefZdd( dd, zRes1 );
430 return NULL;
431 }
432 cuddDeref( zRes0 );
433 cuddDeref( zRes1 );
434
435 /* insert the result into cache */
436 cuddCacheInsert1(dd, extraZddMinimal, zSet, zRes);
437 return zRes;
438 }
439} /* end of extraZddMinimal */
DdNode * extraZddMinimal(DdManager *dd, DdNode *S)
int Extra_zddEmptyBelongs(DdManager *dd, DdNode *zS)
DdNode * extraZddNotSupSet(DdManager *dd, DdNode *X, DdNode *Y)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraZddMinUnion()

DdNode * extraZddMinUnion ( DdManager * dd,
DdNode * S,
DdNode * T )
extern

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

Synopsis [Performs the recursive step of Extra_zddMinUnion.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 564 of file extraBddMaxMin.c.

568{
569 DdNode *zRes;
570 int TopS, TopT;
571 statLine(dd);
572
573 /* consider terminal cases */
574 if ( S == z0 )
575 return T;
576 if ( T == z0 )
577 return S;
578 if ( S == T )
579 return S;
580 /* the empty combination, if present, is the only minimal combination */
581 if ( Extra_zddEmptyBelongs(dd, S) || Extra_zddEmptyBelongs(dd, T) )
582 return z1;
583
584 /* the operation is commutative - normalize the problem */
585 TopS = dd->permZ[S->index];
586 TopT = dd->permZ[T->index];
587
588 if ( TopS > TopT || (TopS == TopT && S > T) )
589 return extraZddMinUnion(dd, T, S);
590
591 /* check cache */
592 zRes = cuddCacheLookup2Zdd(dd, extraZddMinUnion, S, T);
593 if (zRes)
594 return(zRes);
595 else
596 {
597 DdNode *zSet0, *zSet1, *zRes0, *zRes1;
598 if ( TopS == TopT )
599 {
600 /* compute maximal for subsets without the top-most element */
601 zSet0 = extraZddMinUnion(dd, cuddE(S), cuddE(T) );
602 if ( zSet0 == NULL )
603 return NULL;
604 cuddRef( zSet0 );
605
606 /* compute maximal for subsets with the top-most element */
607 zSet1 = extraZddMinUnion(dd, cuddT(S), cuddT(T) );
608 if ( zSet1 == NULL )
609 {
610 Cudd_RecursiveDerefZdd(dd, zSet0);
611 return NULL;
612 }
613 cuddRef( zSet1 );
614 }
615 else /* if ( TopS < TopT ) */
616 {
617 /* compute maximal for subsets without the top-most element */
618 zSet0 = extraZddMinUnion(dd, cuddE(S), T );
619 if ( zSet0 == NULL )
620 return NULL;
621 cuddRef( zSet0 );
622
623 /* subset with this element is just the cofactor of S */
624 zSet1 = cuddT(S);
625 cuddRef( zSet1 );
626 }
627
628 /* subset without this element remains unchanged */
629 zRes0 = zSet0;
630
631 /* remove subsets with this element that contain subsets without this element */
632 zRes1 = extraZddNotSupSet(dd, zSet1, zSet0);
633 if ( zRes1 == NULL )
634 {
635 Cudd_RecursiveDerefZdd(dd, zSet0);
636 Cudd_RecursiveDerefZdd(dd, zSet1);
637 return NULL;
638 }
639 cuddRef( zRes1 );
640 Cudd_RecursiveDerefZdd(dd, zSet1);
641
642 /* create the new node */
643 zRes = cuddZddGetNode( dd, S->index, zRes1, zRes0 );
644 if ( zRes == NULL )
645 {
646 Cudd_RecursiveDerefZdd( dd, zRes0 );
647 Cudd_RecursiveDerefZdd( dd, zRes1 );
648 return NULL;
649 }
650 cuddDeref( zRes0 );
651 cuddDeref( zRes1 );
652
653 /* insert the result into cache */
654 cuddCacheInsert2(dd, extraZddMinUnion, S, T, zRes);
655 return zRes;
656 }
657} /* end of extraZddMinUnion */
DdNode * extraZddMinUnion(DdManager *dd, DdNode *S, DdNode *T)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraZddNotSubSet()

DdNode * extraZddNotSubSet ( DdManager * dd,
DdNode * X,
DdNode * Y )
extern

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

Synopsis [Performs the recursive step of Extra_zddNotSubSet.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 550 of file extraBddSet.c.

551{
552 DdNode *zRes;
553 statLine(dd);
554 /* any comb is a subset of itself */
555 if ( X == Y )
556 return z0;
557 /* combs in X are notsubsets of non-existant combs in Y */
558 if ( Y == z0 )
559 return X;
560 /* only {()} is the subset of {()} */
561 if ( Y == z1 ) /* remove empty combination from X */
562 return cuddZddDiff( dd, X, z1 );
563 /* if X is empty, the result is empty */
564 if ( X == z0 )
565 return z0;
566 /* the empty comb is contained in all combs of Y */
567 if ( X == z1 )
568 return z0;
569
570 /* check cache */
571 zRes = cuddCacheLookup2Zdd(dd, extraZddNotSubSet, X, Y);
572 if (zRes)
573 return(zRes);
574 else
575 {
576 DdNode *zRes0, *zRes1, *zTemp;
577 int TopLevelX = dd->permZ[ X->index ];
578 int TopLevelY = dd->permZ[ Y->index ];
579
580 if ( TopLevelX < TopLevelY )
581 {
582 /* compute combs of X without var that are notsubsets of combs with Y */
583 zRes0 = extraZddNotSubSet( dd, cuddE( X ), Y );
584 if ( zRes0 == NULL )
585 return NULL;
586 cuddRef( zRes0 );
587
588 /* combs of X with var cannot be subsets of combs without var in Y */
589 zRes1 = cuddT( X );
590
591 /* compose Res0 and Res1 with the given ZDD variable */
592 zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 );
593 if ( zRes == NULL )
594 {
595 Cudd_RecursiveDerefZdd( dd, zRes0 );
596 return NULL;
597 }
598 cuddDeref( zRes0 );
599 }
600 else if ( TopLevelX == TopLevelY )
601 {
602 /* merge combs of Y with and without var */
603 zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) );
604 if ( zTemp == NULL )
605 return NULL;
606 cuddRef( zTemp );
607
608 /* compute combs of X without var that are notsubsets of combs is Temp */
609 zRes0 = extraZddNotSubSet( dd, cuddE( X ), zTemp );
610 if ( zRes0 == NULL )
611 {
612 Cudd_RecursiveDerefZdd( dd, zTemp );
613 return NULL;
614 }
615 cuddRef( zRes0 );
616 Cudd_RecursiveDerefZdd( dd, zTemp );
617
618 /* combs of X with var that are notsubsets of combs in Y with var */
619 zRes1 = extraZddNotSubSet( dd, cuddT( X ), cuddT( Y ) );
620 if ( zRes1 == NULL )
621 {
622 Cudd_RecursiveDerefZdd( dd, zRes0 );
623 return NULL;
624 }
625 cuddRef( zRes1 );
626
627 /* compose Res0 and Res1 with the given ZDD variable */
628 zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 );
629 if ( zRes == NULL )
630 {
631 Cudd_RecursiveDerefZdd( dd, zRes0 );
632 Cudd_RecursiveDerefZdd( dd, zRes1 );
633 return NULL;
634 }
635 cuddDeref( zRes0 );
636 cuddDeref( zRes1 );
637 }
638 else /* if ( TopLevelX > TopLevelY ) */
639 {
640 /* merge combs of Y with and without var */
641 zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) );
642 if ( zTemp == NULL )
643 return NULL;
644 cuddRef( zTemp );
645
646 /* compute combs that are notsubsets of Temp */
647 zRes = extraZddNotSubSet( dd, X, zTemp );
648 if ( zRes == NULL )
649 {
650 Cudd_RecursiveDerefZdd( dd, zTemp );
651 return NULL;
652 }
653 cuddRef( zRes );
654 Cudd_RecursiveDerefZdd( dd, zTemp );
655 cuddDeref( zRes );
656 }
657
658 /* insert the result into cache */
659 cuddCacheInsert2(dd, extraZddNotSubSet, X, Y, zRes);
660 return zRes;
661 }
662} /* end of extraZddNotSubSet */
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraZddNotSupSet()

DdNode * extraZddNotSupSet ( DdManager * dd,
DdNode * X,
DdNode * Y )
extern

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

Synopsis [Performs the recursive step of Extra_zddNotSupSet.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 676 of file extraBddSet.c.

677{
678 DdNode *zRes;
679 statLine(dd);
680 /* any comb is a superset of itself */
681 if ( X == Y )
682 return z0;
683 /* no comb in X is superset of non-existing combs */
684 if ( Y == z0 )
685 return X;
686 /* any comb in X is the superset of the empty comb */
687 if ( Extra_zddEmptyBelongs( dd, Y ) )
688 return z0;
689 /* if X is empty, the result is empty */
690 if ( X == z0 )
691 return z0;
692 /* if X is the empty comb (and Y does not contain it!), return it */
693 if ( X == z1 )
694 return z1;
695
696 /* check cache */
697 zRes = cuddCacheLookup2Zdd(dd, extraZddNotSupSet, X, Y);
698 if (zRes)
699 return(zRes);
700 else
701 {
702 DdNode *zRes0, *zRes1, *zTemp;
703 int TopLevelX = dd->permZ[ X->index ];
704 int TopLevelY = dd->permZ[ Y->index ];
705
706 if ( TopLevelX < TopLevelY )
707 {
708 /* combinations of X without label that are supersets of combinations of Y */
709 zRes0 = extraZddNotSupSet( dd, cuddE( X ), Y );
710 if ( zRes0 == NULL )
711 return NULL;
712 cuddRef( zRes0 );
713
714 /* combinations of X with label that are supersets of combinations of Y */
715 zRes1 = extraZddNotSupSet( dd, cuddT( X ), Y );
716 if ( zRes1 == NULL )
717 {
718 Cudd_RecursiveDerefZdd( dd, zRes0 );
719 return NULL;
720 }
721 cuddRef( zRes1 );
722
723 /* compose Res0 and Res1 with the given ZDD variable */
724 zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 );
725 if ( zRes == NULL )
726 {
727 Cudd_RecursiveDerefZdd( dd, zRes0 );
728 Cudd_RecursiveDerefZdd( dd, zRes1 );
729 return NULL;
730 }
731 cuddDeref( zRes0 );
732 cuddDeref( zRes1 );
733 }
734 else if ( TopLevelX == TopLevelY )
735 {
736 /* combs of X without var that are not supersets of combs of Y without var */
737 zRes0 = extraZddNotSupSet( dd, cuddE( X ), cuddE( Y ) );
738 if ( zRes0 == NULL )
739 return NULL;
740 cuddRef( zRes0 );
741
742 /* merge combs of Y with and without var */
743 zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) );
744 if ( zTemp == NULL )
745 {
746 Cudd_RecursiveDerefZdd( dd, zRes0 );
747 return NULL;
748 }
749 cuddRef( zTemp );
750
751 /* combs of X with label that are supersets of combs in Temp */
752 zRes1 = extraZddNotSupSet( dd, cuddT( X ), zTemp );
753 if ( zRes1 == NULL )
754 {
755 Cudd_RecursiveDerefZdd( dd, zRes0 );
756 Cudd_RecursiveDerefZdd( dd, zTemp );
757 return NULL;
758 }
759 cuddRef( zRes1 );
760 Cudd_RecursiveDerefZdd( dd, zTemp );
761
762 /* compose Res0 and Res1 with the given ZDD variable */
763 zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 );
764 if ( zRes == NULL )
765 {
766 Cudd_RecursiveDerefZdd( dd, zRes0 );
767 Cudd_RecursiveDerefZdd( dd, zRes1 );
768 return NULL;
769 }
770 cuddDeref( zRes0 );
771 cuddDeref( zRes1 );
772 }
773 else /* if ( TopLevelX > TopLevelY ) */
774 {
775 /* combs of X that are supersets of combs of Y without label */
776 zRes = extraZddNotSupSet( dd, X, cuddE( Y ) );
777 if ( zRes == NULL ) return NULL;
778 }
779
780 /* insert the result into cache */
781 cuddCacheInsert2(dd, extraZddNotSupSet, X, Y, zRes);
782 return zRes;
783 }
784} /* end of extraZddNotSupSet */
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraZddSelectOneSubset()

DdNode * extraZddSelectOneSubset ( DdManager * dd,
DdNode * zS )
extern

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

Synopsis [Performs the recursive step of Extra_zddSelectOneSubset.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 1419 of file extraBddSymm.c.

1424{
1425 DdNode * zRes;
1426
1427 if ( zS == z0 ) return z0;
1428 if ( zS == z1 ) return z1;
1429
1430 // check cache
1431 if ( (zRes = cuddCacheLookup1Zdd( dd, extraZddSelectOneSubset, zS )) )
1432 return zRes;
1433 else
1434 {
1435 DdNode * zS0, * zS1, * zTemp;
1436
1437 zS0 = cuddE(zS);
1438 zS1 = cuddT(zS);
1439
1440 if ( zS0 != z0 )
1441 {
1442 zRes = extraZddSelectOneSubset( dd, zS0 );
1443 if ( zRes == NULL )
1444 return NULL;
1445 }
1446 else // if ( zS0 == z0 )
1447 {
1448 assert( zS1 != z0 );
1449 zRes = extraZddSelectOneSubset( dd, zS1 );
1450 if ( zRes == NULL )
1451 return NULL;
1452 cuddRef( zRes );
1453
1454 zRes = cuddZddGetNode( dd, zS->index, zTemp = zRes, z0 );
1455 if ( zRes == NULL )
1456 {
1457 Cudd_RecursiveDerefZdd( dd, zTemp );
1458 return NULL;
1459 }
1460 cuddDeref( zTemp );
1461 }
1462
1463 // insert the result into cache
1464 cuddCacheInsert1( dd, extraZddSelectOneSubset, zS, zRes );
1465 return zRes;
1466 }
1467} /* end of extraZddSelectOneSubset */
DdNode * extraZddSelectOneSubset(DdManager *dd, DdNode *zS)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraZddSubSet()

DdNode * extraZddSubSet ( DdManager * dd,
DdNode * X,
DdNode * Y )
extern

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

Synopsis [Performs the recursive step of Extra_zddSubSet.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 319 of file extraBddSet.c.

320{
321 DdNode *zRes;
322 statLine(dd);
323 /* any comb is a subset of itself */
324 if ( X == Y )
325 return X;
326 /* if X is empty, the result is empty */
327 if ( X == z0 )
328 return z0;
329 /* combs in X are notsubsets of non-existant combs in Y */
330 if ( Y == z0 )
331 return z0;
332 /* the empty comb is contained in all combs of Y */
333 if ( X == z1 )
334 return z1;
335 /* only {()} is the subset of {()} */
336 if ( Y == z1 ) /* check whether the empty combination is present in X */
337 return ( Extra_zddEmptyBelongs( dd, X )? z1: z0 );
338
339 /* check cache */
340 zRes = cuddCacheLookup2Zdd(dd, extraZddSubSet, X, Y);
341 if (zRes)
342 return(zRes);
343 else
344 {
345 DdNode *zRes0, *zRes1, *zTemp;
346 int TopLevelX = dd->permZ[ X->index ];
347 int TopLevelY = dd->permZ[ Y->index ];
348
349 if ( TopLevelX < TopLevelY )
350 {
351 /* compute combs of X without var that are notsubsets of combs with Y */
352 zRes = extraZddSubSet( dd, cuddE( X ), Y );
353 if ( zRes == NULL ) return NULL;
354 }
355 else if ( TopLevelX == TopLevelY )
356 {
357 /* merge combs of Y with and without var */
358 zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) );
359 if ( zTemp == NULL )
360 return NULL;
361 cuddRef( zTemp );
362
363 /* compute combs of X without var that are notsubsets of combs is Temp */
364 zRes0 = extraZddSubSet( dd, cuddE( X ), zTemp );
365 if ( zRes0 == NULL )
366 {
367 Cudd_RecursiveDerefZdd( dd, zTemp );
368 return NULL;
369 }
370 cuddRef( zRes0 );
371 Cudd_RecursiveDerefZdd( dd, zTemp );
372
373 /* combs of X with var that are notsubsets of combs in Y with var */
374 zRes1 = extraZddSubSet( dd, cuddT( X ), cuddT( Y ) );
375 if ( zRes1 == NULL )
376 {
377 Cudd_RecursiveDerefZdd( dd, zRes0 );
378 return NULL;
379 }
380 cuddRef( zRes1 );
381
382 /* compose Res0 and Res1 with the given ZDD variable */
383 zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 );
384 if ( zRes == NULL )
385 {
386 Cudd_RecursiveDerefZdd( dd, zRes0 );
387 Cudd_RecursiveDerefZdd( dd, zRes1 );
388 return NULL;
389 }
390 cuddDeref( zRes0 );
391 cuddDeref( zRes1 );
392 }
393 else /* if ( TopLevelX > TopLevelY ) */
394 {
395 /* merge combs of Y with and without var */
396 zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) );
397 if ( zTemp == NULL ) return NULL;
398 cuddRef( zTemp );
399
400 /* compute combs that are notsubsets of Temp */
401 zRes = extraZddSubSet( dd, X, zTemp );
402 if ( zRes == NULL )
403 {
404 Cudd_RecursiveDerefZdd( dd, zTemp );
405 return NULL;
406 }
407 cuddRef( zRes );
408 Cudd_RecursiveDerefZdd( dd, zTemp );
409 cuddDeref( zRes );
410 }
411
412 /* insert the result into cache */
413 cuddCacheInsert2(dd, extraZddSubSet, X, Y, zRes);
414 return zRes;
415 }
416} /* end of extraZddSubSet */
DdNode * extraZddSubSet(DdManager *dd, DdNode *X, DdNode *Y)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraZddSupSet()

DdNode * extraZddSupSet ( DdManager * dd,
DdNode * X,
DdNode * Y )
extern

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

Synopsis [Performs the recursive step of Extra_zddSupSet.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 430 of file extraBddSet.c.

431{
432 DdNode *zRes;
433 statLine(dd);
434 /* any comb is a superset of itself */
435 if ( X == Y )
436 return X;
437 /* no comb in X is superset of non-existing combs */
438 if ( Y == z0 )
439 return z0;
440 /* any comb in X is the superset of the empty comb */
441 if ( Extra_zddEmptyBelongs( dd, Y ) )
442 return X;
443 /* if X is empty, the result is empty */
444 if ( X == z0 )
445 return z0;
446 /* if X is the empty comb (and Y does not contain it!), return empty */
447 if ( X == z1 )
448 return z0;
449
450 /* check cache */
451 zRes = cuddCacheLookup2Zdd(dd, extraZddSupSet, X, Y);
452 if (zRes)
453 return(zRes);
454 else
455 {
456 DdNode *zRes0, *zRes1, *zTemp;
457 int TopLevelX = dd->permZ[ X->index ];
458 int TopLevelY = dd->permZ[ Y->index ];
459
460 if ( TopLevelX < TopLevelY )
461 {
462 /* combinations of X without label that are supersets of combinations with Y */
463 zRes0 = extraZddSupSet( dd, cuddE( X ), Y );
464 if ( zRes0 == NULL ) return NULL;
465 cuddRef( zRes0 );
466
467 /* combinations of X with label that are supersets of combinations with Y */
468 zRes1 = extraZddSupSet( dd, cuddT( X ), Y );
469 if ( zRes1 == NULL )
470 {
471 Cudd_RecursiveDerefZdd( dd, zRes0 );
472 return NULL;
473 }
474 cuddRef( zRes1 );
475
476 /* compose Res0 and Res1 with the given ZDD variable */
477 zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 );
478 if ( zRes == NULL )
479 {
480 Cudd_RecursiveDerefZdd( dd, zRes0 );
481 Cudd_RecursiveDerefZdd( dd, zRes1 );
482 return NULL;
483 }
484 cuddDeref( zRes0 );
485 cuddDeref( zRes1 );
486 }
487 else if ( TopLevelX == TopLevelY )
488 {
489 /* combs of X without var that are supersets of combs of Y without var */
490 zRes0 = extraZddSupSet( dd, cuddE( X ), cuddE( Y ) );
491 if ( zRes0 == NULL ) return NULL;
492 cuddRef( zRes0 );
493
494 /* merge combs of Y with and without var */
495 zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) );
496 if ( zTemp == NULL )
497 {
498 Cudd_RecursiveDerefZdd( dd, zRes0 );
499 return NULL;
500 }
501 cuddRef( zTemp );
502
503 /* combs of X with label that are supersets of combs in Temp */
504 zRes1 = extraZddSupSet( dd, cuddT( X ), zTemp );
505 if ( zRes1 == NULL )
506 {
507 Cudd_RecursiveDerefZdd( dd, zRes0 );
508 Cudd_RecursiveDerefZdd( dd, zTemp );
509 return NULL;
510 }
511 cuddRef( zRes1 );
512 Cudd_RecursiveDerefZdd( dd, zTemp );
513
514 /* compose Res0 and Res1 with the given ZDD variable */
515 zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 );
516 if ( zRes == NULL )
517 {
518 Cudd_RecursiveDerefZdd( dd, zRes0 );
519 Cudd_RecursiveDerefZdd( dd, zRes1 );
520 return NULL;
521 }
522 cuddDeref( zRes0 );
523 cuddDeref( zRes1 );
524 }
525 else /* if ( TopLevelX > TopLevelY ) */
526 {
527 /* combs of X that are supersets of combs of Y without label */
528 zRes = extraZddSupSet( dd, X, cuddE( Y ) );
529 if ( zRes == NULL ) return NULL;
530 }
531
532 /* insert the result into cache */
533 cuddCacheInsert2(dd, extraZddSupSet, X, Y, zRes);
534 return zRes;
535 }
536} /* end of extraZddSupSet */
DdNode * extraZddSupSet(DdManager *dd, DdNode *X, DdNode *Y)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraZddSymmPairsCompute()

DdNode * extraZddSymmPairsCompute ( DdManager * dd,
DdNode * bFunc,
DdNode * bVars )
extern

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

Synopsis [Performs a recursive step of Extra_SymmPairsCompute.]

Description [Returns the set of symmetric variable pairs represented as a set of two-literal ZDD cubes. Both variables always appear in the positive polarity in the cubes. This function works without building new BDD nodes. Some relatively small number of ZDD nodes may be built to ensure proper bookkeeping of the symmetry information.]

SideEffects []

SeeAlso []

Definition at line 580 of file extraBddSymm.c.

584{
585 DdNode * zRes;
586 DdNode * bFR = Cudd_Regular(bFunc);
587
588 if ( cuddIsConstant(bFR) )
589 {
590 int nVars, i;
591
592 // determine how many vars are in the bVars
593 nVars = Extra_bddSuppSize( dd, bVars );
594 if ( nVars < 2 )
595 return z0;
596 else
597 {
598 DdNode * bVarsK;
599
600 // create the BDD bVarsK corresponding to K = 2;
601 bVarsK = bVars;
602 for ( i = 0; i < nVars-2; i++ )
603 bVarsK = cuddT( bVarsK );
604 return extraZddTuplesFromBdd( dd, bVarsK, bVars );
605 }
606 }
607 assert( bVars != b1 );
608
609 if ( (zRes = cuddCacheLookup2Zdd(dd, extraZddSymmPairsCompute, bFunc, bVars)) )
610 return zRes;
611 else
612 {
613 DdNode * zRes0, * zRes1;
614 DdNode * zTemp, * zPlus, * zSymmVars;
615 DdNode * bF0, * bF1;
616 DdNode * bVarsNew;
617 int nVarsExtra;
618 int LevelF;
619
620 // every variable in bF should be also in bVars, therefore LevelF cannot be above LevelV
621 // if LevelF is below LevelV, scroll through the vars in bVars to the same level as F
622 // count how many extra vars are there in bVars
623 nVarsExtra = 0;
624 LevelF = dd->perm[bFR->index];
625 for ( bVarsNew = bVars; LevelF > dd->perm[bVarsNew->index]; bVarsNew = cuddT(bVarsNew) )
626 nVarsExtra++;
627 // the indexes (level) of variables should be synchronized now
628 assert( bFR->index == bVarsNew->index );
629
630 // cofactor the function
631 if ( bFR != bFunc ) // bFunc is complemented
632 {
633 bF0 = Cudd_Not( cuddE(bFR) );
634 bF1 = Cudd_Not( cuddT(bFR) );
635 }
636 else
637 {
638 bF0 = cuddE(bFR);
639 bF1 = cuddT(bFR);
640 }
641
642 // solve subproblems
643 zRes0 = extraZddSymmPairsCompute( dd, bF0, cuddT(bVarsNew) );
644 if ( zRes0 == NULL )
645 return NULL;
646 cuddRef( zRes0 );
647
648 // if there is no symmetries in the negative cofactor
649 // there is no need to test the positive cofactor
650 if ( zRes0 == z0 )
651 zRes = zRes0; // zRes takes reference
652 else
653 {
654 zRes1 = extraZddSymmPairsCompute( dd, bF1, cuddT(bVarsNew) );
655 if ( zRes1 == NULL )
656 {
657 Cudd_RecursiveDerefZdd( dd, zRes0 );
658 return NULL;
659 }
660 cuddRef( zRes1 );
661
662 // only those variables are pair-wise symmetric
663 // that are pair-wise symmetric in both cofactors
664 // therefore, intersect the solutions
665 zRes = cuddZddIntersect( dd, zRes0, zRes1 );
666 if ( zRes == NULL )
667 {
668 Cudd_RecursiveDerefZdd( dd, zRes0 );
669 Cudd_RecursiveDerefZdd( dd, zRes1 );
670 return NULL;
671 }
672 cuddRef( zRes );
673 Cudd_RecursiveDerefZdd( dd, zRes0 );
674 Cudd_RecursiveDerefZdd( dd, zRes1 );
675 }
676
677 // consider the current top-most variable and find all the vars
678 // that are pairwise symmetric with it
679 // these variables are returned as a set of ZDD singletons
680 zSymmVars = extraZddGetSymmetricVars( dd, bF1, bF0, cuddT(bVarsNew) );
681 if ( zSymmVars == NULL )
682 {
683 Cudd_RecursiveDerefZdd( dd, zRes );
684 return NULL;
685 }
686 cuddRef( zSymmVars );
687
688 // attach the topmost variable to the set, to get the variable pairs
689 // use the positive polarity ZDD variable for the purpose
690
691 // there is no need to do so, if zSymmVars is empty
692 if ( zSymmVars == z0 )
693 Cudd_RecursiveDerefZdd( dd, zSymmVars );
694 else
695 {
696 zPlus = cuddZddGetNode( dd, 2*bFR->index, zSymmVars, z0 );
697 if ( zPlus == NULL )
698 {
699 Cudd_RecursiveDerefZdd( dd, zRes );
700 Cudd_RecursiveDerefZdd( dd, zSymmVars );
701 return NULL;
702 }
703 cuddRef( zPlus );
704 cuddDeref( zSymmVars );
705
706 // add these variable pairs to the result
707 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
708 if ( zRes == NULL )
709 {
710 Cudd_RecursiveDerefZdd( dd, zTemp );
711 Cudd_RecursiveDerefZdd( dd, zPlus );
712 return NULL;
713 }
714 cuddRef( zRes );
715 Cudd_RecursiveDerefZdd( dd, zTemp );
716 Cudd_RecursiveDerefZdd( dd, zPlus );
717 }
718
719 // only zRes is referenced at this point
720
721 // if we skipped some variables, these variables cannot be symmetric with
722 // any variables that are currently in the support of bF, but they can be
723 // symmetric with the variables that are in bVars but not in the support of bF
724 if ( nVarsExtra )
725 {
726 // it is possible to improve this step:
727 // (1) there is no need to enter here, if nVarsExtra < 2
728
729 // create the set of topmost nVarsExtra in bVars
730 DdNode * bVarsExtra;
731 int nVars;
732
733 // remove from bVars all the variable that are in the support of bFunc
734 bVarsExtra = extraBddReduceVarSet( dd, bVars, bFunc );
735 if ( bVarsExtra == NULL )
736 {
737 Cudd_RecursiveDerefZdd( dd, zRes );
738 return NULL;
739 }
740 cuddRef( bVarsExtra );
741
742 // determine how many vars are in the bVarsExtra
743 nVars = Extra_bddSuppSize( dd, bVarsExtra );
744 if ( nVars < 2 )
745 {
746 Cudd_RecursiveDeref( dd, bVarsExtra );
747 }
748 else
749 {
750 int i;
751 DdNode * bVarsK;
752
753 // create the BDD bVarsK corresponding to K = 2;
754 bVarsK = bVarsExtra;
755 for ( i = 0; i < nVars-2; i++ )
756 bVarsK = cuddT( bVarsK );
757
758 // create the 2 variable tuples
759 zPlus = extraZddTuplesFromBdd( dd, bVarsK, bVarsExtra );
760 if ( zPlus == NULL )
761 {
762 Cudd_RecursiveDeref( dd, bVarsExtra );
763 Cudd_RecursiveDerefZdd( dd, zRes );
764 return NULL;
765 }
766 cuddRef( zPlus );
767 Cudd_RecursiveDeref( dd, bVarsExtra );
768
769 // add these to the result
770 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
771 if ( zRes == NULL )
772 {
773 Cudd_RecursiveDerefZdd( dd, zTemp );
774 Cudd_RecursiveDerefZdd( dd, zPlus );
775 return NULL;
776 }
777 cuddRef( zRes );
778 Cudd_RecursiveDerefZdd( dd, zTemp );
779 Cudd_RecursiveDerefZdd( dd, zPlus );
780 }
781 }
782 cuddDeref( zRes );
783
784
785 /* insert the result into cache */
786 cuddCacheInsert2(dd, extraZddSymmPairsCompute, bFunc, bVars, zRes);
787 return zRes;
788 }
789} /* end of extraZddSymmPairsCompute */
DdNode * extraZddSymmPairsCompute(DdManager *dd, DdNode *bF, DdNode *bVars)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraZddTuplesFromBdd()

DdNode * extraZddTuplesFromBdd ( DdManager * dd,
DdNode * bVarsK,
DdNode * bVarsN )
extern

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

Synopsis [Performs the reordering-sensitive step of Extra_zddTupleFromBdd().]

Description [Generates in a bottom-up fashion ZDD for all combinations composed of k variables out of variables belonging to Support.]

SideEffects []

SeeAlso []

Definition at line 1341 of file extraBddSymm.c.

1345{
1346 DdNode *zRes, *zRes0, *zRes1;
1347 statLine(dd);
1348
1349 /* terminal cases */
1350/* if ( k < 0 || k > n )
1351 * return dd->zero;
1352 * if ( n == 0 )
1353 * return dd->one;
1354 */
1355 if ( cuddI( dd, bVarsK->index ) < cuddI( dd, bVarsN->index ) )
1356 return z0;
1357 if ( bVarsN == b1 )
1358 return z1;
1359
1360 /* check cache */
1361 zRes = cuddCacheLookup2Zdd(dd, extraZddTuplesFromBdd, bVarsK, bVarsN);
1362 if (zRes)
1363 return(zRes);
1364
1365 /* ZDD in which this variable is 0 */
1366/* zRes0 = extraZddTuplesFromBdd( dd, k, n-1 ); */
1367 zRes0 = extraZddTuplesFromBdd( dd, bVarsK, cuddT(bVarsN) );
1368 if ( zRes0 == NULL )
1369 return NULL;
1370 cuddRef( zRes0 );
1371
1372 /* ZDD in which this variable is 1 */
1373/* zRes1 = extraZddTuplesFromBdd( dd, k-1, n-1 ); */
1374 if ( bVarsK == b1 )
1375 {
1376 zRes1 = z0;
1377 cuddRef( zRes1 );
1378 }
1379 else
1380 {
1381 zRes1 = extraZddTuplesFromBdd( dd, cuddT(bVarsK), cuddT(bVarsN) );
1382 if ( zRes1 == NULL )
1383 {
1384 Cudd_RecursiveDerefZdd( dd, zRes0 );
1385 return NULL;
1386 }
1387 cuddRef( zRes1 );
1388 }
1389
1390 /* compose Res0 and Res1 with the given ZDD variable */
1391 zRes = cuddZddGetNode( dd, 2*bVarsN->index, zRes1, zRes0 );
1392 if ( zRes == NULL )
1393 {
1394 Cudd_RecursiveDerefZdd( dd, zRes0 );
1395 Cudd_RecursiveDerefZdd( dd, zRes1 );
1396 return NULL;
1397 }
1398 cuddDeref( zRes0 );
1399 cuddDeref( zRes1 );
1400
1401 /* insert the result into cache */
1402 cuddCacheInsert2(dd, extraZddTuplesFromBdd, bVarsK, bVarsN, zRes);
1403 return zRes;
1404
1405} /* end of extraZddTuplesFromBdd */
DdNode * extraZddTuplesFromBdd(DdManager *dd, DdNode *bVarsK, DdNode *bVarsN)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ extraZddUnateInfoCompute()

DdNode * extraZddUnateInfoCompute ( DdManager * dd,
DdNode * bFunc,
DdNode * bVars )
extern

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

Synopsis [Performs a recursive step of Extra_UnateInfoCompute.]

Description [Returns the set of symmetric variable pairs represented as a set of two-literal ZDD cubes. Both variables always appear in the positive polarity in the cubes. This function works without building new BDD nodes. Some relatively small number of ZDD nodes may be built to ensure proper bookkeeping of the symmetry information.]

SideEffects []

SeeAlso []

Definition at line 385 of file extraBddUnate.c.

389{
390 DdNode * zRes;
391 DdNode * bFR = Cudd_Regular(bFunc);
392
393 if ( cuddIsConstant(bFR) )
394 {
395 if ( cuddIsConstant(bVars) )
396 return z0;
397 return extraZddGetSingletonsBoth( dd, bVars );
398 }
399 assert( bVars != b1 );
400
401 if ( (zRes = cuddCacheLookup2Zdd(dd, extraZddUnateInfoCompute, bFunc, bVars)) )
402 return zRes;
403 else
404 {
405 DdNode * zRes0, * zRes1;
406 DdNode * zTemp, * zPlus;
407 DdNode * bF0, * bF1;
408 DdNode * bVarsNew;
409 int nVarsExtra;
410 int LevelF;
411 int AddVar;
412
413 // every variable in bF should be also in bVars, therefore LevelF cannot be above LevelV
414 // if LevelF is below LevelV, scroll through the vars in bVars to the same level as F
415 // count how many extra vars are there in bVars
416 nVarsExtra = 0;
417 LevelF = dd->perm[bFR->index];
418 for ( bVarsNew = bVars; LevelF > dd->perm[bVarsNew->index]; bVarsNew = cuddT(bVarsNew) )
419 nVarsExtra++;
420 // the indexes (level) of variables should be synchronized now
421 assert( bFR->index == bVarsNew->index );
422
423 // cofactor the function
424 if ( bFR != bFunc ) // bFunc is complemented
425 {
426 bF0 = Cudd_Not( cuddE(bFR) );
427 bF1 = Cudd_Not( cuddT(bFR) );
428 }
429 else
430 {
431 bF0 = cuddE(bFR);
432 bF1 = cuddT(bFR);
433 }
434
435 // solve subproblems
436 zRes0 = extraZddUnateInfoCompute( dd, bF0, cuddT(bVarsNew) );
437 if ( zRes0 == NULL )
438 return NULL;
439 cuddRef( zRes0 );
440
441 // if there is no symmetries in the negative cofactor
442 // there is no need to test the positive cofactor
443 if ( zRes0 == z0 )
444 zRes = zRes0; // zRes takes reference
445 else
446 {
447 zRes1 = extraZddUnateInfoCompute( dd, bF1, cuddT(bVarsNew) );
448 if ( zRes1 == NULL )
449 {
450 Cudd_RecursiveDerefZdd( dd, zRes0 );
451 return NULL;
452 }
453 cuddRef( zRes1 );
454
455 // only those variables are pair-wise symmetric
456 // that are pair-wise symmetric in both cofactors
457 // therefore, intersect the solutions
458 zRes = cuddZddIntersect( dd, zRes0, zRes1 );
459 if ( zRes == NULL )
460 {
461 Cudd_RecursiveDerefZdd( dd, zRes0 );
462 Cudd_RecursiveDerefZdd( dd, zRes1 );
463 return NULL;
464 }
465 cuddRef( zRes );
466 Cudd_RecursiveDerefZdd( dd, zRes0 );
467 Cudd_RecursiveDerefZdd( dd, zRes1 );
468 }
469
470 // consider the current top-most variable
471 AddVar = -1;
472 if ( Cudd_bddLeq( dd, bF0, bF1 ) ) // pos
473 AddVar = 0;
474 else if ( Cudd_bddLeq( dd, bF1, bF0 ) ) // neg
475 AddVar = 1;
476 if ( AddVar >= 0 )
477 {
478 // create the singleton
479 zPlus = cuddZddGetNode( dd, 2*bFR->index + AddVar, z1, z0 );
480 if ( zPlus == NULL )
481 {
482 Cudd_RecursiveDerefZdd( dd, zRes );
483 return NULL;
484 }
485 cuddRef( zPlus );
486
487 // add these to the result
488 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
489 if ( zRes == NULL )
490 {
491 Cudd_RecursiveDerefZdd( dd, zTemp );
492 Cudd_RecursiveDerefZdd( dd, zPlus );
493 return NULL;
494 }
495 cuddRef( zRes );
496 Cudd_RecursiveDerefZdd( dd, zTemp );
497 Cudd_RecursiveDerefZdd( dd, zPlus );
498 }
499 // only zRes is referenced at this point
500
501 // if we skipped some variables, these variables cannot be symmetric with
502 // any variables that are currently in the support of bF, but they can be
503 // symmetric with the variables that are in bVars but not in the support of bF
504 for ( bVarsNew = bVars; LevelF > dd->perm[bVarsNew->index]; bVarsNew = cuddT(bVarsNew) )
505 {
506 // create the negative singleton
507 zPlus = cuddZddGetNode( dd, 2*bVarsNew->index+1, z1, z0 );
508 if ( zPlus == NULL )
509 {
510 Cudd_RecursiveDerefZdd( dd, zRes );
511 return NULL;
512 }
513 cuddRef( zPlus );
514
515 // add these to the result
516 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
517 if ( zRes == NULL )
518 {
519 Cudd_RecursiveDerefZdd( dd, zTemp );
520 Cudd_RecursiveDerefZdd( dd, zPlus );
521 return NULL;
522 }
523 cuddRef( zRes );
524 Cudd_RecursiveDerefZdd( dd, zTemp );
525 Cudd_RecursiveDerefZdd( dd, zPlus );
526
527
528 // create the positive singleton
529 zPlus = cuddZddGetNode( dd, 2*bVarsNew->index, z1, z0 );
530 if ( zPlus == NULL )
531 {
532 Cudd_RecursiveDerefZdd( dd, zRes );
533 return NULL;
534 }
535 cuddRef( zPlus );
536
537 // add these to the result
538 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
539 if ( zRes == NULL )
540 {
541 Cudd_RecursiveDerefZdd( dd, zTemp );
542 Cudd_RecursiveDerefZdd( dd, zPlus );
543 return NULL;
544 }
545 cuddRef( zRes );
546 Cudd_RecursiveDerefZdd( dd, zTemp );
547 Cudd_RecursiveDerefZdd( dd, zPlus );
548 }
549 cuddDeref( zRes );
550
551 /* insert the result into cache */
552 cuddCacheInsert2(dd, extraZddUnateInfoCompute, bFunc, bVars, zRes);
553 return zRes;
554 }
555} /* end of extraZddUnateInfoCompute */
DdNode * extraZddUnateInfoCompute(DdManager *dd, DdNode *bF, DdNode *bVars)
Here is the call graph for this function:
Here is the caller graph for this function: