src/misc/extra/extra.h File Reference

#include "leaks.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <time.h>
#include "st.h"
#include "cuddInt.h"
Include dependency graph for extra.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  Extra_SymmInfo_t_
struct  Extra_UnateVar_t_
struct  Extra_UnateInfo_t_

Defines

#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)   ((unsigned)(a) % TSIZE)
#define hashKey2(a, b, TSIZE)   (((unsigned)(a) + (unsigned)(b) * DD_P1) % TSIZE)
#define hashKey3(a, b, c, TSIZE)   (((((unsigned)(a) + (unsigned)(b)) * DD_P1 + (unsigned)(c)) * DD_P2 ) % TSIZE)
#define hashKey4(a, b, c, d, TSIZE)
#define hashKey5(a, b, c, d, e, TSIZE)
#define PRTP(a, t, T)   printf("%s = ", (a)); printf("%6.2f sec (%6.2f %%)\n", (float)(t)/(float)(CLOCKS_PER_SEC), (T)? 100.0*(t)/(T) : 0.0)

Typedefs

typedef unsigned char uint8
typedef unsigned short uint16
typedef unsigned int uint32
typedef unsigned long long uint64
typedef struct Extra_SymmInfo_t_ Extra_SymmInfo_t
typedef struct Extra_UnateVar_t_ Extra_UnateVar_t
typedef struct Extra_UnateInfo_t_ Extra_UnateInfo_t
typedef struct Extra_BitMat_t_ Extra_BitMat_t
typedef struct Extra_FileReader_t_ Extra_FileReader_t
typedef struct Extra_MmFixed_t_ Extra_MmFixed_t
typedef struct Extra_MmFlex_t_ Extra_MmFlex_t
typedef struct Extra_MmStep_t_ Extra_MmStep_t
typedef struct ProgressBarStruct ProgressBar

Functions

DdNodeExtra_bddSpaceFromFunctionFast (DdManager *dd, DdNode *bFunc)
DdNodeExtra_bddSpaceFromFunction (DdManager *dd, DdNode *bF, DdNode *bG)
DdNodeextraBddSpaceFromFunction (DdManager *dd, DdNode *bF, DdNode *bG)
DdNodeExtra_bddSpaceFromFunctionPos (DdManager *dd, DdNode *bFunc)
DdNodeextraBddSpaceFromFunctionPos (DdManager *dd, DdNode *bFunc)
DdNodeExtra_bddSpaceFromFunctionNeg (DdManager *dd, DdNode *bFunc)
DdNodeextraBddSpaceFromFunctionNeg (DdManager *dd, DdNode *bFunc)
DdNodeExtra_bddSpaceCanonVars (DdManager *dd, DdNode *bSpace)
DdNodeextraBddSpaceCanonVars (DdManager *dd, DdNode *bSpace)
DdNodeExtra_bddSpaceEquations (DdManager *dd, DdNode *bSpace)
DdNodeExtra_bddSpaceEquationsNeg (DdManager *dd, DdNode *bSpace)
DdNodeextraBddSpaceEquationsNeg (DdManager *dd, DdNode *bSpace)
DdNodeExtra_bddSpaceEquationsPos (DdManager *dd, DdNode *bSpace)
DdNodeextraBddSpaceEquationsPos (DdManager *dd, DdNode *bSpace)
DdNodeExtra_bddSpaceFromMatrixPos (DdManager *dd, DdNode *zA)
DdNodeextraBddSpaceFromMatrixPos (DdManager *dd, DdNode *zA)
DdNodeExtra_bddSpaceFromMatrixNeg (DdManager *dd, DdNode *zA)
DdNodeextraBddSpaceFromMatrixNeg (DdManager *dd, DdNode *zA)
DdNodeExtra_bddSpaceReduce (DdManager *dd, DdNode *bFunc, DdNode *bCanonVars)
DdNode ** Extra_bddSpaceExorGates (DdManager *dd, DdNode *bFuncRed, DdNode *zEquations)
DdNodeExtra_bddEncodingBinary (DdManager *dd, DdNode **pbFuncs, int nFuncs, DdNode **pbVars, int nVars)
DdNodeExtra_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)
DdNodeExtra_TransferPermute (DdManager *ddSource, DdManager *ddDestination, DdNode *f, int *Permute)
DdNodeExtra_TransferLevelByLevel (DdManager *ddSource, DdManager *ddDestination, DdNode *f)
DdNodeExtra_bddRemapUp (DdManager *dd, DdNode *bF)
DdNodeExtra_bddMove (DdManager *dd, DdNode *bF, int fShiftUp)
DdNodeextraBddMove (DdManager *dd, DdNode *bF, DdNode *bFlag)
void Extra_StopManager (DdManager *dd)
void Extra_bddPrint (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)
DdNodeExtra_bddFindOneCube (DdManager *dd, DdNode *bF)
DdNodeExtra_bddGetOneCube (DdManager *dd, DdNode *bFunc)
DdNodeExtra_bddComputeRangeCube (DdManager *dd, int iStart, int iStop)
DdNodeExtra_bddBitsToCube (DdManager *dd, int Code, int CodeWidth, DdNode **pbVars, int fMsbFirst)
DdNodeExtra_bddSupportNegativeCube (DdManager *dd, DdNode *f)
int Extra_bddIsVar (DdNode *bFunc)
DdNodeExtra_bddCreateAnd (DdManager *dd, int nVars)
DdNodeExtra_bddCreateOr (DdManager *dd, int nVars)
DdNodeExtra_bddCreateExor (DdManager *dd, int nVars)
DdNodeExtra_zddPrimes (DdManager *dd, DdNode *F)
void Extra_bddPermuteArray (DdManager *dd, DdNode **bNodesIn, DdNode **bNodesOut, int nNodes, int *permut)
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)
DdNodeExtra_zddSymmPairsCompute (DdManager *dd, DdNode *bF, DdNode *bVars)
DdNodeextraZddSymmPairsCompute (DdManager *dd, DdNode *bF, DdNode *bVars)
DdNodeExtra_zddGetSymmetricVars (DdManager *dd, DdNode *bF, DdNode *bG, DdNode *bVars)
DdNodeextraZddGetSymmetricVars (DdManager *dd, DdNode *bF, DdNode *bG, DdNode *bVars)
DdNodeExtra_zddGetSingletons (DdManager *dd, DdNode *bVars)
DdNodeextraZddGetSingletons (DdManager *dd, DdNode *bVars)
DdNodeExtra_bddReduceVarSet (DdManager *dd, DdNode *bVars, DdNode *bF)
DdNodeextraBddReduceVarSet (DdManager *dd, DdNode *bVars, DdNode *bF)
int Extra_bddCheckVarsSymmetric (DdManager *dd, DdNode *bF, int iVar1, int iVar2)
DdNodeextraBddCheckVarsSymmetric (DdManager *dd, DdNode *bF, DdNode *bVars)
DdNodeExtra_zddTuplesFromBdd (DdManager *dd, int K, DdNode *bVarsN)
DdNodeextraZddTuplesFromBdd (DdManager *dd, DdNode *bVarsK, DdNode *bVarsN)
DdNodeExtra_zddSelectOneSubset (DdManager *dd, DdNode *zS)
DdNodeextraZddSelectOneSubset (DdManager *dd, DdNode *zS)
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)
DdNodeExtra_zddUnateInfoCompute (DdManager *dd, DdNode *bF, DdNode *bVars)
DdNodeextraZddUnateInfoCompute (DdManager *dd, DdNode *bF, DdNode *bVars)
DdNodeExtra_zddGetSingletonsBoth (DdManager *dd, DdNode *bVars)
DdNodeextraZddGetSingletonsBoth (DdManager *dd, DdNode *bVars)
Extra_BitMat_tExtra_BitMatrixStart (int nSize)
void Extra_BitMatrixClean (Extra_BitMat_t *p)
void Extra_BitMatrixStop (Extra_BitMat_t *p)
void Extra_BitMatrixPrint (Extra_BitMat_t *p)
int Extra_BitMatrixReadSize (Extra_BitMat_t *p)
void Extra_BitMatrixInsert1 (Extra_BitMat_t *p, int i, int k)
int Extra_BitMatrixLookup1 (Extra_BitMat_t *p, int i, int k)
void Extra_BitMatrixDelete1 (Extra_BitMat_t *p, int i, int k)
void Extra_BitMatrixInsert2 (Extra_BitMat_t *p, int i, int k)
int Extra_BitMatrixLookup2 (Extra_BitMat_t *p, int i, int k)
void Extra_BitMatrixDelete2 (Extra_BitMat_t *p, int i, int k)
void Extra_BitMatrixOr (Extra_BitMat_t *p, int i, unsigned *pInfo)
void Extra_BitMatrixOrTwo (Extra_BitMat_t *p, int i, int j)
int Extra_BitMatrixCountOnesUpper (Extra_BitMat_t *p)
int Extra_BitMatrixIsDisjoint (Extra_BitMat_t *p1, Extra_BitMat_t *p2)
int Extra_BitMatrixIsClique (Extra_BitMat_t *p)
char * Extra_FileGetSimilarName (char *pFileNameWrong, char *pS1, char *pS2, char *pS3, char *pS4, char *pS5)
char * Extra_FileNameExtension (char *FileName)
char * Extra_FileNameAppend (char *pBase, char *pSuffix)
char * Extra_FileNameGeneric (char *FileName)
int Extra_FileSize (char *pFileName)
char * Extra_FileRead (FILE *pFile)
char * Extra_TimeStamp ()
char * Extra_StringAppend (char *pStrGiven, char *pStrAdd)
unsigned Extra_ReadBinary (char *Buffer)
void Extra_PrintBinary (FILE *pFile, unsigned Sign[], int nBits)
int Extra_ReadHexadecimal (unsigned Sign[], char *pString, int nVars)
void Extra_PrintHexadecimal (FILE *pFile, unsigned Sign[], int nVars)
void Extra_PrintHexadecimalString (char *pString, unsigned Sign[], int nVars)
void Extra_PrintHex (FILE *pFile, unsigned uTruth, int nVars)
void Extra_PrintSymbols (FILE *pFile, char Char, int nTimes, int fPrintNewLine)
Extra_FileReader_tExtra_FileReaderAlloc (char *pFileName, char *pCharsComment, char *pCharsStop, char *pCharsClean)
void Extra_FileReaderFree (Extra_FileReader_t *p)
char * Extra_FileReaderGetFileName (Extra_FileReader_t *p)
int Extra_FileReaderGetFileSize (Extra_FileReader_t *p)
int Extra_FileReaderGetCurPosition (Extra_FileReader_t *p)
void * Extra_FileReaderGetTokens (Extra_FileReader_t *p)
int Extra_FileReaderGetLineNumber (Extra_FileReader_t *p, int iToken)
Extra_MmFixed_tExtra_MmFixedStart (int nEntrySize)
void Extra_MmFixedStop (Extra_MmFixed_t *p)
char * Extra_MmFixedEntryFetch (Extra_MmFixed_t *p)
void Extra_MmFixedEntryRecycle (Extra_MmFixed_t *p, char *pEntry)
void Extra_MmFixedRestart (Extra_MmFixed_t *p)
int Extra_MmFixedReadMemUsage (Extra_MmFixed_t *p)
int Extra_MmFixedReadMaxEntriesUsed (Extra_MmFixed_t *p)
Extra_MmFlex_tExtra_MmFlexStart ()
void Extra_MmFlexStop (Extra_MmFlex_t *p)
void Extra_MmFlexPrint (Extra_MmFlex_t *p)
char * Extra_MmFlexEntryFetch (Extra_MmFlex_t *p, int nBytes)
int Extra_MmFlexReadMemUsage (Extra_MmFlex_t *p)
Extra_MmStep_tExtra_MmStepStart (int nSteps)
void Extra_MmStepStop (Extra_MmStep_t *p)
char * Extra_MmStepEntryFetch (Extra_MmStep_t *p, int nBytes)
void Extra_MmStepEntryRecycle (Extra_MmStep_t *p, char *pEntry, int nBytes)
int Extra_MmStepReadMemUsage (Extra_MmStep_t *p)
int Extra_Base2Log (unsigned Num)
int Extra_Base2LogDouble (double Num)
int Extra_Base10Log (unsigned Num)
double Extra_Power2 (int Num)
int Extra_Power3 (int Num)
int Extra_NumCombinations (int k, int n)
int * Extra_DeriveRadixCode (int Number, int Radix, int nDigits)
int Extra_CountOnes (unsigned char *pBytes, int nBytes)
int Extra_Factorial (int n)
char ** Extra_Permutations (int n)
unsigned Extra_TruthPermute (unsigned Truth, char *pPerms, int nVars, int fReverse)
unsigned Extra_TruthPolarize (unsigned uTruth, int Polarity, int nVars)
unsigned Extra_TruthCanonN (unsigned uTruth, int nVars)
unsigned Extra_TruthCanonNN (unsigned uTruth, int nVars)
unsigned Extra_TruthCanonP (unsigned uTruth, int nVars)
unsigned Extra_TruthCanonNP (unsigned uTruth, int nVars)
unsigned Extra_TruthCanonNPN (unsigned uTruth, int nVars)
void Extra_Truth4VarNPN (unsigned short **puCanons, char **puPhases, char **puPerms, unsigned char **puMap)
void Extra_Truth4VarN (unsigned short **puCanons, char ***puPhases, char **ppCounters, int nPhasesMax)
unsigned short Extra_TruthPerm4One (unsigned uTruth, int Phase)
unsigned Extra_TruthPerm5One (unsigned uTruth, int Phase)
void Extra_TruthPerm6One (unsigned *uTruth, int Phase, unsigned *uTruthRes)
void Extra_TruthExpand (int nVars, int nWords, unsigned *puTruth, unsigned uPhase, unsigned *puTruthR)
void ** Extra_ArrayAlloc (int nCols, int nRows, int Size)
unsigned short ** Extra_TruthPerm43 ()
unsigned ** Extra_TruthPerm53 ()
unsigned ** Extra_TruthPerm54 ()
void Extra_BubbleSort (int Order[], int Costs[], int nSize, int fIncreasing)
unsigned int Cudd_PrimeCopy (unsigned int p)
int Extra_TruthCanonFastN (int nVarsMax, int nVarsReal, unsigned *pt, unsigned **pptRes, char **ppfRes)
ProgressBarExtra_ProgressBarStart (FILE *pFile, int nItemsTotal)
void Extra_ProgressBarStop (ProgressBar *p)
void Extra_ProgressBarUpdate_int (ProgressBar *p, int nItemsCur, char *pString)
static void Extra_ProgressBarUpdate (ProgressBar *p, int nItemsCur, char *pString)
static int Extra_Float2Int (float Val)
static float Extra_Int2Float (int Num)
static int Extra_BitWordNum (int nBits)
static int Extra_TruthWordNum (int nVars)
static void Extra_TruthSetBit (unsigned *p, int Bit)
static void Extra_TruthXorBit (unsigned *p, int Bit)
static int Extra_TruthHasBit (unsigned *p, int Bit)
static int Extra_WordCountOnes (unsigned uWord)
static int Extra_TruthCountOnes (unsigned *pIn, int nVars)
static int Extra_TruthIsEqual (unsigned *pIn0, unsigned *pIn1, int nVars)
static int Extra_TruthIsConst0 (unsigned *pIn, int nVars)
static int Extra_TruthIsConst1 (unsigned *pIn, int nVars)
static int Extra_TruthIsImply (unsigned *pIn1, unsigned *pIn2, int nVars)
static void Extra_TruthCopy (unsigned *pOut, unsigned *pIn, int nVars)
static void Extra_TruthClear (unsigned *pOut, int nVars)
static void Extra_TruthFill (unsigned *pOut, int nVars)
static void Extra_TruthNot (unsigned *pOut, unsigned *pIn, int nVars)
static void Extra_TruthAnd (unsigned *pOut, unsigned *pIn0, unsigned *pIn1, int nVars)
static void Extra_TruthOr (unsigned *pOut, unsigned *pIn0, unsigned *pIn1, int nVars)
static void Extra_TruthSharp (unsigned *pOut, unsigned *pIn0, unsigned *pIn1, int nVars)
static void Extra_TruthNand (unsigned *pOut, unsigned *pIn0, unsigned *pIn1, int nVars)
static void Extra_TruthAndPhase (unsigned *pOut, unsigned *pIn0, unsigned *pIn1, int nVars, int fCompl0, int fCompl1)
unsigned ** Extra_TruthElementary (int nVars)
void Extra_TruthSwapAdjacentVars (unsigned *pOut, unsigned *pIn, int nVars, int Start)
void Extra_TruthStretch (unsigned *pOut, unsigned *pIn, int nVars, int nVarsAll, unsigned Phase)
void Extra_TruthShrink (unsigned *pOut, unsigned *pIn, int nVars, int nVarsAll, unsigned Phase)
int Extra_TruthVarInSupport (unsigned *pTruth, int nVars, int iVar)
int Extra_TruthSupportSize (unsigned *pTruth, int nVars)
int Extra_TruthSupport (unsigned *pTruth, int nVars)
void Extra_TruthCofactor0 (unsigned *pTruth, int nVars, int iVar)
void Extra_TruthCofactor1 (unsigned *pTruth, int nVars, int iVar)
void Extra_TruthExist (unsigned *pTruth, int nVars, int iVar)
void Extra_TruthForall (unsigned *pTruth, int nVars, int iVar)
void Extra_TruthMux (unsigned *pOut, unsigned *pCof0, unsigned *pCof1, int nVars, int iVar)
void Extra_TruthChangePhase (unsigned *pTruth, int nVars, int iVar)
int Extra_TruthMinCofSuppOverlap (unsigned *pTruth, int nVars, int *pVarMin)
void Extra_TruthCountOnesInCofs (unsigned *pTruth, int nVars, short *pStore)
unsigned Extra_TruthHash (unsigned *pIn, int nWords)
unsigned Extra_TruthSemiCanonicize (unsigned *pInOut, unsigned *pAux, int nVars, char *pCanonPerm, short *pStore)
long Extra_CpuTime ()
int Extra_GetSoftDataLimit ()
void Extra_UtilGetoptReset ()
int Extra_UtilGetopt (int argc, char *argv[], char *optstring)
char * Extra_UtilPrintTime (long t)
char * Extra_UtilStrsav (char *s)
char * Extra_UtilTildeExpand (char *fname)
char * Extra_UtilFileSearch (char *file, char *path, char *mode)

Variables

void(* Extra_UtilMMoutOfMemory )()
char * globalUtilOptarg
int globalUtilOptind

Define Documentation

#define a0   (dd)->zero

Definition at line 90 of file extra.h.

#define a1   (dd)->one

Definition at line 91 of file extra.h.

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

Definition at line 86 of file extra.h.

#define b1   (dd)->one

Definition at line 87 of file extra.h.

#define hashKey1 ( a,
TSIZE   )     ((unsigned)(a) % TSIZE)

Definition at line 94 of file extra.h.

#define hashKey2 ( a,
b,
TSIZE   )     (((unsigned)(a) + (unsigned)(b) * DD_P1) % TSIZE)

Definition at line 97 of file extra.h.

#define hashKey3 ( a,
b,
c,
TSIZE   )     (((((unsigned)(a) + (unsigned)(b)) * DD_P1 + (unsigned)(c)) * DD_P2 ) % TSIZE)

Definition at line 100 of file extra.h.

#define hashKey4 ( a,
b,
c,
d,
TSIZE   ) 
Value:
((((((unsigned)(a) + (unsigned)(b)) * DD_P1 + (unsigned)(c)) * DD_P2 + \
   (unsigned)(d)) * DD_P3) % TSIZE)

Definition at line 103 of file extra.h.

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

Definition at line 107 of file extra.h.

#define PRTP ( a,
t,
 )     printf("%s = ", (a)); printf("%6.2f sec (%6.2f %%)\n", (float)(t)/(float)(CLOCKS_PER_SEC), (T)? 100.0*(t)/(T) : 0.0)

Definition at line 117 of file extra.h.

#define z0   (dd)->zero

Definition at line 88 of file extra.h.

#define z1   (dd)->one

Definition at line 89 of file extra.h.


Typedef Documentation

Definition at line 293 of file extra.h.

Definition at line 331 of file extra.h.

Definition at line 343 of file extra.h.

Definition at line 344 of file extra.h.

Definition at line 345 of file extra.h.

Definition at line 202 of file extra.h.

Definition at line 260 of file extra.h.

Definition at line 253 of file extra.h.

Definition at line 420 of file extra.h.

typedef unsigned short uint16

Definition at line 77 of file extra.h.

typedef unsigned int uint32

Definition at line 78 of file extra.h.

typedef unsigned long long uint64

Definition at line 82 of file extra.h.

typedef unsigned char uint8

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

FileName [extra.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
extra.h,v 1.00 2005/06/20 00:00:00 alanmi Exp

]

Definition at line 76 of file extra.h.


Function Documentation

unsigned int Cudd_PrimeCopy ( unsigned int  p  ) 

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

Synopsis [Returns the smallest prime larger than the number.]

Description []

SideEffects []

SeeAlso []

Definition at line 2131 of file extraUtilMisc.c.

02132 {
02133     int i,pn;
02134 
02135     p--;
02136     do {
02137         p++;
02138         if (p&1) {
02139             pn = 1;
02140             i = 3;
02141             while ((unsigned) (i * i) <= p) {
02142                 if (p % i == 0) {
02143                     pn = 0;
02144                     break;
02145                 }
02146                 i += 2;
02147             }
02148         } else {
02149             pn = 0;
02150         }
02151     } while (!pn);
02152     return(p);
02153 
02154 } /* end of Cudd_Prime */

void** Extra_ArrayAlloc ( int  nCols,
int  nRows,
int  Size 
)

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

Synopsis [Allocated one-memory-chunk array.]

Description []

SideEffects []

SeeAlso []

Definition at line 918 of file extraUtilMisc.c.

00919 {
00920     char ** pRes;
00921     char * pBuffer;
00922     int i;
00923     assert( nCols > 0 && nRows > 0 && Size > 0 );
00924     pBuffer = ALLOC( char, nCols * (sizeof(void *) + nRows * Size) );
00925     pRes = (char **)pBuffer;
00926     pRes[0] = pBuffer + nCols * sizeof(void *);
00927     for ( i = 1; i < nCols; i++ )
00928         pRes[i] = pRes[0] + i * nRows * Size;
00929     return pRes;
00930 }

int Extra_Base10Log ( unsigned  Num  ) 

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

Synopsis [Finds the smallest integer larger of equal than the logarithm.]

Description [Returns [Log10(Num)].]

SideEffects []

SeeAlso []

Definition at line 115 of file extraUtilMisc.c.

00116 {
00117     int Res;
00118     assert( Num >= 0 );
00119     if ( Num == 0 ) return 0;
00120     if ( Num == 1 ) return 1;
00121         for ( Res = 0, Num--;  Num;  Num /= 10,  Res++ );
00122     return Res;
00123 } /* end of Extra_Base2Log */

int Extra_Base2Log ( unsigned  Num  ) 

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

Synopsis [Finds the smallest integer larger of equal than the logarithm.]

Description [Returns [Log2(Num)].]

SideEffects []

SeeAlso []

Definition at line 70 of file extraUtilMisc.c.

00071 {
00072     int Res;
00073     assert( Num >= 0 );
00074     if ( Num == 0 ) return 0;
00075     if ( Num == 1 ) return 1;
00076     for ( Res = 0, Num--; Num; Num >>= 1, Res++ );
00077     return Res;
00078 } /* end of Extra_Base2Log */

int Extra_Base2LogDouble ( double  Num  ) 

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

Synopsis [Finds the smallest integer larger of equal than the logarithm.]

Description []

SideEffects []

SeeAlso []

Definition at line 91 of file extraUtilMisc.c.

00092 {
00093     double Res;
00094     int ResInt;
00095 
00096     Res    = log(Num)/log(2.0);
00097     ResInt = (int)Res;
00098     if ( ResInt == Res )
00099         return ResInt;
00100     else 
00101         return ResInt+1;
00102 }

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

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 704 of file extraBddMisc.c.

00705 {
00706     int z;
00707     DdNode * bTemp, * bVar, * bVarBdd, * bResult;
00708 
00709     bResult = b1;   Cudd_Ref( bResult );
00710     for ( z = 0; z < CodeWidth; z++ )
00711     {
00712         bVarBdd = (pbVars)? pbVars[z]: dd->vars[z];
00713         if ( fMsbFirst )
00714             bVar = Cudd_NotCond( bVarBdd, (Code & (1 << (CodeWidth-1-z)))==0 );
00715         else
00716             bVar = Cudd_NotCond( bVarBdd, (Code & (1 << (z)))==0 );
00717         bResult = Cudd_bddAnd( dd, bTemp = bResult, bVar );     Cudd_Ref( bResult );
00718         Cudd_RecursiveDeref( dd, bTemp );
00719     }
00720     Cudd_Deref( bResult );
00721 
00722     return bResult;
00723 }  /* end of Extra_bddBitsToCube */

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

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 335 of file extraBddUnate.c.

00339 {
00340     DdNode * bCof0, * bCof1;
00341     int Res;
00342 
00343     assert( iVar < dd->size );
00344 
00345     bCof0 = Cudd_Cofactor( dd, bF, Cudd_Not(Cudd_bddIthVar(dd,iVar)) );  Cudd_Ref( bCof0 );
00346     bCof1 = Cudd_Cofactor( dd, bF, Cudd_bddIthVar(dd,iVar) );            Cudd_Ref( bCof1 );
00347 
00348     if ( Cudd_bddLeq( dd, bCof0, bCof1 ) )
00349         Res = 1;
00350     else if ( Cudd_bddLeq( dd, bCof1, bCof0 ) )
00351         Res =-1;
00352     else
00353         Res = 0;
00354 
00355     Cudd_RecursiveDeref( dd, bCof0 );
00356     Cudd_RecursiveDeref( dd, bCof1 );
00357     return Res;
00358 } /* end of Extra_bddCheckUnateNaive */

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

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 357 of file extraBddSymm.c.

00362 {
00363     DdNode * bVars;
00364     int Res;
00365 
00366 //  return 1;
00367 
00368     assert( iVar1 != iVar2 );
00369     assert( iVar1 < dd->size );
00370     assert( iVar2 < dd->size );
00371 
00372     bVars = Cudd_bddAnd( dd, dd->vars[iVar1], dd->vars[iVar2] );   Cudd_Ref( bVars );
00373 
00374     Res = (int)( extraBddCheckVarsSymmetric( dd, bF, bVars ) == b1 );
00375 
00376     Cudd_RecursiveDeref( dd, bVars );
00377 
00378     return Res;
00379 } /* end of Extra_bddCheckVarsSymmetric */

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

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 440 of file extraBddSymm.c.

00445 {
00446     DdNode * bCube1, * bCube2;
00447     DdNode * bCof01, * bCof10;
00448     int Res;
00449 
00450     assert( iVar1 != iVar2 );
00451     assert( iVar1 < dd->size );
00452     assert( iVar2 < dd->size );
00453 
00454     bCube1 = Cudd_bddAnd( dd, Cudd_Not( dd->vars[iVar1] ), dd->vars[iVar2] );   Cudd_Ref( bCube1 );
00455     bCube2 = Cudd_bddAnd( dd, Cudd_Not( dd->vars[iVar2] ), dd->vars[iVar1] );   Cudd_Ref( bCube2 );
00456 
00457     bCof01 = Cudd_Cofactor( dd, bF, bCube1 );  Cudd_Ref( bCof01 );
00458     bCof10 = Cudd_Cofactor( dd, bF, bCube2 );  Cudd_Ref( bCof10 );
00459 
00460     Res = (int)( bCof10 == bCof01 );
00461 
00462     Cudd_RecursiveDeref( dd, bCof01 );
00463     Cudd_RecursiveDeref( dd, bCof10 );
00464     Cudd_RecursiveDeref( dd, bCube1 );
00465     Cudd_RecursiveDeref( dd, bCube2 );
00466 
00467     return Res;
00468 } /* end of Extra_bddCheckVarsSymmetricNaive */

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

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 673 of file extraBddMisc.c.

00674 {
00675     DdNode * bTemp, * bProd;
00676     int i;
00677     assert( iStart <= iStop );
00678     assert( iStart >= 0 && iStart <= dd->size );
00679     assert( iStop >= 0  && iStop  <= dd->size );
00680     bProd = b1;         Cudd_Ref( bProd );
00681     for ( i = iStart; i < iStop; i++ )
00682     {
00683         bProd = Cudd_bddAnd( dd, bTemp = bProd, dd->vars[i] );      Cudd_Ref( bProd );
00684         Cudd_RecursiveDeref( dd, bTemp ); 
00685     }
00686     Cudd_Deref( bProd );
00687     return bProd;
00688 }

DdNode* Extra_bddCreateAnd ( DdManager dd,
int  nVars 
)

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 832 of file extraBddMisc.c.

00833 {
00834     DdNode * bFunc, * bTemp;
00835     int i;
00836     bFunc = Cudd_ReadOne(dd); Cudd_Ref( bFunc );
00837     for ( i = 0; i < nVars; i++ )
00838     {
00839         bFunc = Cudd_bddAnd( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) );  Cudd_Ref( bFunc );
00840         Cudd_RecursiveDeref( dd, bTemp );
00841     }
00842     Cudd_Deref( bFunc );
00843     return bFunc;
00844 }

DdNode* Extra_bddCreateExor ( DdManager dd,
int  nVars 
)

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 882 of file extraBddMisc.c.

00883 {
00884     DdNode * bFunc, * bTemp;
00885     int i;
00886     bFunc = Cudd_ReadLogicZero(dd); Cudd_Ref( bFunc );
00887     for ( i = 0; i < nVars; i++ )
00888     {
00889         bFunc = Cudd_bddXor( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) );  Cudd_Ref( bFunc );
00890         Cudd_RecursiveDeref( dd, bTemp );
00891     }
00892     Cudd_Deref( bFunc );
00893     return bFunc;
00894 }

DdNode* Extra_bddCreateOr ( DdManager dd,
int  nVars 
)

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 857 of file extraBddMisc.c.

00858 {
00859     DdNode * bFunc, * bTemp;
00860     int i;
00861     bFunc = Cudd_ReadLogicZero(dd); Cudd_Ref( bFunc );
00862     for ( i = 0; i < nVars; i++ )
00863     {
00864         bFunc = Cudd_bddOr( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) );  Cudd_Ref( bFunc );
00865         Cudd_RecursiveDeref( dd, bTemp );
00866     }
00867     Cudd_Deref( bFunc );
00868     return bFunc;
00869 }

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

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 135 of file extraBddCas.c.

00141 {
00142         int i;
00143         DdNode * bResult;
00144         DdNode * bCube, * bTemp, * bProd;
00145 
00146         assert( nVars >= Extra_Base2Log(nFuncs) );
00147 
00148         bResult = b0;   Cudd_Ref( bResult );
00149         for ( i = 0; i < nFuncs; i++ )
00150         {
00151                 bCube   = Extra_bddBitsToCube( dd, i, nVars, pbVars, 1 );   Cudd_Ref( bCube );
00152                 bProd   = Cudd_bddAnd( dd, bCube, pbFuncs[i] );         Cudd_Ref( bProd );
00153                 Cudd_RecursiveDeref( dd, bCube );
00154 
00155                 bResult = Cudd_bddOr( dd, bProd, bTemp = bResult );     Cudd_Ref( bResult );
00156                 Cudd_RecursiveDeref( dd, bTemp );
00157                 Cudd_RecursiveDeref( dd, bProd );
00158         }
00159 
00160         Cudd_Deref( bResult );
00161         return bResult;
00162 } /* end of Extra_bddEncodingBinary */

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

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 181 of file extraBddCas.c.

00189 {
00190         DdNode * bEncoded, * bResult;
00191         int nVarsCol = Cudd_SupportSize(dd,bVarsCol);
00192         long clk;
00193 
00194         // cannot work with more that 32-bit codes
00195         assert( nMulti < 32 );
00196 
00197         // perform the preliminary encoding using the straight binary code
00198         bEncoded = Extra_bddEncodingBinary( dd, pbColumns, nColumns, pCVars, nMulti );   Cudd_Ref( bEncoded );
00199         //printf( "Node count = %d", Cudd_DagSize(bEncoded) );
00200 
00201         // set the backgroup value for counting minterms
00202         s_Terminal = b0;
00203         // set the level of the encoding variables
00204         s_EncodingVarsLevel = dd->invperm[pCVars[0]->index];
00205 
00206         // the current number of backtracks
00207         s_BackTracks = 0;
00208         // the variables that are cofactored on the topmost level where everything starts (no vars)
00209         s_Field[0][0] = b1;   
00210         // the size of the best set of "simple" encoding variables found so far
00211         s_nVarsBest   = 0;
00212 
00213     // set the relation to be accessible to traversal procedures
00214         s_Encoded = bEncoded;
00215         // the set of all vars to be accessible to traversal procedures
00216         s_VarAll  = bVarsCol;
00217         // the column multiplicity
00218         s_MultiStart  = nMulti;
00219 
00220 
00221         clk = clock();
00222         // find the simplest encoding
00223         if ( nColumns > 2 )
00224         EvaluateEncodings_rec( dd, bVarsCol, nVarsCol, nMulti, 1 );
00225 //      printf( "The number of backtracks = %d\n", s_BackTracks );
00226 //      s_EncSearchTime += clock() - clk;
00227 
00228         // allocate the temporary storage for the columns
00229         s_pbTemp = (DdNode **) malloc( nColumns * sizeof(DdNode *) );
00230 
00231 //      clk = clock();
00232         bResult = CreateTheCodes_rec( dd, bEncoded, 0, pCVars );   Cudd_Ref( bResult );
00233 //      s_EncComputeTime += clock() - clk;
00234         
00235         // delocate the preliminarily encoded set
00236         Cudd_RecursiveDeref( dd, bEncoded );
00237 //      Cudd_RecursiveDeref( dd, aEncoded );
00238 
00239         free( s_pbTemp );
00240 
00241         *pSimple = s_nVarsBest;
00242         Cudd_Deref( bResult );
00243         return bResult;
00244 }

DdNode* Extra_bddFindOneCube ( DdManager dd,
DdNode bF 
)

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 579 of file extraBddMisc.c.

00580 {
00581     char * s_Temp;
00582     DdNode * bCube, * bTemp;
00583     int v;
00584 
00585     // get the vector of variables in the cube
00586     s_Temp = ALLOC( char, dd->size );
00587     Cudd_bddPickOneCube( dd, bF, s_Temp );
00588 
00589     // start the cube
00590     bCube = b1; Cudd_Ref( bCube );
00591     for ( v = 0; v < dd->size; v++ )
00592         if ( s_Temp[v] == 0 )
00593         {
00594 //          Cube &= !s_XVars[v];
00595             bCube = Cudd_bddAnd( dd, bTemp = bCube, Cudd_Not(dd->vars[v]) ); Cudd_Ref( bCube );
00596             Cudd_RecursiveDeref( dd, bTemp );
00597         }
00598         else if ( s_Temp[v] == 1 )
00599         {
00600 //          Cube &=  s_XVars[v];
00601             bCube = Cudd_bddAnd( dd, bTemp = bCube,          dd->vars[v]  ); Cudd_Ref( bCube );
00602             Cudd_RecursiveDeref( dd, bTemp );
00603         }
00604     Cudd_Deref(bCube);
00605     free( s_Temp );
00606     return bCube;
00607 }

DdNode* Extra_bddGetOneCube ( DdManager dd,
DdNode bFunc 
)

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 619 of file extraBddMisc.c.

00620 {
00621     DdNode * bFuncR, * bFunc0, * bFunc1;
00622     DdNode * bRes0,  * bRes1,  * bRes;
00623 
00624     bFuncR = Cudd_Regular(bFunc);
00625     if ( cuddIsConstant(bFuncR) )
00626         return bFunc;
00627 
00628     // cofactor
00629     if ( Cudd_IsComplement(bFunc) )
00630     {
00631         bFunc0 = Cudd_Not( cuddE(bFuncR) );
00632         bFunc1 = Cudd_Not( cuddT(bFuncR) );
00633     }
00634     else
00635     {
00636         bFunc0 = cuddE(bFuncR);
00637         bFunc1 = cuddT(bFuncR);
00638     }
00639 
00640     // try to find the cube with the negative literal
00641     bRes0 = Extra_bddGetOneCube( dd, bFunc0 );  Cudd_Ref( bRes0 );
00642 
00643     if ( bRes0 != b0 )
00644     {
00645         bRes = Cudd_bddAnd( dd, bRes0, Cudd_Not(dd->vars[bFuncR->index]) ); Cudd_Ref( bRes );
00646         Cudd_RecursiveDeref( dd, bRes0 );
00647     }
00648     else
00649     {
00650         Cudd_RecursiveDeref( dd, bRes0 );
00651         // try to find the cube with the positive literal
00652         bRes1 = Extra_bddGetOneCube( dd, bFunc1 );  Cudd_Ref( bRes1 );
00653         assert( bRes1 != b0 );
00654         bRes = Cudd_bddAnd( dd, bRes1, dd->vars[bFuncR->index] ); Cudd_Ref( bRes );
00655         Cudd_RecursiveDeref( dd, bRes1 );
00656     }
00657 
00658     Cudd_Deref( bRes );
00659     return bRes;
00660 }

int Extra_bddIsVar ( DdNode bFunc  ) 

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 813 of file extraBddMisc.c.

00814 {
00815     bFunc = Cudd_Regular( bFunc );
00816     if ( cuddIsConstant(bFunc) )
00817         return 0;
00818     return cuddIsConstant( cuddT(bFunc) ) && cuddIsConstant( Cudd_Regular(cuddE(bFunc)) );
00819 }

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

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

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

Description []

SideEffects []

SeeAlso [Extra_bddShift]

Definition at line 182 of file extraBddMisc.c.

00186 {
00187     DdNode * res;
00188     DdNode * bVars;
00189     if ( nVars == 0 )
00190         return bF;
00191     if ( Cudd_IsConstant(bF) )
00192         return bF;
00193     assert( nVars <= dd->size );
00194     if ( nVars > 0 )
00195         bVars = dd->vars[nVars];
00196     else
00197         bVars = Cudd_Not(dd->vars[-nVars]);
00198 
00199     do {
00200         dd->reordered = 0;
00201         res = extraBddMove( dd, bF, bVars );
00202     } while (dd->reordered == 1);
00203     return(res);
00204 
00205 } /* end of Extra_bddMove */

st_table* Extra_bddNodePathsUnderCut ( DdManager dd,
DdNode bFunc,
int  CutLevel 
)

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 260 of file extraBddCas.c.

00261 {
00262         st_table * Visited;  // temporary table to remember the visited nodes
00263         st_table * CutNodes; // the result goes here
00264         st_table * Result; // the result goes here
00265         DdNode * aFunc;
00266 
00267         s_CutLevel = CutLevel;
00268 
00269         Result  = st_init_table(st_ptrcmp,st_ptrhash);
00270         // the terminal cases
00271         if ( Cudd_IsConstant( bFunc ) )
00272         {
00273                 if ( bFunc == b1 )
00274                 {
00275                         st_insert( Result, (char*)b1, (char*)b1 );
00276                         Cudd_Ref( b1 );
00277                         Cudd_Ref( b1 );
00278                 }
00279                 else
00280                 {
00281                         st_insert( Result, (char*)b0, (char*)b0 );
00282                         Cudd_Ref( b0 );
00283                         Cudd_Ref( b0 );
00284                 }
00285                 return Result;
00286         }
00287 
00288         // create the ADD to simplify processing (no complemented edges)
00289         aFunc = Cudd_BddToAdd( dd, bFunc );   Cudd_Ref( aFunc );
00290 
00291         // Step 1: Start the tables and collect information about the nodes above the cut 
00292         // this information tells how many edges point to each node
00293         Visited  = st_init_table(st_ptrcmp,st_ptrhash);
00294         CutNodes = st_init_table(st_ptrcmp,st_ptrhash);
00295 
00296         CountNodeVisits_rec( dd, aFunc, Visited );
00297 
00298         // Step 2: Traverse the BDD using the visited table and compute the sum of paths
00299         CollectNodesAndComputePaths_rec( dd, aFunc, b1, Visited, CutNodes );
00300 
00301         // at this point the table of cut nodes is ready and the table of visited is useless
00302         {
00303                 st_generator * gen;
00304                 DdNode * aNode;
00305                 traventry * p;
00306                 st_foreach_item( Visited, gen, (char**)&aNode, (char**)&p ) 
00307                 {
00308                         Cudd_RecursiveDeref( dd, p->bSum );
00309                         free( p );
00310                 }
00311                 st_free_table( Visited );
00312         }
00313 
00314         // go through the table CutNodes and create the BDD and the path to be returned
00315         {
00316                 st_generator * gen;
00317                 DdNode * aNode, * bNode, * bSum;
00318                 st_foreach_item( CutNodes, gen, (char**)&aNode, (char**)&bSum) 
00319                 {
00320                         // aNode is not referenced, because aFunc is holding it
00321                         bNode = Cudd_addBddPattern( dd, aNode );  Cudd_Ref( bNode ); 
00322                         st_insert( Result, (char*)bNode, (char*)bSum );
00323                         // the new table takes both refs
00324                 }
00325                 st_free_table( CutNodes );
00326         }
00327 
00328         // dereference the ADD
00329         Cudd_RecursiveDeref( dd, aFunc );
00330 
00331         // return the table
00332         return Result;
00333 
00334 } /* end of Extra_bddNodePathsUnderCut */

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

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 352 of file extraBddCas.c.

00353 {
00354         st_table * Visited;  // temporary table to remember the visited nodes
00355         st_table * CutNodes; // the nodes under the cut go here
00356         int i, Counter;
00357 
00358         s_CutLevel = CutLevel;
00359 
00360         // there should be some nodes
00361         assert( nNodes > 0 );
00362         if ( nNodes == 1 && Cudd_IsConstant( paNodes[0] ) )
00363         {
00364                 if ( paNodes[0] == a1 )
00365                 {
00366                         paNodesRes[0] = a1;          Cudd_Ref( a1 );
00367                         pbCubesRes[0] = pbCubes[0];  Cudd_Ref( pbCubes[0] );
00368                 }
00369                 else
00370                 {
00371                         paNodesRes[0] = a0;          Cudd_Ref( a0 );
00372                         pbCubesRes[0] = pbCubes[0];  Cudd_Ref( pbCubes[0] );
00373                 }
00374                 return 1;
00375         }
00376 
00377         // Step 1: Start the table and collect information about the nodes above the cut 
00378         // this information tells how many edges point to each node
00379         CutNodes = st_init_table(st_ptrcmp,st_ptrhash);
00380         Visited  = st_init_table(st_ptrcmp,st_ptrhash);
00381 
00382         for ( i = 0; i < nNodes; i++ )
00383                 CountNodeVisits_rec( dd, paNodes[i], Visited );
00384 
00385         // Step 2: Traverse the BDD using the visited table and compute the sum of paths
00386         for ( i = 0; i < nNodes; i++ )
00387                 CollectNodesAndComputePaths_rec( dd, paNodes[i], pbCubes[i], Visited, CutNodes );
00388 
00389         // at this point, the table of cut nodes is ready and the table of visited is useless
00390         {
00391                 st_generator * gen;
00392                 DdNode * aNode;
00393                 traventry * p;
00394                 st_foreach_item( Visited, gen, (char**)&aNode, (char**)&p ) 
00395                 {
00396                         Cudd_RecursiveDeref( dd, p->bSum );
00397                         free( p );
00398                 }
00399                 st_free_table( Visited );
00400         }
00401 
00402         // go through the table CutNodes and create the BDD and the path to be returned
00403         {
00404                 st_generator * gen;
00405                 DdNode * aNode, * bSum;
00406                 Counter = 0;
00407                 st_foreach_item( CutNodes, gen, (char**)&aNode, (char**)&bSum) 
00408                 {
00409                         paNodesRes[Counter] = aNode;   Cudd_Ref( aNode ); 
00410                         pbCubesRes[Counter] = bSum;
00411                         Counter++;
00412                 }
00413                 st_free_table( CutNodes );
00414         }
00415 
00416         // return the number of cofactors found
00417         return Counter;
00418 
00419 } /* end of Extra_bddNodePathsUnderCutArray */

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

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 935 of file extraBddMisc.c.

00936 {
00937         DdHashTable *table;
00938         int i, k;
00939         do
00940         {
00941                 manager->reordered = 0;
00942                 table = cuddHashTableInit( manager, 1, 2 );
00943 
00944                 /* permute the output functions one-by-one */
00945                 for ( i = 0; i < nNodes; i++ )
00946                 {
00947                         bNodesOut[i] = cuddBddPermuteRecur( manager, table, bNodesIn[i], permut );
00948                         if ( bNodesOut[i] == NULL )
00949                         {
00950                                 /* deref the array of the already computed outputs */
00951                                 for ( k = 0; k < i; k++ )
00952                                         Cudd_RecursiveDeref( manager, bNodesOut[k] );
00953                                 break;
00954                         }
00955                         cuddRef( bNodesOut[i] );
00956                 }
00957                 /* Dispose of local cache. */
00958                 cuddHashTableQuit( table );
00959         }
00960         while ( manager->reordered == 1 );
00961 }       /* end of Extra_bddPermuteArray */

void Extra_bddPrint ( DdManager dd,
DdNode F 
)

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

Synopsis [Outputs the BDD in a readable format.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 240 of file extraBddMisc.c.

00241 {
00242     DdGen * Gen;
00243     int * Cube;
00244     CUDD_VALUE_TYPE Value;
00245     int nVars = dd->size;
00246     int fFirstCube = 1;
00247     int i;
00248 
00249     if ( F == NULL )
00250     {
00251         printf("NULL");
00252         return;
00253     }
00254     if ( F == b0 )
00255     {
00256         printf("Constant 0");
00257         return;
00258     }
00259     if ( F == b1 )
00260     {
00261         printf("Constant 1");
00262         return;
00263     }
00264 
00265     Cudd_ForeachCube( dd, F, Gen, Cube, Value )
00266     {
00267         if ( fFirstCube )
00268             fFirstCube = 0;
00269         else
00270 //          Output << " + ";
00271             printf( " + " );
00272 
00273         for ( i = 0; i < nVars; i++ )
00274             if ( Cube[i] == 0 )
00275                 printf( "[%d]'", i );
00276 //              printf( "%c'", (char)('a'+i) );
00277             else if ( Cube[i] == 1 )
00278                 printf( "[%d]", i );
00279 //              printf( "%c", (char)('a'+i) );
00280     }
00281 
00282 //  printf("\n");
00283 }

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

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 178 of file extraBddSymm.c.

00182 {
00183     DdNode * res;
00184     do {
00185         dd->reordered = 0;
00186         res = extraBddReduceVarSet( dd, bVars, bF );
00187     } while (dd->reordered == 1);
00188     return(res);
00189 
00190 } /* end of Extra_bddReduceVarSet */

DdNode* Extra_bddRemapUp ( DdManager dd,
DdNode bF 
)

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 140 of file extraBddMisc.c.

00143 {
00144     int * pPermute;
00145     DdNode * bSupp, * bTemp, * bRes;
00146     int Counter;
00147 
00148     pPermute = ALLOC( int, dd->size );
00149 
00150     // get support
00151     bSupp = Cudd_Support( dd, bF );    Cudd_Ref( bSupp );
00152 
00153     // create the variable map
00154     // to remap the DD into the upper part of the manager
00155     Counter = 0;
00156     for ( bTemp = bSupp; bTemp != dd->one; bTemp = cuddT(bTemp) )
00157         pPermute[bTemp->index] = dd->invperm[Counter++];
00158 
00159     // transfer the BDD and remap it
00160     bRes = Cudd_bddPermute( dd, bF, pPermute );  Cudd_Ref( bRes );
00161 
00162     // remove support
00163     Cudd_RecursiveDeref( dd, bSupp );
00164 
00165     // return
00166     Cudd_Deref( bRes );
00167     free( pPermute );
00168     return bRes;
00169 }

DdNode* Extra_bddSpaceCanonVars ( DdManager dd,
DdNode bSpace 
)

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 313 of file extraBddAuto.c.

00314 {
00315     DdNode * bRes;
00316     do {
00317                 dd->reordered = 0;
00318                 bRes = extraBddSpaceCanonVars( dd, bSpace );
00319     } while (dd->reordered == 1);
00320     return bRes;
00321 }

DdNode* Extra_bddSpaceEquations ( DdManager dd,
DdNode bSpace 
)

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 358 of file extraBddAuto.c.

00359 {
00360     DdNode * zRes;
00361         DdNode * zEquPos;
00362         DdNode * zEquNeg;
00363         zEquPos = Extra_bddSpaceEquationsPos( dd, bSpace );  Cudd_Ref( zEquPos );
00364         zEquNeg = Extra_bddSpaceEquationsNeg( dd, bSpace );  Cudd_Ref( zEquNeg );
00365         zRes    = Cudd_zddUnion( dd, zEquPos, zEquNeg );     Cudd_Ref( zRes );
00366         Cudd_RecursiveDerefZdd( dd, zEquPos );
00367         Cudd_RecursiveDerefZdd( dd, zEquNeg );
00368         Cudd_Deref( zRes );
00369     return zRes;
00370 }

DdNode* Extra_bddSpaceEquationsNeg ( DdManager dd,
DdNode bSpace 
)

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 406 of file extraBddAuto.c.

00407 {
00408     DdNode * zRes;
00409     do {
00410                 dd->reordered = 0;
00411                 zRes = extraBddSpaceEquationsNeg( dd, bSpace );
00412     } while (dd->reordered == 1);
00413     return zRes;
00414 }

DdNode* Extra_bddSpaceEquationsPos ( DdManager dd,
DdNode bSpace 
)

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 384 of file extraBddAuto.c.

00385 {
00386     DdNode * zRes;
00387     do {
00388                 dd->reordered = 0;
00389                 zRes = extraBddSpaceEquationsPos( dd, bSpace );
00390     } while (dd->reordered == 1);
00391     return zRes;
00392 }

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

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 494 of file extraBddAuto.c.

00495 {
00496         DdNode ** pzRes;
00497         int * pVarsNonCan;
00498         DdNode * zEquRem;
00499         int iVarNonCan;
00500         DdNode * zExor, * zTemp;
00501 
00502         // get the set of non-canonical variables
00503         pVarsNonCan = ALLOC( int, ddMax(dd->size,dd->sizeZ) );
00504         Extra_SupportArray( dd, bFuncRed, pVarsNonCan );
00505 
00506         // allocate storage for the EXOR sets
00507         pzRes = ALLOC( DdNode *, dd->size );
00508         memset( pzRes, 0, sizeof(DdNode *) * dd->size );
00509 
00510         // go through all the equations
00511         zEquRem = zEquations;  Cudd_Ref( zEquRem );
00512         while ( zEquRem != z0 )
00513         {
00514                 // extract one product
00515                 zExor = Extra_zddSelectOneSubset( dd, zEquRem );   Cudd_Ref( zExor );
00516                 // remove it from the set
00517                 zEquRem = Cudd_zddDiff( dd, zTemp = zEquRem, zExor );  Cudd_Ref( zEquRem );
00518                 Cudd_RecursiveDerefZdd( dd, zTemp );
00519 
00520                 // locate the non-canonical variable
00521                 iVarNonCan = -1;
00522                 for ( zTemp = zExor; zTemp != z1; zTemp = cuddT(zTemp) )
00523                 {
00524                         if ( pVarsNonCan[zTemp->index/2] == 1 )
00525                         {
00526                                 assert( iVarNonCan == -1 );
00527                                 iVarNonCan = zTemp->index/2;
00528                         }
00529                 }
00530                 assert( iVarNonCan != -1 );
00531 
00532                 if ( Extra_zddLitCountComb( dd, zExor ) > 1 )
00533                         pzRes[ iVarNonCan ] = zExor; // takes ref
00534                 else
00535                         Cudd_RecursiveDerefZdd( dd, zExor );
00536         }
00537         Cudd_RecursiveDerefZdd( dd, zEquRem );
00538 
00539         free( pVarsNonCan );
00540         return pzRes;
00541 }

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

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 250 of file extraBddAuto.c.

00251 {
00252     DdNode * bRes;
00253     do {
00254                 dd->reordered = 0;
00255                 bRes = extraBddSpaceFromFunction( dd, bF, bG );
00256     } while (dd->reordered == 1);
00257     return bRes;
00258 }

DdNode* Extra_bddSpaceFromFunctionFast ( DdManager dd,
DdNode bFunc 
)

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 150 of file extraBddAuto.c.

00151 {
00152         int * pSupport;
00153         int * pPermute;
00154         int * pPermuteBack;
00155         DdNode ** pCompose;
00156         DdNode * bCube, * bTemp;
00157         DdNode * bSpace, * bFunc1, * bFunc2, * bSpaceShift;
00158         int nSupp, Counter;
00159         int i, lev;
00160 
00161         // get the support
00162         pSupport = ALLOC( int, ddMax(dd->size,dd->sizeZ) );
00163         Extra_SupportArray( dd, bFunc, pSupport );
00164         nSupp = 0;
00165         for ( i = 0; i < dd->size; i++ )
00166                 if ( pSupport[i] )
00167                         nSupp++;
00168 
00169         // make sure the manager has enough variables
00170         if ( 2*nSupp > dd->size )
00171         {
00172                 printf( "Cannot derive linear space, because DD manager does not have enough variables.\n" );
00173                 fflush( stdout );
00174                 free( pSupport );
00175                 return NULL;
00176         }
00177 
00178         // create the permutation arrays
00179         pPermute     = ALLOC( int, dd->size );
00180         pPermuteBack = ALLOC( int, dd->size );
00181         pCompose     = ALLOC( DdNode *, dd->size );
00182         for ( i = 0; i < dd->size; i++ )
00183         {
00184                 pPermute[i]     = i;
00185                 pPermuteBack[i] = i;
00186                 pCompose[i]     = dd->vars[i];   Cudd_Ref( pCompose[i] );
00187         }
00188 
00189         // remap the function in such a way that the variables are interleaved
00190         Counter = 0;
00191         bCube = b1;  Cudd_Ref( bCube );
00192         for ( lev = 0; lev < dd->size; lev++ )
00193                 if ( pSupport[ dd->invperm[lev] ] )
00194                 {   // var "dd->invperm[lev]" on level "lev" should go to level 2*Counter;
00195                         pPermute[ dd->invperm[lev] ] = dd->invperm[2*Counter];
00196                         // var from level 2*Counter+1 should go back to the place of this var
00197                         pPermuteBack[ dd->invperm[2*Counter+1] ] = dd->invperm[lev];
00198                         // the permutation should be defined in such a way that variable
00199                         // on level 2*Counter is replaced by an EXOR of itself and var on the next level
00200                         Cudd_Deref( pCompose[ dd->invperm[2*Counter] ] );
00201                         pCompose[ dd->invperm[2*Counter] ] = 
00202                                 Cudd_bddXor( dd, dd->vars[ dd->invperm[2*Counter] ], dd->vars[ dd->invperm[2*Counter+1] ] );  
00203                         Cudd_Ref( pCompose[ dd->invperm[2*Counter] ] );
00204                         // add this variable to the cube
00205                         bCube = Cudd_bddAnd( dd, bTemp = bCube, dd->vars[ dd->invperm[2*Counter] ] );  Cudd_Ref( bCube );
00206                         Cudd_RecursiveDeref( dd, bTemp );
00207                         // increment the counter
00208                         Counter ++;
00209                 }
00210 
00211         // permute the functions
00212         bFunc1 = Cudd_bddPermute( dd, bFunc, pPermute );         Cudd_Ref( bFunc1 );
00213         // compose to gate the function depending on both vars
00214         bFunc2 = Cudd_bddVectorCompose( dd, bFunc1, pCompose );  Cudd_Ref( bFunc2 );
00215         // gate the vector space
00216         // L(a) = ForAll x [ F(x) = F(x+a) ] = Not( Exist x [ F(x) (+) F(x+a) ] )
00217         bSpaceShift = Cudd_bddXorExistAbstract( dd, bFunc1, bFunc2, bCube );  Cudd_Ref( bSpaceShift );
00218         bSpaceShift = Cudd_Not( bSpaceShift );
00219         // permute the space back into the original mapping
00220         bSpace = Cudd_bddPermute( dd, bSpaceShift, pPermuteBack ); Cudd_Ref( bSpace );
00221         Cudd_RecursiveDeref( dd, bFunc1 );
00222         Cudd_RecursiveDeref( dd, bFunc2 );
00223         Cudd_RecursiveDeref( dd, bSpaceShift );
00224         Cudd_RecursiveDeref( dd, bCube );
00225 
00226         for ( i = 0; i < dd->size; i++ )
00227                 Cudd_RecursiveDeref( dd, pCompose[i] );
00228         free( pPermute );
00229         free( pPermuteBack );
00230         free( pCompose );
00231     free( pSupport );
00232 
00233         Cudd_Deref( bSpace );
00234         return bSpace;
00235 }

DdNode* Extra_bddSpaceFromFunctionNeg ( DdManager dd,
DdNode bFunc 
)

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 292 of file extraBddAuto.c.

00293 {
00294     DdNode * bRes;
00295     do {
00296                 dd->reordered = 0;
00297                 bRes = extraBddSpaceFromFunctionNeg( dd, bFunc );
00298     } while (dd->reordered == 1);
00299     return bRes;
00300 }

DdNode* Extra_bddSpaceFromFunctionPos ( DdManager dd,
DdNode bFunc 
)

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 271 of file extraBddAuto.c.

00272 {
00273     DdNode * bRes;
00274     do {
00275                 dd->reordered = 0;
00276                 bRes = extraBddSpaceFromFunctionPos( dd, bFunc );
00277     } while (dd->reordered == 1);
00278     return bRes;
00279 }

DdNode* Extra_bddSpaceFromMatrixNeg ( DdManager dd,
DdNode zA 
)

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 449 of file extraBddAuto.c.

00450 {
00451     DdNode * bRes;
00452     do {
00453                 dd->reordered = 0;
00454                 bRes = extraBddSpaceFromMatrixNeg( dd, zA );
00455     } while (dd->reordered == 1);
00456     return bRes;
00457 }

DdNode* Extra_bddSpaceFromMatrixPos ( DdManager dd,
DdNode zA 
)

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 428 of file extraBddAuto.c.

00429 {
00430     DdNode * bRes;
00431     do {
00432                 dd->reordered = 0;
00433                 bRes = extraBddSpaceFromMatrixPos( dd, zA );
00434     } while (dd->reordered == 1);
00435     return bRes;
00436 }

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

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 334 of file extraBddAuto.c.

00335 {
00336         DdNode * bNegCube;
00337         DdNode * bResult;
00338         bNegCube = Extra_bddSupportNegativeCube( dd, bCanonVars );  Cudd_Ref( bNegCube );
00339         bResult  = Cudd_Cofactor( dd, bFunc, bNegCube );            Cudd_Ref( bResult );
00340         Cudd_RecursiveDeref( dd, bNegCube );
00341         Cudd_Deref( bResult );
00342         return bResult;
00343 }

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

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 417 of file extraBddMisc.c.

00418 {
00419     DdNode * bSL = bL;
00420     DdNode * bSH = bH;
00421     int fLcontainsH = 1;
00422     int fHcontainsL = 1;
00423     int TopVar;
00424     
00425     if ( bSL == bSH )
00426         return 0;
00427 
00428     while ( bSL != b1 || bSH != b1 )
00429     {
00430         if ( bSL == b1 )
00431         { // Low component has no vars; High components has some vars
00432             fLcontainsH = 0;
00433             if ( fHcontainsL == 0 )
00434                 return 0;
00435             else
00436                 break;
00437         }
00438 
00439         if ( bSH == b1 )
00440         { // similarly
00441             fHcontainsL = 0;
00442             if ( fLcontainsH == 0 )
00443                 return 0;
00444             else
00445                 break;
00446         }
00447 
00448         // determine the topmost var of the supports by comparing their levels
00449         if ( dd->perm[bSL->index] < dd->perm[bSH->index] )
00450             TopVar = bSL->index;
00451         else
00452             TopVar = bSH->index;
00453 
00454         if ( TopVar == bSL->index && TopVar == bSH->index ) 
00455         { // they are on the same level
00456             // it does not tell us anything about their containment
00457             // skip this var
00458             bSL = cuddT(bSL);
00459             bSH = cuddT(bSH);
00460         }
00461         else if ( TopVar == bSL->index ) // and TopVar != bSH->index
00462         { // Low components is higher and contains more vars
00463             // it is not possible that High component contains Low
00464             fHcontainsL = 0;
00465             // skip this var
00466             bSL = cuddT(bSL);
00467         }
00468         else // if ( TopVar == bSH->index ) // and TopVar != bSL->index
00469         { // similarly
00470             fLcontainsH = 0;
00471             // skip this var
00472             bSH = cuddT(bSH);
00473         }
00474 
00475         // check the stopping condition
00476         if ( !fHcontainsL && !fLcontainsH )
00477             return 0;
00478     }
00479     // only one of them can be true at the same time
00480     assert( !fHcontainsL || !fLcontainsH );
00481     if ( fHcontainsL )
00482     {
00483         *bLarge = bH;
00484         *bSmall = bL;
00485     }
00486     else // fLcontainsH
00487     {
00488         *bLarge = bL;
00489         *bSmall = bH;
00490     }
00491     return 1;
00492 }

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

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 320 of file extraBddMisc.c.

00321 { 
00322     for( ; bS != b1; bS = cuddT(bS) )
00323         if ( bS->index == bVar->index )
00324             return 1;
00325     return 0;
00326 }

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

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 367 of file extraBddMisc.c.

00368 {
00369     int Result = 0;
00370     while ( S1->index != CUDD_CONST_INDEX && S2->index != CUDD_CONST_INDEX )
00371     {
00372         // if the top vars are the same, this var is the same
00373         if ( S1->index == S2->index )
00374         {
00375             S1 = cuddT(S1);
00376             S2 = cuddT(S2);
00377             continue;
00378         }
00379         // the top var is different
00380         Result++;
00381 
00382         if ( Result >= DiffMax )
00383             return DiffMax;
00384 
00385         // if the top vars are different, skip the one, which is higher
00386         if ( dd->perm[S1->index] < dd->perm[S2->index] )
00387             S1 = cuddT(S1);
00388         else
00389             S2 = cuddT(S2);
00390     }
00391 
00392     // consider the remaining variables
00393     if ( S1->index != CUDD_CONST_INDEX )
00394         Result += Extra_bddSuppSize(dd,S1);
00395     else if ( S2->index != CUDD_CONST_INDEX )
00396         Result += Extra_bddSuppSize(dd,S2);
00397 
00398     if ( Result >= DiffMax )
00399         return DiffMax;
00400     return Result;
00401 }

DdNode* Extra_bddSupportNegativeCube ( DdManager dd,
DdNode f 
)

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 738 of file extraBddMisc.c.

00739 {
00740         int *support;
00741         DdNode *res, *tmp, *var;
00742         int i, j;
00743         int size;
00744 
00745         /* Allocate and initialize support array for ddSupportStep. */
00746         size = ddMax( dd->size, dd->sizeZ );
00747         support = ALLOC( int, size );
00748         if ( support == NULL )
00749         {
00750                 dd->errorCode = CUDD_MEMORY_OUT;
00751                 return ( NULL );
00752         }
00753         for ( i = 0; i < size; i++ )
00754         {
00755                 support[i] = 0;
00756         }
00757 
00758         /* Compute support and clean up markers. */
00759         ddSupportStep( Cudd_Regular( f ), support );
00760         ddClearFlag( Cudd_Regular( f ) );
00761 
00762         /* Transform support from array to cube. */
00763         do
00764         {
00765                 dd->reordered = 0;
00766                 res = DD_ONE( dd );
00767                 cuddRef( res );
00768                 for ( j = size - 1; j >= 0; j-- )
00769                 {                                               /* for each level bottom-up */
00770                         i = ( j >= dd->size ) ? j : dd->invperm[j];
00771                         if ( support[i] == 1 )
00772                         {
00773                                 var = cuddUniqueInter( dd, i, dd->one, Cudd_Not( dd->one ) );
00775                                 var = Cudd_Not(var);
00777                                 cuddRef( var );
00778                                 tmp = cuddBddAndRecur( dd, res, var );
00779                                 if ( tmp == NULL )
00780                                 {
00781                                         Cudd_RecursiveDeref( dd, res );
00782                                         Cudd_RecursiveDeref( dd, var );
00783                                         res = NULL;
00784                                         break;
00785                                 }
00786                                 cuddRef( tmp );
00787                                 Cudd_RecursiveDeref( dd, res );
00788                                 Cudd_RecursiveDeref( dd, var );
00789                                 res = tmp;
00790                         }
00791                 }
00792         }
00793         while ( dd->reordered == 1 );
00794 
00795         FREE( support );
00796         if ( res != NULL )
00797                 cuddDeref( res );
00798         return ( res );
00799 
00800 }                                                               /* end of Extra_SupportNeg */

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

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 339 of file extraBddMisc.c.

00340 {
00341     while ( S1->index != CUDD_CONST_INDEX && S2->index != CUDD_CONST_INDEX )
00342     {
00343         // if the top vars are the same, they intersect
00344         if ( S1->index == S2->index )
00345             return 1;
00346         // if the top vars are different, skip the one, which is higher
00347         if ( dd->perm[S1->index] < dd->perm[S2->index] )
00348             S1 = cuddT(S1);
00349         else
00350             S2 = cuddT(S2);
00351     }
00352     return 0;
00353 }

int Extra_bddSuppSize ( DdManager dd,
DdNode bSupp 
)

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

Synopsis [Returns the size of the support.]

Description []

SideEffects []

SeeAlso []

Definition at line 295 of file extraBddMisc.c.

00296 {
00297     int Counter = 0;
00298     while ( bSupp != b1 )
00299     {
00300         assert( !Cudd_IsComplement(bSupp) );
00301         assert( cuddE(bSupp) == b0 );
00302 
00303         bSupp = cuddT(bSupp);
00304         Counter++;
00305     }
00306     return Counter;
00307 }

void Extra_BitMatrixClean ( Extra_BitMat_t p  ) 

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

Synopsis [Stops the bit matrix.]

Description []

SideEffects []

SeeAlso []

Definition at line 107 of file extraUtilBitMatrix.c.

00108 {
00109     memset( p->ppData[0], 0, sizeof(unsigned) * p->nSize * p->nWords );
00110 }

int Extra_BitMatrixCountOnesUpper ( Extra_BitMat_t p  ) 

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

Synopsis [Counts the number of 1's in the upper rectangle.]

Description []

SideEffects []

SeeAlso []

Definition at line 346 of file extraUtilBitMatrix.c.

00347 {
00348     int i, k, nTotal = 0;
00349     for ( i = 0; i < p->nSize; i++ )
00350         for ( k = i + 1; k < p->nSize; k++ )
00351             nTotal += ( (p->ppData[i][k>>5] & (1 << (k&31))) > 0 );
00352     return nTotal;
00353 }

void Extra_BitMatrixDelete1 ( Extra_BitMat_t p,
int  i,
int  k 
)

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

Synopsis [Inserts the element into the upper part.]

Description []

SideEffects []

SeeAlso []

Definition at line 227 of file extraUtilBitMatrix.c.

00228 {
00229     p->nDeletes++;
00230     if ( i < k )
00231         p->ppData[i][k>>p->nBitShift] &= ~(1<<(k & p->uMask));
00232     else
00233         p->ppData[k][i>>p->nBitShift] &= ~(1<<(i & p->uMask));
00234 }

void Extra_BitMatrixDelete2 ( Extra_BitMat_t p,
int  i,
int  k 
)

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

Synopsis [Inserts the element into the upper part.]

Description []

SideEffects []

SeeAlso []

Definition at line 289 of file extraUtilBitMatrix.c.

00290 {
00291     p->nDeletes++;
00292     if ( i > k )
00293         p->ppData[i][k>>p->nBitShift] &= ~(1<<(k & p->uMask));
00294     else
00295         p->ppData[k][i>>p->nBitShift] &= ~(1<<(i & p->uMask));
00296 }

void Extra_BitMatrixInsert1 ( Extra_BitMat_t p,
int  i,
int  k 
)

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

Synopsis [Inserts the element into the upper part.]

Description []

SideEffects []

SeeAlso []

Definition at line 187 of file extraUtilBitMatrix.c.

00188 {
00189     p->nInserts++;
00190     if ( i < k )
00191         p->ppData[i][k>>p->nBitShift] |= (1<<(k & p->uMask));
00192     else
00193         p->ppData[k][i>>p->nBitShift] |= (1<<(i & p->uMask));
00194 }

void Extra_BitMatrixInsert2 ( Extra_BitMat_t p,
int  i,
int  k 
)

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

Synopsis [Inserts the element into the upper part.]

Description []

SideEffects []

SeeAlso []

Definition at line 249 of file extraUtilBitMatrix.c.

00250 {
00251     p->nInserts++;
00252     if ( i > k )
00253         p->ppData[i][k>>p->nBitShift] |= (1<<(k & p->uMask));
00254     else
00255         p->ppData[k][i>>p->nBitShift] |= (1<<(i & p->uMask));
00256 }

int Extra_BitMatrixIsClique ( Extra_BitMat_t pMat  ) 

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

Synopsis [Returns 1 if the matrix is a set of cliques.]

Description [For example pairwise symmetry info should satisfy this property.]

SideEffects []

SeeAlso []

Definition at line 388 of file extraUtilBitMatrix.c.

00389 {
00390     int v, u, i;
00391     for ( v = 0; v < pMat->nSize; v++ )
00392     for ( u = v+1; u < pMat->nSize; u++ )
00393     {
00394         if ( !Extra_BitMatrixLookup1( pMat, v, u ) )
00395             continue;
00396         // v and u are symmetric
00397         for ( i = 0; i < pMat->nSize; i++ )
00398         {
00399             if ( i == v || i == u )
00400                 continue;
00401             // i is neither v nor u
00402             // the symmetry status of i is the same w.r.t. to v and u
00403             if ( Extra_BitMatrixLookup1( pMat, i, v ) != Extra_BitMatrixLookup1( pMat, i, u ) )
00404                 return 0;
00405         }
00406     }
00407     return 1;
00408 }

int Extra_BitMatrixIsDisjoint ( Extra_BitMat_t p1,
Extra_BitMat_t p2 
)

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

Synopsis [Returns 1 if the matrices have no entries in common.]

Description []

SideEffects []

SeeAlso []

Definition at line 366 of file extraUtilBitMatrix.c.

00367 {
00368     int i, w;
00369     assert( p1->nSize == p2->nSize );
00370     for ( i = 0; i < p1->nSize; i++ )
00371         for ( w = 0; w < p1->nWords; w++ )
00372             if ( p1->ppData[i][w] & p2->ppData[i][w] )
00373                 return 0;
00374     return 1;
00375 }

int Extra_BitMatrixLookup1 ( Extra_BitMat_t p,
int  i,
int  k 
)

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

Synopsis [Inserts the element into the upper part.]

Description []

SideEffects []

SeeAlso []

Definition at line 207 of file extraUtilBitMatrix.c.

00208 {
00209     p->nLookups++;
00210     if ( i < k )
00211         return ((p->ppData[i][k>>p->nBitShift] & (1<<(k & p->uMask))) > 0);
00212     else
00213         return ((p->ppData[k][i>>p->nBitShift] & (1<<(i & p->uMask))) > 0);
00214 }

int Extra_BitMatrixLookup2 ( Extra_BitMat_t p,
int  i,
int  k 
)

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

Synopsis [Inserts the element into the upper part.]

Description []

SideEffects []

SeeAlso []

Definition at line 269 of file extraUtilBitMatrix.c.

00270 {
00271     p->nLookups++;
00272     if ( i > k )
00273         return ((p->ppData[i][k>>p->nBitShift] & (1<<(k & p->uMask))) > 0);
00274     else
00275         return ((p->ppData[k][i>>p->nBitShift] & (1<<(i & p->uMask))) > 0);
00276 }

void Extra_BitMatrixOr ( Extra_BitMat_t p,
int  i,
unsigned *  pInfo 
)

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

Synopsis [Inserts the element into the upper part.]

Description []

SideEffects []

SeeAlso []

Definition at line 310 of file extraUtilBitMatrix.c.

00311 {
00312     int w;
00313     for ( w = 0; w < p->nWords; w++ )
00314         p->ppData[i][w] |= pInfo[w];
00315 }

void Extra_BitMatrixOrTwo ( Extra_BitMat_t p,
int  i,
int  j 
)

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

Synopsis [Inserts the element into the upper part.]

Description []

SideEffects []

SeeAlso []

Definition at line 328 of file extraUtilBitMatrix.c.

00329 {
00330     int w;
00331     for ( w = 0; w < p->nWords; w++ )
00332         p->ppData[i][w] = p->ppData[j][w] = (p->ppData[i][w] | p->ppData[j][w]);
00333 }

void Extra_BitMatrixPrint ( Extra_BitMat_t pMat  ) 

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

Synopsis [Prints the bit-matrix.]

Description []

SideEffects []

SeeAlso []

Definition at line 141 of file extraUtilBitMatrix.c.

00142 {
00143     int i, k, nVars;
00144     printf( "\n" );
00145     nVars = Extra_BitMatrixReadSize( pMat );
00146     for ( i = 0; i < nVars; i++ )
00147     {
00148         for ( k = 0; k <= i; k++ )
00149             printf( " " );
00150         for ( k = i+1; k < nVars; k++ )
00151             if ( Extra_BitMatrixLookup1( pMat, i, k ) )
00152                 printf( "1" );
00153             else
00154                 printf( "." );
00155         printf( "\n" );
00156     }
00157 }

int Extra_BitMatrixReadSize ( Extra_BitMat_t p  ) 

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

Synopsis [Reads the matrix size.]

Description []

SideEffects []

SeeAlso []

Definition at line 171 of file extraUtilBitMatrix.c.

00172 {
00173     return p->nSize;
00174 }

Extra_BitMat_t* Extra_BitMatrixStart ( int  nSize  ) 

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

Synopsis [Starts the bit matrix.]

Description []

SideEffects []

SeeAlso []

Definition at line 78 of file extraUtilBitMatrix.c.

00079 {
00080     Extra_BitMat_t * p;
00081     int i;
00082     p = ALLOC( Extra_BitMat_t, 1 );
00083     memset( p, 0, sizeof(Extra_BitMat_t) );
00084     p->nSize     = nSize;
00085     p->nBitShift = (sizeof(unsigned) == 4) ?  5:  6;
00086     p->uMask     = (sizeof(unsigned) == 4) ? 31: 63;
00087     p->nWords    = nSize / (8 * sizeof(unsigned)) + ((nSize % (8 * sizeof(unsigned))) > 0);
00088     p->ppData    = ALLOC( unsigned *, nSize );
00089     p->ppData[0] = ALLOC( unsigned, nSize * p->nWords );
00090     memset( p->ppData[0], 0, sizeof(unsigned) * nSize * p->nWords );
00091     for ( i = 1; i < nSize; i++ )
00092         p->ppData[i] = p->ppData[i-1] + p->nWords;
00093     return p;
00094 }

void Extra_BitMatrixStop ( Extra_BitMat_t p  ) 

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

Synopsis [Stops the bit matrix.]

Description []

SideEffects []

SeeAlso []

Definition at line 123 of file extraUtilBitMatrix.c.

00124 {
00125     FREE( p->ppData[0] );
00126     FREE( p->ppData );
00127     FREE( p );
00128 }

static int Extra_BitWordNum ( int  nBits  )  [inline, static]

Definition at line 433 of file extra.h.

00433 { return nBits/(8*sizeof(unsigned)) + ((nBits%(8*sizeof(unsigned))) > 0);  }

void Extra_BubbleSort ( int  Order[],
int  Costs[],
int  nSize,
int  fIncreasing 
)

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

Synopsis [Bubble-sorts components by scores in increasing order.]

Description []

SideEffects []

SeeAlso []

Definition at line 2082 of file extraUtilMisc.c.

02083 {
02084     int i, Temp, fChanges;
02085     assert( nSize < 1000 );
02086     for ( i = 0; i < nSize; i++ )
02087         Order[i] = i;
02088     if ( fIncreasing )
02089     {
02090         do {
02091             fChanges = 0;
02092             for ( i = 0; i < nSize - 1; i++ )
02093             {
02094                 if ( Costs[Order[i]] <= Costs[Order[i+1]] )
02095                     continue;
02096                 Temp = Order[i];
02097                 Order[i] = Order[i+1];
02098                 Order[i+1] = Temp;
02099                 fChanges = 1;
02100             }
02101         } while ( fChanges );
02102     }
02103     else
02104     {
02105         do {
02106             fChanges = 0;
02107             for ( i = 0; i < nSize - 1; i++ )
02108             {
02109                 if ( Costs[Order[i]] >= Costs[Order[i+1]] )
02110                     continue;
02111                 Temp = Order[i];
02112                 Order[i] = Order[i+1];
02113                 Order[i+1] = Temp;
02114                 fChanges = 1;
02115             }
02116         } while ( fChanges );
02117     }
02118 }

int Extra_CountOnes ( unsigned char *  pBytes,
int  nBytes 
)

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

Synopsis [Counts the number of ones in the bitstring.]

Description []

SideEffects []

SeeAlso []

Definition at line 223 of file extraUtilMisc.c.

00224 {
00225     static int bit_count[256] = {
00226       0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
00227       1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
00228       1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
00229       2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
00230       1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
00231       2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
00232       2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
00233       3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
00234     };
00235 
00236     int i, Counter;
00237     Counter = 0;
00238     for ( i = 0; i < nBytes; i++ )
00239         Counter += bit_count[ *(pBytes+i) ];
00240     return Counter;
00241 }

long Extra_CpuTime (  ) 

FUNCTION DEFINITIONS ///Function*************************************************************

Synopsis [util_cpu_time()]

Description []

SideEffects []

SeeAlso []

Definition at line 61 of file extraUtilUtil.c.

00062 {
00063     return clock();
00064 }

int* Extra_DeriveRadixCode ( int  Number,
int  Radix,
int  nDigits 
)

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 198 of file extraUtilMisc.c.

00199 {
00200     static int Code[100];
00201     int i;
00202     assert( nDigits < 100 );
00203     for ( i = 0; i < nDigits; i++ )
00204     {
00205         Code[i] = Number % Radix;
00206         Number  = Number / Radix;
00207     }
00208     assert( Number == 0 );
00209     return Code;
00210 }

int Extra_Factorial ( int  n  ) 

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

Synopsis [Computes the factorial.]

Description []

SideEffects []

SeeAlso []

Definition at line 254 of file extraUtilMisc.c.

00255 {
00256     int i, Res = 1;
00257     for ( i = 1; i <= n; i++ )
00258         Res *= i;
00259     return Res;
00260 }

char* Extra_FileGetSimilarName ( char *  pFileNameWrong,
char *  pS1,
char *  pS2,
char *  pS3,
char *  pS4,
char *  pS5 
)

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

FileName [extraUtilFile.c]

SystemName [ABC: Logic synthesis and verification system.]

PackageName [extra]

Synopsis [File management utilities.]

Author [Alan Mishchenko]

Affiliation [UC Berkeley]

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

Revision [

Id
extraUtilFile.c,v 1.00 2005/06/20 00:00:00 alanmi Exp

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

Synopsis [Tries to find a file name with a different extension.]

Description []

SideEffects []

SeeAlso []

Definition at line 68 of file extraUtilFile.c.

00069 {
00070     FILE * pFile;
00071     char * pFileNameOther;
00072     char * pFileGen;
00073 
00074     if ( pS1 == NULL )
00075         return NULL;
00076 
00077     // get the generic file name
00078     pFileGen = Extra_FileNameGeneric( pFileNameWrong );
00079     pFileNameOther = Extra_FileNameAppend( pFileGen, pS1 );
00080     pFile = fopen( pFileNameOther, "r" );
00081     if ( pFile == NULL && pS2 )
00082     { // try one more
00083         pFileNameOther = Extra_FileNameAppend( pFileGen, pS2 );
00084         pFile = fopen( pFileNameOther, "r" );
00085         if ( pFile == NULL && pS3 )
00086         { // try one more
00087             pFileNameOther = Extra_FileNameAppend( pFileGen, pS3 );
00088             pFile = fopen( pFileNameOther, "r" );
00089             if ( pFile == NULL && pS4 )
00090             { // try one more
00091                 pFileNameOther = Extra_FileNameAppend( pFileGen, pS4 );
00092                 pFile = fopen( pFileNameOther, "r" );
00093                 if ( pFile == NULL && pS5 )
00094                 { // try one more
00095                     pFileNameOther = Extra_FileNameAppend( pFileGen, pS5 );
00096                     pFile = fopen( pFileNameOther, "r" );
00097                 }
00098             }
00099         }
00100     }
00101     FREE( pFileGen );
00102     if ( pFile )
00103     {
00104         fclose( pFile );
00105         return pFileNameOther;
00106     }
00107     // did not find :(
00108     return NULL;            
00109 }

char* Extra_FileNameAppend ( char *  pBase,
char *  pSuffix 
)

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

Synopsis [Returns the composite name of the file.]

Description []

SideEffects []

SeeAlso []

Definition at line 143 of file extraUtilFile.c.

00144 {
00145     static char Buffer[500];
00146     sprintf( Buffer, "%s%s", pBase, pSuffix );
00147     return Buffer;
00148 }

char* Extra_FileNameExtension ( char *  FileName  ) 

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

Synopsis [Returns the pointer to the file extension.]

Description []

SideEffects []

SeeAlso []

Definition at line 122 of file extraUtilFile.c.

00123 {
00124     char * pDot;
00125     // find the last "dot" in the file name, if it is present
00126     for ( pDot = FileName + strlen(FileName)-1; pDot >= FileName; pDot-- )
00127         if ( *pDot == '.' )
00128             return pDot + 1;
00129    return NULL;
00130 }

char* Extra_FileNameGeneric ( char *  FileName  ) 

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 161 of file extraUtilFile.c.

00162 {
00163     char * pDot;
00164     char * pUnd;
00165     char * pRes;
00166     
00167     // find the generic name of the file
00168     pRes = Extra_UtilStrsav( FileName );
00169     // find the pointer to the "." symbol in the file name
00170 //  pUnd = strstr( FileName, "_" );
00171     pUnd = NULL;
00172     pDot = strstr( FileName, "." );
00173     if ( pUnd )
00174         pRes[pUnd - FileName] = 0;
00175     else if ( pDot )
00176         pRes[pDot - FileName] = 0;
00177     return pRes;
00178 }

char* Extra_FileRead ( FILE *  pFile  ) 

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

Synopsis [Read the file into the internal buffer.]

Description []

SideEffects []

SeeAlso []

Definition at line 219 of file extraUtilFile.c.

00220 {
00221     int nFileSize;
00222     char * pBuffer;
00223     // get the file size, in bytes
00224     fseek( pFile, 0, SEEK_END );  
00225     nFileSize = ftell( pFile );  
00226     // move the file current reading position to the beginning
00227     rewind( pFile ); 
00228     // load the contents of the file into memory
00229     pBuffer = ALLOC( char, nFileSize + 3 );
00230     fread( pBuffer, nFileSize, 1, pFile );
00231     // terminate the string with '\0'
00232     pBuffer[ nFileSize + 0] = '\n';
00233     pBuffer[ nFileSize + 1] = '\0';
00234     return pBuffer;
00235 }

Extra_FileReader_t* Extra_FileReaderAlloc ( char *  pFileName,
char *  pCharsComment,
char *  pCharsStop,
char *  pCharsClean 
)

FUNCTION DEFINITIONS ///Function*************************************************************

Synopsis [Starts the file reader.]

Description []

SideEffects []

SeeAlso []

Definition at line 84 of file extraUtilReader.c.

00086 {
00087     Extra_FileReader_t * p;
00088     FILE * pFile;
00089     char * pChar;
00090     int nCharsToRead;
00091     // check if the file can be opened
00092     pFile = fopen( pFileName, "rb" );
00093     if ( pFile == NULL )
00094     {
00095         printf( "Extra_FileReaderAlloc(): Cannot open input file \"%s\".\n", pFileName );
00096         return NULL;
00097     }
00098     // start the file reader    
00099     p = ALLOC( Extra_FileReader_t, 1 );
00100     memset( p, 0, sizeof(Extra_FileReader_t) );
00101     p->pFileName   = pFileName;
00102     p->pFile       = pFile;
00103     // set the character map
00104     memset( p->pCharMap, EXTRA_CHAR_NORMAL, 256 );
00105     for ( pChar = pCharsComment; *pChar; pChar++ )
00106         p->pCharMap[(unsigned char)*pChar] = EXTRA_CHAR_COMMENT;
00107     for ( pChar = pCharsStop; *pChar; pChar++ )
00108         p->pCharMap[(unsigned char)*pChar] = EXTRA_CHAR_STOP;
00109     for ( pChar = pCharsClean; *pChar; pChar++ )
00110         p->pCharMap[(unsigned char)*pChar] = EXTRA_CHAR_CLEAN;
00111     // get the file size, in bytes
00112     fseek( pFile, 0, SEEK_END );  
00113     p->nFileSize = ftell( pFile );  
00114     rewind( pFile ); 
00115     // allocate the buffer
00116     p->pBuffer = ALLOC( char, EXTRA_BUFFER_SIZE+1 );
00117     p->nBufferSize = EXTRA_BUFFER_SIZE;
00118     p->pBufferCur  = p->pBuffer;
00119     // determine how many chars to read
00120     nCharsToRead = EXTRA_MINIMUM(p->nFileSize, EXTRA_BUFFER_SIZE);
00121     // load the first part into the buffer
00122     fread( p->pBuffer, nCharsToRead, 1, p->pFile );
00123     p->nFileRead = nCharsToRead;
00124     // set the ponters to the end and the stopping point
00125     p->pBufferEnd  = p->pBuffer + nCharsToRead;
00126     p->pBufferStop = (p->nFileRead == p->nFileSize)? p->pBufferEnd : p->pBuffer + EXTRA_BUFFER_SIZE - EXTRA_OFFSET_SIZE;
00127     // start the arrays
00128     p->vTokens = Vec_PtrAlloc( 100 );
00129     p->vLines = Vec_IntAlloc( 100 );
00130     p->nLineCounter = 1; // 1-based line counting
00131     return p;
00132 }

void Extra_FileReaderFree ( Extra_FileReader_t p  ) 

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

Synopsis [Stops the file reader.]

Description []

SideEffects []

SeeAlso []

Definition at line 145 of file extraUtilReader.c.

00146 {
00147     if ( p->pFile )
00148         fclose( p->pFile );
00149     FREE( p->pBuffer );
00150     Vec_PtrFree( p->vTokens );
00151     Vec_IntFree( p->vLines );
00152     free( p );
00153 }

int Extra_FileReaderGetCurPosition ( Extra_FileReader_t p  ) 

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

Synopsis [Returns the current reading position.]

Description []

SideEffects []

SeeAlso []

Definition at line 198 of file extraUtilReader.c.

00199 {
00200     return p->nFileRead - (p->pBufferEnd - p->pBufferCur);
00201 }

char* Extra_FileReaderGetFileName ( Extra_FileReader_t p  ) 

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

Synopsis [Returns the file size.]

Description []

SideEffects []

SeeAlso []

Definition at line 166 of file extraUtilReader.c.

00167 {
00168     return p->pFileName;
00169 }

int Extra_FileReaderGetFileSize ( Extra_FileReader_t p  ) 

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

Synopsis [Returns the file size.]

Description []

SideEffects []

SeeAlso []

Definition at line 182 of file extraUtilReader.c.

00183 {
00184     return p->nFileSize;
00185 }

int Extra_FileReaderGetLineNumber ( Extra_FileReader_t p,
int  iToken 
)

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

Synopsis [Returns the line number for the given token.]

Description []

SideEffects []

SeeAlso []

Definition at line 214 of file extraUtilReader.c.

00215 {
00216     assert( iToken >= 0 && iToken < p->vTokens->nSize );
00217     return p->vLines->pArray[iToken];
00218 }

void* Extra_FileReaderGetTokens ( Extra_FileReader_t p  ) 

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

Synopsis [Returns the next set of tokens.]

Description []

SideEffects []

SeeAlso []

Definition at line 232 of file extraUtilReader.c.

00233 {
00234     Vec_Ptr_t * vTokens;
00235     while ( vTokens = Extra_FileReaderGetTokens_int( p ) )
00236         if ( vTokens->nSize > 0 )
00237             break;
00238     return vTokens;
00239 }

int Extra_FileSize ( char *  pFileName  ) 

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

Synopsis [Returns the file size.]

Description [The file should be closed.]

SideEffects []

SeeAlso []

Definition at line 191 of file extraUtilFile.c.

00192 {
00193     FILE * pFile;
00194     int nFileSize;
00195     pFile = fopen( pFileName, "r" );
00196     if ( pFile == NULL )
00197     {
00198         printf( "Extra_FileSize(): The file is unavailable (absent or open).\n" );
00199         return 0;
00200     }
00201     fseek( pFile, 0, SEEK_END );  
00202     nFileSize = ftell( pFile ); 
00203     fclose( pFile );
00204     return nFileSize;
00205 }

static int Extra_Float2Int ( float  Val  )  [inline, static]

Definition at line 431 of file extra.h.

00431 { return *((int *)&Val);               }

int Extra_GetSoftDataLimit (  ) 

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

Synopsis [getSoftDataLimit()]

Description []

SideEffects []

SeeAlso []

Definition at line 77 of file extraUtilUtil.c.

00078 {
00079     return EXTRA_RLIMIT_DATA_DEFAULT;
00080 }

static float Extra_Int2Float ( int  Num  )  [inline, static]

Definition at line 432 of file extra.h.

00432 { return *((float *)&Num);             }

char* Extra_MmFixedEntryFetch ( Extra_MmFixed_t p  ) 

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 199 of file extraUtilMemory.c.

00200 {
00201     char * pTemp;
00202     int i;
00203 
00204     // check if there are still free entries
00205     if ( p->nEntriesUsed == p->nEntriesAlloc )
00206     { // need to allocate more entries
00207         assert( p->pEntriesFree == NULL );
00208         if ( p->nChunks == p->nChunksAlloc )
00209         {
00210             p->nChunksAlloc *= 2;
00211             p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc ); 
00212         }
00213         p->pEntriesFree = ALLOC( char, p->nEntrySize * p->nChunkSize );
00214         p->nMemoryAlloc += p->nEntrySize * p->nChunkSize;
00215         // transform these entries into a linked list
00216         pTemp = p->pEntriesFree;
00217         for ( i = 1; i < p->nChunkSize; i++ )
00218         {
00219             *((char **)pTemp) = pTemp + p->nEntrySize;
00220             pTemp += p->nEntrySize;
00221         }
00222         // set the last link
00223         *((char **)pTemp) = NULL;
00224         // add the chunk to the chunk storage
00225         p->pChunks[ p->nChunks++ ] = p->pEntriesFree;
00226         // add to the number of entries allocated
00227         p->nEntriesAlloc += p->nChunkSize;
00228     }
00229     // incrememt the counter of used entries
00230     p->nEntriesUsed++;
00231     if ( p->nEntriesMax < p->nEntriesUsed )
00232         p->nEntriesMax = p->nEntriesUsed;
00233     // return the first entry in the free entry list
00234     pTemp = p->pEntriesFree;
00235     p->pEntriesFree = *((char **)pTemp);
00236     return pTemp;
00237 }

void Extra_MmFixedEntryRecycle ( Extra_MmFixed_t p,
char *  pEntry 
)

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 250 of file extraUtilMemory.c.

00251 {
00252     // decrement the counter of used entries
00253     p->nEntriesUsed--;
00254     // add the entry to the linked list of free entries
00255     *((char **)pEntry) = p->pEntriesFree;
00256     p->pEntriesFree = pEntry;
00257 }

int Extra_MmFixedReadMaxEntriesUsed ( Extra_MmFixed_t p  ) 

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 324 of file extraUtilMemory.c.

00325 {
00326     return p->nEntriesMax;
00327 }

int Extra_MmFixedReadMemUsage ( Extra_MmFixed_t p  ) 

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 308 of file extraUtilMemory.c.

00309 {
00310     return p->nMemoryAlloc;
00311 }

void Extra_MmFixedRestart ( Extra_MmFixed_t p  ) 

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

Synopsis []

Description [Relocates all the memory except the first chunk.]

SideEffects []

SeeAlso []

Definition at line 270 of file extraUtilMemory.c.

00271 {
00272     int i;
00273     char * pTemp;
00274 
00275     // deallocate all chunks except the first one
00276     for ( i = 1; i < p->nChunks; i++ )
00277         free( p->pChunks[i] );
00278     p->nChunks = 1;
00279     // transform these entries into a linked list
00280     pTemp = p->pChunks[0];
00281     for ( i = 1; i < p->nChunkSize; i++ )
00282     {
00283         *((char **)pTemp) = pTemp + p->nEntrySize;
00284         pTemp += p->nEntrySize;
00285     }
00286     // set the last link
00287     *((char **)pTemp) = NULL;
00288     // set the free entry list
00289     p->pEntriesFree  = p->pChunks[0];
00290     // set the correct statistics
00291     p->nMemoryAlloc  = p->nEntrySize * p->nChunkSize;
00292     p->nMemoryUsed   = 0;
00293     p->nEntriesAlloc = p->nChunkSize;
00294     p->nEntriesUsed  = 0;
00295 }

Extra_MmFixed_t* Extra_MmFixedStart ( int  nEntrySize  ) 

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

Synopsis [Allocates memory pieces of fixed size.]

Description [The size of the chunk is computed as the minimum of 1024 entries and 64K. Can only work with entry size at least 4 byte long.]

SideEffects []

SeeAlso []

Definition at line 119 of file extraUtilMemory.c.

00120 {
00121     Extra_MmFixed_t * p;
00122 
00123     p = ALLOC( Extra_MmFixed_t, 1 );
00124     memset( p, 0, sizeof(Extra_MmFixed_t) );
00125 
00126     p->nEntrySize    = nEntrySize;
00127     p->nEntriesAlloc = 0;
00128     p->nEntriesUsed  = 0;
00129     p->pEntriesFree  = NULL;
00130 
00131     if ( nEntrySize * (1 << 10) < (1<<16) )
00132         p->nChunkSize = (1 << 10);
00133     else
00134         p->nChunkSize = (1<<16) / nEntrySize;
00135     if ( p->nChunkSize < 8 )
00136         p->nChunkSize = 8;
00137 
00138     p->nChunksAlloc  = 64;
00139     p->nChunks       = 0;
00140     p->pChunks       = ALLOC( char *, p->nChunksAlloc );
00141 
00142     p->nMemoryUsed   = 0;
00143     p->nMemoryAlloc  = 0;
00144     return p;
00145 }

void Extra_MmFixedStop ( Extra_MmFixed_t p  ) 

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 177 of file extraUtilMemory.c.

00178 {
00179     int i;
00180     if ( p == NULL )
00181         return;
00182     for ( i = 0; i < p->nChunks; i++ )
00183         free( p->pChunks[i] );
00184     free( p->pChunks );
00185     free( p );
00186 }

char* Extra_MmFlexEntryFetch ( Extra_MmFlex_t p,
int  nBytes 
)

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 415 of file extraUtilMemory.c.

00416 {
00417     char * pTemp;
00418     // check if there are still free entries
00419     if ( p->pCurrent == NULL || p->pCurrent + nBytes > p->pEnd )
00420     { // need to allocate more entries
00421         if ( p->nChunks == p->nChunksAlloc )
00422         {
00423             p->nChunksAlloc *= 2;
00424             p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc ); 
00425         }
00426         if ( nBytes > p->nChunkSize )
00427         {
00428             // resize the chunk size if more memory is requested than it can give
00429             // (ideally, this should never happen)
00430             p->nChunkSize = 2 * nBytes;
00431         }
00432         p->pCurrent = ALLOC( char, p->nChunkSize );
00433         p->pEnd     = p->pCurrent + p->nChunkSize;
00434         p->nMemoryAlloc += p->nChunkSize;
00435         // add the chunk to the chunk storage
00436         p->pChunks[ p->nChunks++ ] = p->pCurrent;
00437     }
00438     assert( p->pCurrent + nBytes <= p->pEnd );
00439     // increment the counter of used entries
00440     p->nEntriesUsed++;
00441     // keep track of the memory used
00442     p->nMemoryUsed += nBytes;
00443     // return the next entry
00444     pTemp = p->pCurrent;
00445     p->pCurrent += nBytes;
00446     return pTemp;
00447 }

void Extra_MmFlexPrint ( Extra_MmFlex_t p  ) 

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 373 of file extraUtilMemory.c.

00374 {
00375     printf( "Flexible memory manager: Chunk size = %d. Chunks used = %d.\n",
00376         p->nChunkSize, p->nChunks );
00377     printf( "   Entries used = %d. Memory used = %d. Memory alloc = %d.\n",
00378         p->nEntriesUsed, p->nMemoryUsed, p->nMemoryAlloc );
00379 }

int Extra_MmFlexReadMemUsage ( Extra_MmFlex_t p  ) 

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 460 of file extraUtilMemory.c.

00461 {
00462     return p->nMemoryAlloc;
00463 }

Extra_MmFlex_t* Extra_MmFlexStart (  ) 

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

Synopsis [Allocates entries of flexible size.]

Description [Can only work with entry size at least 4 byte long.]

SideEffects []

SeeAlso []

Definition at line 341 of file extraUtilMemory.c.

00342 {
00343     Extra_MmFlex_t * p;
00344 //printf( "allocing flex\n" );
00345     p = ALLOC( Extra_MmFlex_t, 1 );
00346     memset( p, 0, sizeof(Extra_MmFlex_t) );
00347 
00348     p->nEntriesUsed  = 0;
00349     p->pCurrent      = NULL;
00350     p->pEnd          = NULL;
00351 
00352     p->nChunkSize    = (1 << 10);
00353     p->nChunksAlloc  = 64;
00354     p->nChunks       = 0;
00355     p->pChunks       = ALLOC( char *, p->nChunksAlloc );
00356 
00357     p->nMemoryUsed   = 0;
00358     p->nMemoryAlloc  = 0;
00359     return p;
00360 }

void Extra_MmFlexStop ( Extra_MmFlex_t p  ) 

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 392 of file extraUtilMemory.c.

00393 {
00394     int i;
00395     if ( p == NULL )
00396         return;
00397 //printf( "deleting flex\n" );
00398     for ( i = 0; i < p->nChunks; i++ )
00399         free( p->pChunks[i] );
00400     free( p->pChunks );
00401     free( p );
00402 }

char* Extra_MmStepEntryFetch ( Extra_MmStep_t p,
int  nBytes 
)

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

Synopsis [Creates the entry.]

Description []

SideEffects []

SeeAlso []

Definition at line 552 of file extraUtilMemory.c.

00553 {
00554     if ( nBytes == 0 )
00555         return NULL;
00556     if ( nBytes > p->nMapSize )
00557     {
00558 //        printf( "Allocating %d bytes.\n", nBytes );
00559 /*
00560         if ( p->nLargeChunks == p->nLargeChunksAlloc )
00561         {
00562             if ( p->nLargeChunksAlloc == 0 )
00563                 p->nLargeChunksAlloc = 5;
00564             p->nLargeChunksAlloc *= 2;
00565             p->pLargeChunks = REALLOC( char *, p->pLargeChunks, p->nLargeChunksAlloc ); 
00566         }
00567         p->pLargeChunks[ p->nLargeChunks++ ] = ALLOC( char, nBytes );
00568         return p->pLargeChunks[ p->nLargeChunks - 1 ];
00569 */
00570         return ALLOC( char, nBytes );
00571     }
00572     return Extra_MmFixedEntryFetch( p->pMap[nBytes] );
00573 }

void Extra_MmStepEntryRecycle ( Extra_MmStep_t p,
char *  pEntry,
int  nBytes 
)

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

Synopsis [Recycles the entry.]

Description []

SideEffects []

SeeAlso []

Definition at line 587 of file extraUtilMemory.c.

00588 {
00589     if ( nBytes == 0 )
00590         return;
00591     if ( nBytes > p->nMapSize )
00592     {
00593         free( pEntry );
00594         return;
00595     }
00596     Extra_MmFixedEntryRecycle( p->pMap[nBytes], pEntry );
00597 }

int Extra_MmStepReadMemUsage ( Extra_MmStep_t p  ) 

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 610 of file extraUtilMemory.c.

00611 {
00612     int i, nMemTotal = 0;
00613     for ( i = 0; i < p->nMems; i++ )
00614         nMemTotal += p->pMems[i]->nMemoryAlloc;
00615     return nMemTotal;
00616 }

Extra_MmStep_t* Extra_MmStepStart ( int  nSteps  ) 

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

Synopsis [Starts the hierarchical memory manager.]

Description [This manager can allocate entries of any size. Iternally they are mapped into the entries with the number of bytes equal to the power of 2. The smallest entry size is 8 bytes. The next one is 16 bytes etc. So, if the user requests 6 bytes, he gets 8 byte entry. If we asks for 25 bytes, he gets 32 byte entry etc. The input parameters "nSteps" says how many fixed memory managers are employed internally. Calling this procedure with nSteps equal to 10 results in 10 hierarchically arranged internal memory managers, which can allocate up to 4096 (1Kb) entries. Requests for larger entries are handed over to malloc() and then free()ed.]

SideEffects []

SeeAlso []

Definition at line 489 of file extraUtilMemory.c.

00490 {
00491     Extra_MmStep_t * p;
00492     int i, k;
00493     p = ALLOC( Extra_MmStep_t, 1 );
00494     memset( p, 0, sizeof(Extra_MmStep_t) );
00495     p->nMems = nSteps;
00496     // start the fixed memory managers
00497     p->pMems = ALLOC( Extra_MmFixed_t *, p->nMems );
00498     for ( i = 0; i < p->nMems; i++ )
00499         p->pMems[i] = Extra_MmFixedStart( (8<<i) );
00500     // set up the mapping of the required memory size into the corresponding manager
00501     p->nMapSize = (4<<p->nMems);
00502     p->pMap = ALLOC( Extra_MmFixed_t *, p->nMapSize+1 );
00503     p->pMap[0] = NULL;
00504     for ( k = 1; k <= 4; k++ )
00505         p->pMap[k] = p->pMems[0];
00506     for ( i = 0; i < p->nMems; i++ )
00507         for ( k = (4<<i)+1; k <= (8<<i); k++ )
00508             p->pMap[k] = p->pMems[i];
00509 //for ( i = 1; i < 100; i ++ )
00510 //printf( "%10d: size = %10d\n", i, p->pMap[i]->nEntrySize );
00511     return p;
00512 }

void Extra_MmStepStop ( Extra_MmStep_t p  ) 

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

Synopsis [Stops the memory manager.]

Description []

SideEffects []

SeeAlso []

Definition at line 525 of file extraUtilMemory.c.

00526 {
00527     int i;
00528     for ( i = 0; i < p->nMems; i++ )
00529         Extra_MmFixedStop( p->pMems[i] );
00530 //    if ( p->pLargeChunks ) 
00531 //    {
00532 //      for ( i = 0; i < p->nLargeChunks; i++ )
00533 //          free( p->pLargeChunks[i] );
00534 //      free( p->pLargeChunks );
00535 //    }
00536     free( p->pMems );
00537     free( p->pMap );
00538     free( p );
00539 }

int Extra_NumCombinations ( int  k,
int  n 
)

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

Synopsis [Finds the number of combinations of k elements out of n.]

Description []

SideEffects []

SeeAlso []

Definition at line 179 of file extraUtilMisc.c.

00180 {
00181     int i, Res = 1;
00182     for ( i = 1; i <= k; i++ )
00183             Res = Res * (n-i+1) / i;
00184     return Res;
00185 } /* end of Extra_NumCombinations */

char** Extra_Permutations ( int  n  ) 

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

Synopsis [Computes the set of all permutations.]

Description [The number of permutations in the array is n!. The number of entries in each permutation is n. Therefore, the resulting array is a two-dimentional array of the size: n! x n. To free the resulting array, call free() on the pointer returned by this procedure.]

SideEffects []

SeeAlso []

Definition at line 276 of file extraUtilMisc.c.

00277 {
00278     char Array[50];
00279     char ** pRes;
00280     int nFact, i;
00281     // allocate memory
00282     nFact = Extra_Factorial( n );
00283     pRes  = (char **)Extra_ArrayAlloc( nFact, n, sizeof(char) );
00284     // fill in the permutations
00285     for ( i = 0; i < n; i++ )
00286         Array[i] = i;
00287     Extra_Permutations_rec( pRes, nFact, n, Array );
00288     // print the permutations
00289 /*
00290     {
00291     int i, k;
00292     for ( i = 0; i < nFact; i++ )
00293     {
00294         printf( "{" );
00295         for ( k = 0; k < n; k++ )
00296             printf( " %d", pRes[i][k] );
00297         printf( " }\n" );
00298     }
00299     }
00300 */
00301     return pRes;
00302 }

double Extra_Power2 ( int  Degree  ) 

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

Synopsis [Returns the power of two as a double.]

Description []

SideEffects []

SeeAlso []

Definition at line 136 of file extraUtilMisc.c.

00137 {
00138     double Res;
00139     assert( Degree >= 0 );
00140     if ( Degree < 32 )
00141         return (double)(01<<Degree); 
00142     for ( Res = 1.0; Degree; Res *= 2.0, Degree-- );
00143     return Res;
00144 }

int Extra_Power3 ( int  Num  ) 

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 158 of file extraUtilMisc.c.

00159 {
00160     int i;
00161     int Res;
00162     Res = 1;
00163     for ( i = 0; i < Num; i++ )
00164         Res *= 3;
00165     return Res;
00166 }

void Extra_PrintBinary ( FILE *  pFile,
unsigned  Sign[],
int  nBits 
)

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

Synopsis [Prints the bit string.]

Description []

SideEffects []

SeeAlso []

Definition at line 299 of file extraUtilFile.c.

00300 {
00301     int Remainder, nWords;
00302     int w, i;
00303 
00304     Remainder = (nBits%(sizeof(unsigned)*8));
00305     nWords    = (nBits/(sizeof(unsigned)*8)) + (Remainder>0);
00306 
00307     for ( w = nWords-1; w >= 0; w-- )
00308         for ( i = ((w == nWords-1 && Remainder)? Remainder-1: 31); i >= 0; i-- )
00309             fprintf( pFile, "%c", '0' + (int)((Sign[w] & (1<<i)) > 0) );
00310 
00311 //  fprintf( pFile, "\n" );
00312 }

void Extra_PrintHex ( FILE *  pFile,
unsigned  uTruth,
int  nVars 
)

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

Synopsis [Prints the hex unsigned into a file.]

Description []

SideEffects []

SeeAlso []

Definition at line 416 of file extraUtilFile.c.

00417 {
00418     int nMints, nDigits, Digit, k;
00419 
00420     // write the number into the file
00421     fprintf( pFile, "0x" );
00422     nMints  = (1 << nVars);
00423     nDigits = nMints / 4;
00424     for ( k = nDigits - 1; k >= 0; k-- )
00425     {
00426         Digit = ((uTruth >> (k * 4)) & 15);
00427         if ( Digit < 10 )
00428             fprintf( pFile, "%d", Digit );
00429         else
00430             fprintf( pFile, "%c", 'a' + Digit-10 );
00431     }
00432 //    fprintf( pFile, "\n" );
00433 }

void Extra_PrintHexadecimal ( FILE *  pFile,
unsigned  Sign[],
int  nVars 
)

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

Synopsis [Prints the hex unsigned into a file.]

Description []

SideEffects []

SeeAlso []

Definition at line 361 of file extraUtilFile.c.

00362 {
00363     int nDigits, Digit, k;
00364     // write the number into the file
00365     nDigits = (1 << nVars) / 4;
00366     for ( k = nDigits - 1; k >= 0; k-- )
00367     {
00368         Digit = ((Sign[k/8] >> ((k%8) * 4)) & 15);
00369         if ( Digit < 10 )
00370             fprintf( pFile, "%d", Digit );
00371         else
00372             fprintf( pFile, "%c", 'a' + Digit-10 );
00373     }
00374 //    fprintf( pFile, "\n" );
00375 }

void Extra_PrintHexadecimalString ( char *  pString,
unsigned  Sign[],
int  nVars 
)

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

Synopsis [Prints the hex unsigned into a file.]

Description []

SideEffects []

SeeAlso []

Definition at line 388 of file extraUtilFile.c.

00389 {
00390     int nDigits, Digit, k;
00391     // write the number into the file
00392     nDigits = (1 << nVars) / 4;
00393     for ( k = nDigits - 1; k >= 0; k-- )
00394     {
00395         Digit = ((Sign[k/8] >> ((k%8) * 4)) & 15);
00396         if ( Digit < 10 )
00397             *pString++ = '0' + Digit;
00398         else
00399             *pString++ = 'a' + Digit-10;
00400     }
00401 //    fprintf( pFile, "\n" );
00402     *pString = 0;
00403 }

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

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 190 of file extraBddKmap.c.

00199 {
00200     int d, p, n, s, v, h, w;
00201     int nVarsVer;
00202     int nVarsHor;
00203     int nCellsVer;
00204     int nCellsHor;
00205     int nSkipSpaces;
00206 
00207     // make sure that on-set and off-set do not overlap
00208     if ( !Cudd_bddLeq( dd, OnSet, Cudd_Not(OffSet) ) )
00209     {
00210         fprintf( Output, "PrintKMap(): The on-set and the off-set overlap\n" );
00211         return;
00212     }
00213 /*
00214     if ( OnSet == b1 )
00215     {
00216         fprintf( Output, "PrintKMap(): Constant 1\n" );
00217         return;
00218     }
00219     if ( OffSet == b1 )
00220     {
00221         fprintf( Output, "PrintKMap(): Constant 0\n" );
00222         return;
00223     }
00224 */
00225     if ( nVars < 0 || nVars > MAXVARS )
00226     {
00227         fprintf( Output, "PrintKMap(): The number of variables is less than zero or more than %d\n", MAXVARS );
00228         return;
00229     }
00230 
00231     // determine the support if it is not given
00232     if ( XVars == NULL )
00233     {
00234         if ( fSuppType == 0 )
00235         {   // assume that the support includes the first nVars of the manager
00236             assert( nVars );
00237             for ( v = 0; v < nVars; v++ )
00238                 s_XVars[v] = Cudd_bddIthVar( dd, v );
00239         }
00240         else if ( fSuppType == 1 )
00241         {   // assume that the support includes the topmost nVars of the manager
00242             assert( nVars );
00243             for ( v = 0; v < nVars; v++ )
00244                 s_XVars[v] = Cudd_bddIthVar( dd, dd->invperm[v] );
00245         }
00246         else // determine the support
00247         {
00248             DdNode * SuppOn, * SuppOff, * Supp;
00249             int cVars = 0;
00250             DdNode * TempSupp;
00251 
00252             // determine support
00253             SuppOn = Cudd_Support( dd, OnSet );         Cudd_Ref( SuppOn );
00254             SuppOff = Cudd_Support( dd, OffSet );       Cudd_Ref( SuppOff );
00255             Supp = Cudd_bddAnd( dd, SuppOn, SuppOff );  Cudd_Ref( Supp );
00256             Cudd_RecursiveDeref( dd, SuppOn );
00257             Cudd_RecursiveDeref( dd, SuppOff );
00258 
00259             nVars = Cudd_SupportSize( dd, Supp );
00260             if ( nVars > MAXVARS )
00261             {
00262                 fprintf( Output, "PrintKMap(): The number of variables is more than %d\n", MAXVARS );
00263                 Cudd_RecursiveDeref( dd, Supp );
00264                 return;
00265             }
00266 
00267             // assign variables
00268             for ( TempSupp = Supp; TempSupp != dd->one; TempSupp = Cudd_T(TempSupp), cVars++ )
00269                 s_XVars[cVars] = Cudd_bddIthVar( dd, TempSupp->index );
00270 
00271             Cudd_RecursiveDeref( dd, TempSupp );
00272         }
00273     }
00274     else
00275     {
00276         // copy variables
00277         assert( XVars );
00278         for ( v = 0; v < nVars; v++ )
00279             s_XVars[v] = XVars[v];
00280     }
00281 
00283     // determine the Karnaugh map parameters
00284     nVarsVer = nVars/2;
00285     nVarsHor = nVars - nVarsVer;
00286     nCellsVer = (1<<nVarsVer);
00287     nCellsHor = (1<<nVarsHor);
00288     nSkipSpaces = nVarsVer + 1;
00289 
00291     // print variable names
00292     fprintf( Output, "\n" );
00293     for ( w = 0; w < nVarsVer; w++ )
00294         if ( pVarNames == NULL )
00295             fprintf( Output, "%c", 'a'+nVarsHor+w );
00296         else
00297             fprintf( Output, " %s", pVarNames[nVarsHor+w] );
00298 
00299     if ( fHorizontalVarNamesPrintedAbove )
00300     {
00301         fprintf( Output, " \\ " );
00302         for ( w = 0; w < nVarsHor; w++ )
00303             if ( pVarNames == NULL )
00304                 fprintf( Output, "%c", 'a'+w );
00305             else
00306                 fprintf( Output, "%s ", pVarNames[w] );
00307     }
00308     fprintf( Output, "\n" );
00309 
00310     if ( fHorizontalVarNamesPrintedAbove )
00311     {
00313         // print horizontal digits
00314         for ( d = 0; d < nVarsHor; d++ )
00315         {
00316             for ( p = 0; p < nSkipSpaces + 2; p++, fprintf( Output, " " ) );
00317             for ( n = 0; n < nCellsHor; n++ )
00318                 if ( GrayCode(n) & (1<<(nVarsHor-1-d)) )
00319                     fprintf( Output, "1   " );
00320                 else
00321                     fprintf( Output, "0   " );
00322             fprintf( Output, "\n" );
00323         }
00324     }
00325 
00327     // print the upper line
00328     for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
00329     fprintf( Output, "%c", DOUBLE_TOP_LEFT );
00330     for ( s = 0; s < nCellsHor; s++ )
00331     {
00332         fprintf( Output, "%c", DOUBLE_HORIZONTAL );
00333         fprintf( Output, "%c", DOUBLE_HORIZONTAL );
00334         fprintf( Output, "%c", DOUBLE_HORIZONTAL );
00335         if ( s != nCellsHor-1 )
00336             if ( s&1 )
00337                 fprintf( Output, "%c", D_JOINS_D_HOR_BOT );
00338             else
00339                 fprintf( Output, "%c", S_JOINS_D_HOR_BOT );
00340     }
00341     fprintf( Output, "%c", DOUBLE_TOP_RIGHT );
00342     fprintf( Output, "\n" );
00343 
00345     // print the map
00346     for ( v = 0; v < nCellsVer; v++ )
00347     {
00348         DdNode * CubeVerBDD;
00349 
00350         // print horizontal digits
00351 //      for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
00352         for ( n = 0; n < nVarsVer; n++ )
00353             if ( GrayCode(v) & (1<<(nVarsVer-1-n)) )
00354                 fprintf( Output, "1" );
00355             else
00356                 fprintf( Output, "0" );
00357         fprintf( Output, " " );
00358 
00359         // find vertical cube
00360         CubeVerBDD = Extra_bddBitsToCube( dd, GrayCode(v), nVarsVer, s_XVars+nVarsHor, 1 );    Cudd_Ref( CubeVerBDD );
00361 
00362         // print text line
00363         fprintf( Output, "%c", DOUBLE_VERTICAL );
00364         for ( h = 0; h < nCellsHor; h++ )
00365         {
00366             DdNode * CubeHorBDD, * Prod, * ValueOnSet, * ValueOffSet;
00367 
00368             fprintf( Output, " " );
00369 //          fprintf( Output, "x" );
00371             // determine what should be printed
00372             CubeHorBDD  = Extra_bddBitsToCube( dd, GrayCode(h), nVarsHor, s_XVars, 1 );    Cudd_Ref( CubeHorBDD );
00373             Prod = Cudd_bddAnd( dd, CubeHorBDD, CubeVerBDD );                   Cudd_Ref( Prod );
00374             Cudd_RecursiveDeref( dd, CubeHorBDD );
00375 
00376             ValueOnSet  = Cudd_Cofactor( dd, OnSet, Prod );                     Cudd_Ref( ValueOnSet );
00377             ValueOffSet = Cudd_Cofactor( dd, OffSet, Prod );                    Cudd_Ref( ValueOffSet );
00378             Cudd_RecursiveDeref( dd, Prod );
00379 
00380             if ( ValueOnSet == b1 && ValueOffSet == b0 )
00381                 fprintf( Output, "%c", SYMBOL_ONE );
00382             else if ( ValueOnSet == b0 && ValueOffSet == b1 )
00383                 fprintf( Output, "%c", SYMBOL_ZERO );
00384             else if ( ValueOnSet == b0 && ValueOffSet == b0 ) 
00385                 fprintf( Output, "%c", SYMBOL_DC );
00386             else if ( ValueOnSet == b1 && ValueOffSet == b1 ) 
00387                 fprintf( Output, "%c", SYMBOL_OVERLAP );
00388             else
00389                 assert(0);
00390 
00391             Cudd_RecursiveDeref( dd, ValueOnSet );
00392             Cudd_RecursiveDeref( dd, ValueOffSet );
00394             fprintf( Output, " " );
00395 
00396             if ( h != nCellsHor-1 )
00397                 if ( h&1 )
00398                     fprintf( Output, "%c", DOUBLE_VERTICAL );
00399                 else
00400                     fprintf( Output, "%c", SINGLE_VERTICAL );
00401         }
00402         fprintf( Output, "%c", DOUBLE_VERTICAL );
00403         fprintf( Output, "\n" );
00404 
00405         Cudd_RecursiveDeref( dd, CubeVerBDD );
00406 
00407         if ( v != nCellsVer-1 )
00408         // print separator line
00409         {
00410             for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
00411             if ( v&1 )
00412             {
00413                 fprintf( Output, "%c", D_JOINS_D_VER_RIGHT );
00414                 for ( s = 0; s < nCellsHor; s++ )
00415                 {
00416                     fprintf( Output, "%c", DOUBLE_HORIZONTAL );
00417                     fprintf( Output, "%c", DOUBLE_HORIZONTAL );
00418                     fprintf( Output, "%c", DOUBLE_HORIZONTAL );
00419                     if ( s != nCellsHor-1 )
00420                         if ( s&1 )
00421                             fprintf( Output, "%c", DOUBLES_CROSS );
00422                         else
00423                             fprintf( Output, "%c", S_VER_CROSS_D_HOR );
00424                 }
00425                 fprintf( Output, "%c", D_JOINS_D_VER_LEFT );
00426             }
00427             else
00428             {
00429                 fprintf( Output, "%c", S_JOINS_D_VER_RIGHT );
00430                 for ( s = 0; s < nCellsHor; s++ )
00431                 {
00432                     fprintf( Output, "%c", SINGLE_HORIZONTAL );
00433                     fprintf( Output, "%c", SINGLE_HORIZONTAL );
00434                     fprintf( Output, "%c", SINGLE_HORIZONTAL );
00435                     if ( s != nCellsHor-1 )
00436                         if ( s&1 )
00437                             fprintf( Output, "%c", S_HOR_CROSS_D_VER );
00438                         else
00439                             fprintf( Output, "%c", SINGLES_CROSS );
00440                 }
00441                 fprintf( Output, "%c", S_JOINS_D_VER_LEFT );
00442             }
00443             fprintf( Output, "\n" );
00444         }
00445     }
00446     
00448     // print the lower line
00449     for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
00450     fprintf( Output, "%c", DOUBLE_BOT_LEFT );
00451     for ( s = 0; s < nCellsHor; s++ )
00452     {
00453         fprintf( Output, "%c", DOUBLE_HORIZONTAL );
00454         fprintf( Output, "%c", DOUBLE_HORIZONTAL );
00455         fprintf( Output, "%c", DOUBLE_HORIZONTAL );
00456         if ( s != nCellsHor-1 )
00457             if ( s&1 )
00458                 fprintf( Output, "%c", D_JOINS_D_HOR_TOP );
00459             else
00460                 fprintf( Output, "%c", S_JOINS_D_HOR_TOP );
00461     }
00462     fprintf( Output, "%c", DOUBLE_BOT_RIGHT );
00463     fprintf( Output, "\n" );
00464 
00465     if ( !fHorizontalVarNamesPrintedAbove )
00466     {
00468         // print horizontal digits
00469         for ( d = 0; d < nVarsHor; d++ )
00470         {
00471             for ( p = 0; p < nSkipSpaces + 2; p++, fprintf( Output, " " ) );
00472             for ( n = 0; n < nCellsHor; n++ )
00473                 if ( GrayCode(n) & (1<<(nVarsHor-1-d)) )
00474                     fprintf( Output, "1   " );
00475                 else
00476                     fprintf( Output, "0   " );
00477 
00479             fprintf( Output, "%c", (char)('a'+d) );
00481             fprintf( Output, "\n" );
00482         }
00483     }
00484 }

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

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 500 of file extraBddKmap.c.

00509 {
00510     int d, p, n, s, v, h, w;
00511     int nVars;
00512     int nVarsVer;
00513     int nVarsHor;
00514     int nCellsVer;
00515     int nCellsHor;
00516     int nSkipSpaces;
00517 
00518     // make sure that on-set and off-set do not overlap
00519     if ( !Cudd_bddLeq( dd, OnSet, Cudd_Not(OffSet) ) )
00520     {
00521         fprintf( Output, "PrintKMap(): The on-set and the off-set overlap\n" );
00522         return;
00523     }
00524 
00525     if ( OnSet == b1 )
00526     {
00527         fprintf( Output, "PrintKMap(): Constant 1\n" );
00528         return;
00529     }
00530     if ( OffSet == b1 )
00531     {
00532         fprintf( Output, "PrintKMap(): Constant 0\n" );
00533         return;
00534     }
00535 
00536     nVars = nXVars + nYVars;
00537     if ( nVars < 0 || nVars > MAXVARS )
00538     {
00539         fprintf( Output, "PrintKMap(): The number of variables is less than zero or more than %d\n", MAXVARS );
00540         return;
00541     }
00542 
00543 
00545     // determine the Karnaugh map parameters
00546     nVarsVer = nXVars;
00547     nVarsHor = nYVars;
00548     nCellsVer = (1<<nVarsVer);
00549     nCellsHor = (1<<nVarsHor);
00550     nSkipSpaces = nVarsVer + 1;
00551 
00553     // print variable names
00554     fprintf( Output, "\n" );
00555     for ( w = 0; w < nVarsVer; w++ )
00556         fprintf( Output, "%c", 'a'+nVarsHor+w );
00557     if ( fHorizontalVarNamesPrintedAbove )
00558     {
00559         fprintf( Output, " \\ " );
00560         for ( w = 0; w < nVarsHor; w++ )
00561             fprintf( Output, "%c", 'a'+w );
00562     }
00563     fprintf( Output, "\n" );
00564 
00565     if ( fHorizontalVarNamesPrintedAbove )
00566     {
00568         // print horizontal digits
00569         for ( d = 0; d < nVarsHor; d++ )
00570         {
00571             for ( p = 0; p < nSkipSpaces + 2; p++, fprintf( Output, " " ) );
00572             for ( n = 0; n < nCellsHor; n++ )
00573                 if ( GrayCode(n) & (1<<(nVarsHor-1-d)) )
00574                     fprintf( Output, "1   " );
00575                 else
00576                     fprintf( Output, "0   " );
00577             fprintf( Output, "\n" );
00578         }
00579     }
00580 
00582     // print the upper line
00583     for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
00584     fprintf( Output, "%c", DOUBLE_TOP_LEFT );
00585     for ( s = 0; s < nCellsHor; s++ )
00586     {
00587         fprintf( Output, "%c", DOUBLE_HORIZONTAL );
00588         fprintf( Output, "%c", DOUBLE_HORIZONTAL );
00589         fprintf( Output, "%c", DOUBLE_HORIZONTAL );
00590         if ( s != nCellsHor-1 )
00591             if ( s&1 )
00592                 fprintf( Output, "%c", D_JOINS_D_HOR_BOT );
00593             else
00594                 fprintf( Output, "%c", S_JOINS_D_HOR_BOT );
00595     }
00596     fprintf( Output, "%c", DOUBLE_TOP_RIGHT );
00597     fprintf( Output, "\n" );
00598 
00600     // print the map
00601     for ( v = 0; v < nCellsVer; v++ )
00602     {
00603         DdNode * CubeVerBDD;
00604 
00605         // print horizontal digits
00606 //      for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
00607         for ( n = 0; n < nVarsVer; n++ )
00608             if ( GrayCode(v) & (1<<(nVarsVer-1-n)) )
00609                 fprintf( Output, "1" );
00610             else
00611                 fprintf( Output, "0" );
00612         fprintf( Output, " " );
00613 
00614         // find vertical cube
00615 //      CubeVerBDD = Extra_bddBitsToCube( dd, GrayCode(v), nVarsVer, s_XVars+nVarsHor );    Cudd_Ref( CubeVerBDD );
00616         CubeVerBDD = Extra_bddBitsToCube( dd, GrayCode(v), nXVars, XVars, 1 );                 Cudd_Ref( CubeVerBDD );
00617 
00618         // print text line
00619         fprintf( Output, "%c", DOUBLE_VERTICAL );
00620         for ( h = 0; h < nCellsHor; h++ )
00621         {
00622             DdNode * CubeHorBDD, * Prod, * ValueOnSet, * ValueOffSet;
00623 
00624             fprintf( Output, " " );
00625 //          fprintf( Output, "x" );
00627             // determine what should be printed
00628 //          CubeHorBDD  = Extra_bddBitsToCube( dd, GrayCode(h), nVarsHor, s_XVars );    Cudd_Ref( CubeHorBDD );
00629             CubeHorBDD  = Extra_bddBitsToCube( dd, GrayCode(h), nYVars, YVars, 1 );        Cudd_Ref( CubeHorBDD );
00630             Prod = Cudd_bddAnd( dd, CubeHorBDD, CubeVerBDD );                           Cudd_Ref( Prod );
00631             Cudd_RecursiveDeref( dd, CubeHorBDD );
00632 
00633             ValueOnSet  = Cudd_Cofactor( dd, OnSet, Prod );                     Cudd_Ref( ValueOnSet );
00634             ValueOffSet = Cudd_Cofactor( dd, OffSet, Prod );                    Cudd_Ref( ValueOffSet );
00635             Cudd_RecursiveDeref( dd, Prod );
00636 
00637             if ( ValueOnSet == b1 && ValueOffSet == b0 )
00638                 fprintf( Output, "%c", SYMBOL_ONE );
00639             else if ( ValueOnSet == b0 && ValueOffSet == b1 )
00640                 fprintf( Output, "%c", SYMBOL_ZERO );
00641             else if ( ValueOnSet == b0 && ValueOffSet == b0 ) 
00642                 fprintf( Output, "%c", SYMBOL_DC );
00643             else if ( ValueOnSet == b1 && ValueOffSet == b1 ) 
00644                 fprintf( Output, "%c", SYMBOL_OVERLAP );
00645             else
00646                 assert(0);
00647 
00648             Cudd_RecursiveDeref( dd, ValueOnSet );
00649             Cudd_RecursiveDeref( dd, ValueOffSet );
00651             fprintf( Output, " " );
00652 
00653             if ( h != nCellsHor-1 )
00654                 if ( h&1 )
00655                     fprintf( Output, "%c", DOUBLE_VERTICAL );
00656                 else
00657                     fprintf( Output, "%c", SINGLE_VERTICAL );
00658         }
00659         fprintf( Output, "%c", DOUBLE_VERTICAL );
00660         fprintf( Output, "\n" );
00661 
00662         Cudd_RecursiveDeref( dd, CubeVerBDD );
00663 
00664         if ( v != nCellsVer-1 )
00665         // print separator line
00666         {
00667             for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
00668             if ( v&1 )
00669             {
00670                 fprintf( Output, "%c", D_JOINS_D_VER_RIGHT );
00671                 for ( s = 0; s < nCellsHor; s++ )
00672                 {
00673                     fprintf( Output, "%c", DOUBLE_HORIZONTAL );
00674                     fprintf( Output, "%c", DOUBLE_HORIZONTAL );
00675                     fprintf( Output, "%c", DOUBLE_HORIZONTAL );
00676                     if ( s != nCellsHor-1 )
00677                         if ( s&1 )
00678                             fprintf( Output, "%c", DOUBLES_CROSS );
00679                         else
00680                             fprintf( Output, "%c", S_VER_CROSS_D_HOR );
00681                 }
00682                 fprintf( Output, "%c", D_JOINS_D_VER_LEFT );
00683             }
00684             else
00685             {
00686                 fprintf( Output, "%c", S_JOINS_D_VER_RIGHT );
00687                 for ( s = 0; s < nCellsHor; s++ )
00688                 {
00689                     fprintf( Output, "%c", SINGLE_HORIZONTAL );
00690                     fprintf( Output, "%c", SINGLE_HORIZONTAL );
00691                     fprintf( Output, "%c", SINGLE_HORIZONTAL );
00692                     if ( s != nCellsHor-1 )
00693                         if ( s&1 )
00694                             fprintf( Output, "%c", S_HOR_CROSS_D_VER );
00695                         else
00696                             fprintf( Output, "%c", SINGLES_CROSS );
00697                 }
00698                 fprintf( Output, "%c", S_JOINS_D_VER_LEFT );
00699             }
00700             fprintf( Output, "\n" );
00701         }
00702     }
00703     
00705     // print the lower line
00706     for ( p = 0; p < nSkipSpaces; p++, fprintf( Output, " " ) );
00707     fprintf( Output, "%c", DOUBLE_BOT_LEFT );
00708     for ( s = 0; s < nCellsHor; s++ )
00709     {
00710         fprintf( Output, "%c", DOUBLE_HORIZONTAL );
00711         fprintf( Output, "%c", DOUBLE_HORIZONTAL );
00712         fprintf( Output, "%c", DOUBLE_HORIZONTAL );
00713         if ( s != nCellsHor-1 )
00714             if ( s&1 )
00715                 fprintf( Output, "%c", D_JOINS_D_HOR_TOP );
00716             else
00717                 fprintf( Output, "%c", S_JOINS_D_HOR_TOP );
00718     }
00719     fprintf( Output, "%c", DOUBLE_BOT_RIGHT );
00720     fprintf( Output, "\n" );
00721 
00722     if ( !fHorizontalVarNamesPrintedAbove )
00723     {
00725         // print horizontal digits
00726         for ( d = 0; d < nVarsHor; d++ )
00727         {
00728             for ( p = 0; p < nSkipSpaces + 2; p++, fprintf( Output, " " ) );
00729             for ( n = 0; n < nCellsHor; n++ )
00730                 if ( GrayCode(n) & (1<<(nVarsHor-1-d)) )
00731                     fprintf( Output, "1   " );
00732                 else
00733                     fprintf( Output, "0   " );
00734 
00736             fprintf( Output, "%c", (char)('a'+d) );
00738             fprintf( Output, "\n" );
00739         }
00740     }
00741 }

void Extra_PrintSymbols ( FILE *  pFile,
char  Char,
int  nTimes,
int  fPrintNewLine 
)

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

Synopsis [Returns the composite name of the file.]

Description []

SideEffects []

SeeAlso []

Definition at line 446 of file extraUtilFile.c.

00447 {
00448     int i;
00449     for ( i = 0; i < nTimes; i++ )
00450         printf( "%c", Char );
00451     if ( fPrintNewLine )
00452         printf( "\n" );
00453 }

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

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 516 of file extraBddCas.c.

00517 {
00518         st_generator * gen;
00519         st_table * tNodeTopRef; // this table stores the top level from which this node is pointed to
00520         st_table * tNodes;
00521         DdNode * node;
00522         DdNode * nodeR;
00523         int LevelStart, Limit;
00524     int i, size;
00525         int WidthMax;
00526   
00527         // start the mapping table
00528         tNodeTopRef = st_init_table(st_ptrcmp,st_ptrhash);
00529         // add the topmost node to the profile
00530         extraProfileUpdateTopLevel( tNodeTopRef, 0, Func );
00531 
00532         // collect all nodes
00533         tNodes = Extra_CollectNodes( Func );
00534         // go though all the nodes and set the top level the cofactors are pointed from
00535 //      Cudd_ForeachNode( dd, Func, genDD, node )
00536         st_foreach_item( tNodes, gen, (char**)&node, NULL )
00537         {
00538 //              assert( Cudd_Regular(node) );  // this procedure works only with ADD/ZDD (not BDD w/ compl.edges)
00539                 nodeR = Cudd_Regular(node);
00540                 if ( cuddIsConstant(nodeR) )
00541                         continue;
00542                 // this node is not a constant - consider its cofactors
00543                 extraProfileUpdateTopLevel( tNodeTopRef, dd->perm[node->index]+1, cuddE(nodeR) );
00544                 extraProfileUpdateTopLevel( tNodeTopRef, dd->perm[node->index]+1, cuddT(nodeR) );
00545         }
00546         st_free_table( tNodes );
00547 
00548     // clean the profile
00549     size = ddMax(dd->size, dd->sizeZ) + 1;
00550     for ( i = 0; i < size; i++ ) 
00551                 pProfile[i] = 0;
00552 
00553         // create the profile
00554         st_foreach_item( tNodeTopRef, gen, (char**)&node, (char**)&LevelStart )
00555         {
00556                 nodeR = Cudd_Regular(node);
00557                 Limit = (cuddIsConstant(nodeR))? dd->size: dd->perm[nodeR->index];
00558                 for ( i = LevelStart; i <= Limit; i++ )
00559                         pProfile[i]++;
00560         }
00561 
00562         if ( CutLevel != -1 && CutLevel != 0  )
00563                 size = CutLevel;
00564 
00565         // get the max width
00566         WidthMax = 0;
00567     for ( i = 0; i < size; i++ ) 
00568                 if ( WidthMax < pProfile[i] )
00569                         WidthMax = pProfile[i];
00570 
00571         // deref the table
00572         st_free_table( tNodeTopRef );
00573 
00574         return WidthMax;
00575 } /* end of Extra_ProfileWidth */

ProgressBar* Extra_ProgressBarStart ( FILE *  pFile,
int  nItemsTotal 
)

FUNCTION DEFINITIONS ///Function*************************************************************

Synopsis [Starts the progress bar.]

Description [The first parameter is the output stream (pFile), where the progress is printed. The current printing position should be the first one on the given line. The second parameters is the total number of items that correspond to 100% position of the progress bar.]

SideEffects []

SeeAlso []

Definition at line 58 of file extraUtilProgress.c.

00059 {
00060     ProgressBar * p;
00061     extern int Abc_FrameShowProgress( void * p );
00062     extern void * Abc_FrameGetGlobalFrame();
00063 
00064     if ( !Abc_FrameShowProgress(Abc_FrameGetGlobalFrame()) ) return NULL;
00065     p = ALLOC( ProgressBar, 1 );
00066     memset( p, 0, sizeof(ProgressBar) );
00067     p->pFile       = pFile;
00068     p->nItemsTotal = nItemsTotal;
00069     p->posTotal    = 78;
00070     p->posCur      = 1;
00071     p->nItemsNext  = (int)((7.0+p->posCur)*p->nItemsTotal/p->posTotal);
00072     Extra_ProgressBarShow( p, NULL );
00073     return p;
00074 }

void Extra_ProgressBarStop ( ProgressBar p  ) 

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

Synopsis [Stops the progress bar.]

Description []

SideEffects []

SeeAlso []

Definition at line 117 of file extraUtilProgress.c.

00118 {
00119     if ( p == NULL ) return;
00120     Extra_ProgressBarClean( p );
00121     FREE( p );
00122 }

static void Extra_ProgressBarUpdate ( ProgressBar p,
int  nItemsCur,
char *  pString 
) [inline, static]

Definition at line 426 of file extra.h.

00427 {  if ( p && nItemsCur < *((int*)p) ) return; Extra_ProgressBarUpdate_int(p, nItemsCur, pString); }

void Extra_ProgressBarUpdate_int ( ProgressBar p,
int  nItemsCur,
char *  pString 
)

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

Synopsis [Updates the progress bar.]

Description []

SideEffects []

SeeAlso []

Definition at line 87 of file extraUtilProgress.c.

00088 {
00089     if ( p == NULL ) return;
00090     if ( nItemsCur < p->nItemsNext )
00091         return;
00092     if ( nItemsCur >= p->nItemsTotal )
00093     {
00094         p->posCur = 78;
00095         p->nItemsNext = 0x7FFFFFFF;
00096     }
00097     else
00098     {
00099         p->posCur += 7;
00100         p->nItemsNext = (int)((7.0+p->posCur)*p->nItemsTotal/p->posTotal);
00101     }
00102     Extra_ProgressBarShow( p, pString );
00103 }

unsigned Extra_ReadBinary ( char *  Buffer  ) 

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 272 of file extraUtilFile.c.

00273 {
00274     unsigned Result;
00275     int i;
00276 
00277     Result = 0;
00278     for ( i = 0; Buffer[i]; i++ )
00279         if ( Buffer[i] == '0' || Buffer[i] == '1' )
00280             Result = Result * 2 + Buffer[i] - '0';
00281         else
00282         {
00283             assert( 0 );
00284         }
00285     return Result;
00286 }

int Extra_ReadHexadecimal ( unsigned  Sign[],
char *  pString,
int  nVars 
)

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

Synopsis [Reads the hex unsigned into the bit-string.]

Description []

SideEffects []

SeeAlso []

Definition at line 325 of file extraUtilFile.c.

00326 {
00327     int nWords, nDigits, Digit, k, c;
00328     nWords = Extra_TruthWordNum( nVars );
00329     for ( k = 0; k < nWords; k++ )
00330         Sign[k] = 0;
00331     // read the number from the string
00332     nDigits = (1 << nVars) / 4;
00333     if ( nDigits == 0 )
00334         nDigits = 1;
00335     for ( k = 0; k < nDigits; k++ )
00336     {
00337         c = nDigits-1-k;
00338         if ( pString[c] >= '0' && pString[c] <= '9' )
00339             Digit = pString[c] - '0';
00340         else if ( pString[c] >= 'A' && pString[c] <= 'F' )
00341             Digit = pString[c] - 'A' + 10;
00342         else if ( pString[c] >= 'a' && pString[c] <= 'f' )
00343             Digit = pString[c] - 'a' + 10;
00344         else { assert( 0 ); return 0; }
00345         Sign[k/8] |= ( (Digit & 15) << ((k%8) * 4) );
00346     }
00347     return 1;
00348 }

void Extra_StopManager ( DdManager dd  ) 

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 218 of file extraBddMisc.c.

00219 {
00220     int RetValue;
00221     // check for remaining references in the package
00222     RetValue = Cudd_CheckZeroRef( dd );
00223     if ( RetValue > 0 )
00224         printf( "\nThe number of referenced nodes = %d\n\n", RetValue );
00225 //  Cudd_PrintInfo( dd, stdout );
00226     Cudd_Quit( dd );
00227 }

char* Extra_StringAppend ( char *  pStrGiven,
char *  pStrAdd 
)

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

Synopsis [Appends the string.]

Description [Assumes that the given string (pStrGiven) has been allocated before using malloc(). The additional string has not been allocated. Allocs more root, appends the additional part, frees the old given string.]

SideEffects []

SeeAlso []

Definition at line 468 of file extraUtilFile.c.

00469 {
00470     char * pTemp;
00471     if ( pStrGiven )
00472     {
00473         pTemp = ALLOC( char, strlen(pStrGiven) + strlen(pStrAdd) + 2 );
00474         sprintf( pTemp, "%s%s", pStrGiven, pStrAdd );
00475         free( pStrGiven );
00476     }
00477     else
00478         pTemp = Extra_UtilStrsav( pStrAdd );
00479     return pTemp;
00480 }

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

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 511 of file extraBddMisc.c.

00515 {
00516     int i, size;
00517 
00518     /* Initialize support array for ddSupportStep. */
00519     size = ddMax(dd->size, dd->sizeZ);
00520     for (i = 0; i < size; i++) 
00521         support[i] = 0;
00522     
00523     /* Compute support and clean up markers. */
00524     ddSupportStep(Cudd_Regular(f),support);
00525     ddClearFlag(Cudd_Regular(f));
00526 
00527     return(support);
00528 
00529 } /* end of Extra_SupportArray */

Extra_SymmInfo_t* Extra_SymmPairsAllocate ( int  nVars  ) 

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

Synopsis [Allocates symmetry information structure.]

Description []

SideEffects []

SeeAlso []

Definition at line 204 of file extraBddSymm.c.

00205 {
00206     int i;
00207     Extra_SymmInfo_t * p;
00208 
00209     // allocate and clean the storage for symmetry info
00210     p = ALLOC( Extra_SymmInfo_t, 1 );
00211     memset( p, 0, sizeof(Extra_SymmInfo_t) );
00212     p->nVars     = nVars;
00213     p->pVars     = ALLOC( int, nVars );  
00214     p->pSymms    = ALLOC( char *, nVars );  
00215     p->pSymms[0] = ALLOC( char  , nVars * nVars );
00216     memset( p->pSymms[0], 0, nVars * nVars * sizeof(char) );
00217 
00218     for ( i = 1; i < nVars; i++ )
00219         p->pSymms[i] = p->pSymms[i-1] + nVars;
00220 
00221     return p;
00222 } /* end of Extra_SymmPairsAllocate */

Extra_SymmInfo_t* Extra_SymmPairsCompute ( DdManager dd,
DdNode bFunc 
)

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 70 of file extraBddSymm.c.

00073 {
00074     DdNode * bSupp;
00075     DdNode * zRes;
00076     Extra_SymmInfo_t * p;
00077 
00078     bSupp = Cudd_Support( dd, bFunc );                      Cudd_Ref( bSupp );
00079     zRes  = Extra_zddSymmPairsCompute( dd, bFunc, bSupp );  Cudd_Ref( zRes );
00080 
00081     p = Extra_SymmPairsCreateFromZdd( dd, zRes, bSupp );
00082 
00083     Cudd_RecursiveDeref( dd, bSupp );
00084     Cudd_RecursiveDerefZdd( dd, zRes );
00085 
00086     return p;
00087 
00088 } /* end of Extra_SymmPairsCompute */

Extra_SymmInfo_t* Extra_SymmPairsComputeNaive ( DdManager dd,
DdNode bFunc 
)

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

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

Description [Uses the naive way of comparing cofactors.]

SideEffects []

SeeAlso []

Definition at line 393 of file extraBddSymm.c.

00394 {
00395     DdNode * bSupp, * bTemp;
00396     int nSuppSize;
00397     Extra_SymmInfo_t * p;
00398     int i, k;
00399 
00400     // compute the support
00401     bSupp = Cudd_Support( dd, bFunc );   Cudd_Ref( bSupp );
00402     nSuppSize = Extra_bddSuppSize( dd, bSupp );
00403 //printf( "Support = %d. ", nSuppSize );
00404 //Extra_bddPrint( dd, bSupp );
00405 //printf( "%d ", nSuppSize );
00406 
00407     // allocate the storage for symmetry info
00408     p = Extra_SymmPairsAllocate( nSuppSize );
00409 
00410     // assign the variables
00411     p->nVarsMax = dd->size;
00412     for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ )
00413         p->pVars[i] = bTemp->index;
00414 
00415     // go through the candidate pairs and check using Idea1
00416     for ( i = 0; i < nSuppSize; i++ )
00417     for ( k = i+1; k < nSuppSize; k++ )
00418     {
00419         p->pSymms[k][i] = p->pSymms[i][k] = Extra_bddCheckVarsSymmetricNaive( dd, bFunc, p->pVars[i], p->pVars[k] );
00420         if ( p->pSymms[i][k] )
00421              p->nSymms++;
00422     }
00423 
00424     Cudd_RecursiveDeref( dd, bSupp );
00425     return p;
00426 
00427 } /* end of Extra_SymmPairsComputeNaive */

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

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 285 of file extraBddSymm.c.

00286 {
00287     int i;
00288     int nSuppSize;
00289     Extra_SymmInfo_t * p;
00290     int * pMapVars2Nums;
00291     DdNode * bTemp;
00292     DdNode * zSet, * zCube, * zTemp;
00293     int iVar1, iVar2;
00294 
00295     nSuppSize = Extra_bddSuppSize( dd, bSupp );
00296 
00297     // allocate and clean the storage for symmetry info
00298     p = Extra_SymmPairsAllocate( nSuppSize );
00299 
00300     // allocate the storage for the temporary map
00301     pMapVars2Nums = ALLOC( int, dd->size );
00302     memset( pMapVars2Nums, 0, dd->size * sizeof(int) );
00303 
00304     // assign the variables
00305     p->nVarsMax = dd->size;
00306 //  p->nNodes   = Cudd_DagSize( zPairs );
00307     p->nNodes   = 0;
00308     for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ )
00309     {
00310         p->pVars[i] = bTemp->index;
00311         pMapVars2Nums[bTemp->index] = i;
00312     }
00313 
00314     // write the symmetry info into the structure
00315     zSet = zPairs;   Cudd_Ref( zSet );
00316     while ( zSet != z0 )
00317     {
00318         // get the next cube
00319         zCube  = Extra_zddSelectOneSubset( dd, zSet );    Cudd_Ref( zCube );
00320 
00321         // add these two variables to the data structure
00322         assert( cuddT( cuddT(zCube) ) == z1 );
00323         iVar1 = zCube->index/2;
00324         iVar2 = cuddT(zCube)->index/2;
00325         if ( pMapVars2Nums[iVar1] < pMapVars2Nums[iVar2] )
00326             p->pSymms[ pMapVars2Nums[iVar1] ][ pMapVars2Nums[iVar2] ] = 1;
00327         else
00328             p->pSymms[ pMapVars2Nums[iVar2] ][ pMapVars2Nums[iVar1] ] = 1;
00329         // count the symmetric pairs
00330         p->nSymms ++;
00331 
00332         // update the cuver and deref the cube
00333         zSet = Cudd_zddDiff( dd, zTemp = zSet, zCube );     Cudd_Ref( zSet );
00334         Cudd_RecursiveDerefZdd( dd, zTemp );
00335         Cudd_RecursiveDerefZdd( dd, zCube );
00336 
00337     } // for each cube 
00338     Cudd_RecursiveDerefZdd( dd, zSet );
00339 
00340     FREE( pMapVars2Nums );
00341     return p;
00342 
00343 } /* end of Extra_SymmPairsCreateFromZdd */

void Extra_SymmPairsDissolve ( Extra_SymmInfo_t p  ) 

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

Synopsis [Deallocates symmetry information structure.]

Description []

SideEffects []

SeeAlso []

Definition at line 235 of file extraBddSymm.c.

00236 {
00237     free( p->pVars );
00238     free( p->pSymms[0] );
00239     free( p->pSymms    );
00240     free( p );
00241 } /* end of Extra_SymmPairsDissolve */

void Extra_SymmPairsPrint ( Extra_SymmInfo_t p  ) 

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

Synopsis [Allocates symmetry information structure.]

Description []

SideEffects []

SeeAlso []

Definition at line 254 of file extraBddSymm.c.

00255 {
00256     int i, k;
00257     printf( "\n" );
00258     for ( i = 0; i < p->nVars; i++ )
00259     {
00260         for ( k = 0; k <= i; k++ )
00261             printf( " " );
00262         for ( k = i+1; k < p->nVars; k++ )
00263             if ( p->pSymms[i][k] )
00264                 printf( "1" );
00265             else
00266                 printf( "." );
00267         printf( "\n" );
00268     }
00269 } /* end of Extra_SymmPairsPrint */

char* Extra_TimeStamp (  ) 

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

Synopsis [Returns the time stamp.]

Description [The file should be closed.]

SideEffects []

SeeAlso []

Definition at line 248 of file extraUtilFile.c.

00249 {
00250     static char Buffer[100];
00251         char * TimeStamp;
00252         time_t ltime;
00253     // get the current time
00254         time( &ltime );
00255         TimeStamp = asctime( localtime( &ltime ) );
00256         TimeStamp[ strlen(TimeStamp) - 1 ] = 0;
00257     strcpy( Buffer, TimeStamp );
00258     return Buffer;
00259 }

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

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 107 of file extraBddMisc.c.

00108 {
00109     DdNode * bRes;
00110     int * pPermute;
00111     int nMin, nMax, i;
00112 
00113     nMin = ddMin(ddSource->size, ddDestination->size);
00114     nMax = ddMax(ddSource->size, ddDestination->size);
00115     pPermute = ALLOC( int, nMax );
00116     // set up the variable permutation
00117     for ( i = 0; i < nMin; i++ )
00118         pPermute[ ddSource->invperm[i] ] = ddDestination->invperm[i];
00119     if ( ddSource->size > ddDestination->size )
00120     {
00121         for (      ; i < nMax; i++ )
00122             pPermute[ ddSource->invperm[i] ] = -1;
00123     }
00124     bRes = Extra_TransferPermute( ddSource, ddDestination, f, pPermute );
00125     FREE( pPermute );
00126     return bRes;
00127 }

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

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 82 of file extraBddMisc.c.

00083 {
00084     DdNode * bRes;
00085     do
00086     {
00087         ddDestination->reordered = 0;
00088         bRes = extraTransferPermute( ddSource, ddDestination, f, Permute );
00089     }
00090     while ( ddDestination->reordered == 1 );
00091     return ( bRes );
00092 
00093 }                               /* end of Extra_TransferPermute */

void Extra_Truth4VarN ( unsigned short **  puCanons,
char ***  puPhases,
char **  ppCounters,
int  nPhasesMax 
)

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

Synopsis [Computes NPN canonical forms for 4-variable functions.]

Description []

SideEffects []

SeeAlso []

Definition at line 852 of file extraUtilMisc.c.

00853 {
00854     unsigned short * uCanons;
00855     unsigned uTruth, uPhase;
00856     char ** uPhases, * pCounters;
00857     int nFuncs, nClasses, i;
00858 
00859     nFuncs  = (1 << 16);
00860     uCanons = ALLOC( unsigned short, nFuncs );
00861     memset( uCanons, 0, sizeof(unsigned short) * nFuncs );
00862     pCounters = ALLOC( char, nFuncs );
00863     memset( pCounters, 0, sizeof(char) * nFuncs );
00864     uPhases = (char **)Extra_ArrayAlloc( nFuncs, nPhasesMax, sizeof(char) );
00865     nClasses = 0;
00866     for ( uTruth = 0; uTruth < (unsigned)nFuncs; uTruth++ )
00867     {
00868         // skip already assigned
00869         if ( uCanons[uTruth] )
00870         {
00871             assert( uTruth > uCanons[uTruth] );
00872             continue;
00873         }
00874         nClasses++;
00875         for ( i = 0; i < 16; i++ )
00876         {
00877             uPhase = Extra_TruthPolarize( uTruth, i, 4 );
00878             if ( uCanons[uPhase] == 0 && (uTruth || i==0) )
00879             {
00880                 uCanons[uPhase]    = uTruth;
00881                 uPhases[uPhase][0] = i;
00882                 pCounters[uPhase]  = 1;
00883             }
00884             else
00885             {
00886                 assert( uCanons[uPhase] == uTruth );
00887                 if ( pCounters[uPhase] < nPhasesMax )
00888                     uPhases[uPhase][ pCounters[uPhase]++ ] = i;
00889             }
00890         }
00891     }
00892     if ( puCanons ) 
00893         *puCanons = uCanons;
00894     else
00895         free( uCanons );
00896     if ( puPhases ) 
00897         *puPhases = uPhases;
00898     else
00899         free( uPhases );
00900     if ( ppCounters ) 
00901         *ppCounters = pCounters;
00902     else
00903         free( pCounters );
00904 //    printf( "The number of 4N-classes = %d.\n", nClasses );
00905 }

void Extra_Truth4VarNPN ( unsigned short **  puCanons,
char **  puPhases,
char **  puPerms,
unsigned char **  puMap 
)

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

Synopsis [Computes NPN canonical forms for 4-variable functions.]

Description []

SideEffects []

SeeAlso []

Definition at line 680 of file extraUtilMisc.c.

00681 {
00682     unsigned short * uCanons;
00683     unsigned char * uMap;
00684     unsigned uTruth, uPhase, uPerm;
00685     char ** pPerms4, * uPhases, * uPerms;
00686     int nFuncs, nClasses;
00687     int i, k;
00688 
00689     nFuncs  = (1 << 16);
00690     uCanons = ALLOC( unsigned short, nFuncs );
00691     uPhases = ALLOC( char, nFuncs );
00692     uPerms  = ALLOC( char, nFuncs );
00693     uMap    = ALLOC( unsigned char, nFuncs );
00694     memset( uCanons, 0, sizeof(unsigned short) * nFuncs );
00695     memset( uPhases, 0, sizeof(char) * nFuncs );
00696     memset( uPerms,  0, sizeof(char) * nFuncs );
00697     memset( uMap,    0, sizeof(unsigned char) * nFuncs );
00698     pPerms4 = Extra_Permutations( 4 );
00699 
00700     nClasses = 1;
00701     nFuncs = (1 << 15);
00702     for ( uTruth = 1; uTruth < (unsigned)nFuncs; uTruth++ )
00703     {
00704         // skip already assigned
00705         if ( uCanons[uTruth] )
00706         {
00707             assert( uTruth > uCanons[uTruth] );
00708             uMap[~uTruth & 0xFFFF] = uMap[uTruth] = uMap[uCanons[uTruth]];
00709             continue;
00710         }
00711         uMap[uTruth] = nClasses++;
00712         for ( i = 0; i < 16; i++ )
00713         {
00714             uPhase = Extra_TruthPolarize( uTruth, i, 4 );
00715             for ( k = 0; k < 24; k++ )
00716             {
00717                 uPerm = Extra_TruthPermute( uPhase, pPerms4[k], 4, 0 );
00718                 if ( uCanons[uPerm] == 0 )
00719                 {
00720                     uCanons[uPerm] = uTruth;
00721                     uPhases[uPerm] = i;
00722                     uPerms[uPerm]  = k;
00723 
00724                     uPerm = ~uPerm & 0xFFFF;
00725                     uCanons[uPerm] = uTruth;
00726                     uPhases[uPerm] = i | 16;
00727                     uPerms[uPerm]  = k;
00728                 }
00729                 else
00730                     assert( uCanons[uPerm] == uTruth );
00731             }
00732             uPhase = Extra_TruthPolarize( ~uTruth & 0xFFFF, i, 4 ); 
00733             for ( k = 0; k < 24; k++ )
00734             {
00735                 uPerm = Extra_TruthPermute( uPhase, pPerms4[k], 4, 0 );
00736                 if ( uCanons[uPerm] == 0 )
00737                 {
00738                     uCanons[uPerm] = uTruth;
00739                     uPhases[uPerm] = i;
00740                     uPerms[uPerm]  = k;
00741 
00742                     uPerm = ~uPerm & 0xFFFF;
00743                     uCanons[uPerm] = uTruth;
00744                     uPhases[uPerm] = i | 16;
00745                     uPerms[uPerm]  = k;
00746                 }
00747                 else
00748                     assert( uCanons[uPerm] == uTruth );
00749             }
00750         }
00751     }
00752     uPhases[(1<<16)-1] = 16;
00753     assert( nClasses == 222 );
00754     free( pPerms4 );
00755     if ( puCanons ) 
00756         *puCanons = uCanons;
00757     else
00758         free( uCanons );
00759     if ( puPhases ) 
00760         *puPhases = uPhases;
00761     else
00762         free( uPhases );
00763     if ( puPerms ) 
00764         *puPerms = uPerms;
00765     else
00766         free( uPerms );
00767     if ( puMap ) 
00768         *puMap = uMap;
00769     else
00770         free( uMap );
00771 }

static void Extra_TruthAnd ( unsigned *  pOut,
unsigned *  pIn0,
unsigned *  pIn1,
int  nVars 
) [inline, static]

Definition at line 511 of file extra.h.

00512 {
00513     int w;
00514     for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
00515         pOut[w] = pIn0[w] & pIn1[w];
00516 }

static void Extra_TruthAndPhase ( unsigned *  pOut,
unsigned *  pIn0,
unsigned *  pIn1,
int  nVars,
int  fCompl0,
int  fCompl1 
) [inline, static]

Definition at line 535 of file extra.h.

00536 {
00537     int w;
00538     if ( fCompl0 && fCompl1 )
00539     {
00540         for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
00541             pOut[w] = ~(pIn0[w] | pIn1[w]);
00542     }
00543     else if ( fCompl0 && !fCompl1 )
00544     {
00545         for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
00546             pOut[w] = ~pIn0[w] & pIn1[w];
00547     }
00548     else if ( !fCompl0 && fCompl1 )
00549     {
00550         for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
00551             pOut[w] = pIn0[w] & ~pIn1[w];
00552     }
00553     else // if ( !fCompl0 && !fCompl1 )
00554     {
00555         for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
00556             pOut[w] = pIn0[w] & pIn1[w];
00557     }
00558 }

int Extra_TruthCanonFastN ( int  nVarsMax,
int  nVarsReal,
unsigned *  pt,
unsigned **  pptRes,
char **  ppfRes 
)

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

Synopsis [Computes the N-canonical form of the Boolean function up to 6 inputs.]

Description [The N-canonical form is defined as the truth table with the minimum integer value. This function exhaustively enumerates through the complete set of 2^N phase assignments. Returns pointers to the static storage to the truth table and phases. This data should be used before the function is called again.]

SideEffects []

SeeAlso []

Definition at line 76 of file extraUtilCanon.c.

00077 {
00078     static unsigned uTruthStore6[2];
00079     int RetValue;
00080     assert( nVarsMax <= 6 );
00081     assert( nVarsReal <= nVarsMax );
00082     RetValue = Extra_TruthCanonN_rec( nVarsReal <= 3? 3: nVarsReal, (unsigned char *)pt, pptRes, ppfRes, 0 );
00083     if ( nVarsMax == 6 && nVarsReal < nVarsMax )
00084     {
00085         uTruthStore6[0] = **pptRes;
00086         uTruthStore6[1] = **pptRes;
00087         *pptRes = uTruthStore6;
00088     }
00089     return RetValue;
00090 }

unsigned Extra_TruthCanonN ( unsigned  uTruth,
int  nVars 
)

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

Synopsis [Computes N-canonical form using brute-force methods.]

Description []

SideEffects []

SeeAlso []

Definition at line 477 of file extraUtilMisc.c.

00478 {
00479     unsigned uTruthMin, uPhase;
00480     int nMints, i;
00481     nMints    = (1 << nVars);
00482     uTruthMin = 0xFFFFFFFF;
00483     for ( i = 0; i < nMints; i++ )
00484     {
00485         uPhase = Extra_TruthPolarize( uTruth, i, nVars ); 
00486         if ( uTruthMin > uPhase )
00487             uTruthMin = uPhase;
00488     }
00489     return uTruthMin;
00490 }

unsigned Extra_TruthCanonNN ( unsigned  uTruth,
int  nVars 
)

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

Synopsis [Computes NN-canonical form using brute-force methods.]

Description []

SideEffects []

SeeAlso []

Definition at line 503 of file extraUtilMisc.c.

00504 {
00505     unsigned uTruthMin, uTruthC, uPhase;
00506     int nMints, i;
00507     nMints    = (1 << nVars);
00508     uTruthC   = (unsigned)( (~uTruth) & ((~((unsigned)0)) >> (32-nMints)) );
00509     uTruthMin = 0xFFFFFFFF;
00510     for ( i = 0; i < nMints; i++ )
00511     {
00512         uPhase = Extra_TruthPolarize( uTruth, i, nVars ); 
00513         if ( uTruthMin > uPhase )
00514             uTruthMin = uPhase;
00515         uPhase = Extra_TruthPolarize( uTruthC, i, nVars ); 
00516         if ( uTruthMin > uPhase )
00517             uTruthMin = uPhase;
00518     }
00519     return uTruthMin;
00520 }

unsigned Extra_TruthCanonNP ( unsigned  uTruth,
int  nVars 
)

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

Synopsis [Computes NP-canonical form using brute-force methods.]

Description []

SideEffects []

SeeAlso []

Definition at line 576 of file extraUtilMisc.c.

00577 {
00578     static int nVarsOld, nPerms;
00579     static char ** pPerms = NULL;
00580 
00581     unsigned uTruthMin, uPhase, uPerm;
00582     int nMints, k, i;
00583 
00584     if ( pPerms == NULL )
00585     {
00586         nPerms = Extra_Factorial( nVars );   
00587         pPerms = Extra_Permutations( nVars );
00588         nVarsOld = nVars;
00589     }
00590     else if ( nVarsOld != nVars )
00591     {
00592         free( pPerms );
00593         nPerms = Extra_Factorial( nVars );   
00594         pPerms = Extra_Permutations( nVars );
00595         nVarsOld = nVars;
00596     }
00597 
00598     nMints    = (1 << nVars);
00599     uTruthMin = 0xFFFFFFFF;
00600     for ( i = 0; i < nMints; i++ )
00601     {
00602         uPhase = Extra_TruthPolarize( uTruth, i, nVars ); 
00603         for ( k = 0; k < nPerms; k++ )
00604         {
00605             uPerm = Extra_TruthPermute( uPhase, pPerms[k], nVars, 0 );
00606             if ( uTruthMin > uPerm )
00607                 uTruthMin = uPerm;
00608         }
00609     }
00610     return uTruthMin;
00611 }

unsigned Extra_TruthCanonNPN ( unsigned  uTruth,
int  nVars 
)

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

Synopsis [Computes NPN-canonical form using brute-force methods.]

Description []

SideEffects []

SeeAlso []

Definition at line 624 of file extraUtilMisc.c.

00625 {
00626     static int nVarsOld, nPerms;
00627     static char ** pPerms = NULL;
00628 
00629     unsigned uTruthMin, uTruthC, uPhase, uPerm;
00630     int nMints, k, i;
00631 
00632     if ( pPerms == NULL )
00633     {
00634         nPerms = Extra_Factorial( nVars );   
00635         pPerms = Extra_Permutations( nVars );
00636         nVarsOld = nVars;
00637     }
00638     else if ( nVarsOld != nVars )
00639     {
00640         free( pPerms );
00641         nPerms = Extra_Factorial( nVars );   
00642         pPerms = Extra_Permutations( nVars );
00643         nVarsOld = nVars;
00644     }
00645 
00646     nMints    = (1 << nVars);
00647     uTruthC   = (unsigned)( (~uTruth) & ((~((unsigned)0)) >> (32-nMints)) );
00648     uTruthMin = 0xFFFFFFFF;
00649     for ( i = 0; i < nMints; i++ )
00650     {
00651         uPhase = Extra_TruthPolarize( uTruth, i, nVars ); 
00652         for ( k = 0; k < nPerms; k++ )
00653         {
00654             uPerm = Extra_TruthPermute( uPhase, pPerms[k], nVars, 0 );
00655             if ( uTruthMin > uPerm )
00656                 uTruthMin = uPerm;
00657         }
00658         uPhase = Extra_TruthPolarize( uTruthC, i, nVars ); 
00659         for ( k = 0; k < nPerms; k++ )
00660         {
00661             uPerm = Extra_TruthPermute( uPhase, pPerms[k], nVars, 0 );
00662             if ( uTruthMin > uPerm )
00663                 uTruthMin = uPerm;
00664         }
00665     }
00666     return uTruthMin;
00667 }

unsigned Extra_TruthCanonP ( unsigned  uTruth,
int  nVars 
)

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

Synopsis [Computes P-canonical form using brute-force methods.]

Description []

SideEffects []

SeeAlso []

Definition at line 533 of file extraUtilMisc.c.

00534 {
00535     static int nVarsOld, nPerms;
00536     static char ** pPerms = NULL;
00537 
00538     unsigned uTruthMin, uPerm;
00539     int k;
00540 
00541     if ( pPerms == NULL )
00542     {
00543         nPerms = Extra_Factorial( nVars );   
00544         pPerms = Extra_Permutations( nVars );
00545         nVarsOld = nVars;
00546     }
00547     else if ( nVarsOld != nVars )
00548     {
00549         free( pPerms );
00550         nPerms = Extra_Factorial( nVars );   
00551         pPerms = Extra_Permutations( nVars );
00552         nVarsOld = nVars;
00553     }
00554 
00555     uTruthMin = 0xFFFFFFFF;
00556     for ( k = 0; k < nPerms; k++ )
00557     {
00558         uPerm = Extra_TruthPermute( uTruth, pPerms[k], nVars, 0 );
00559         if ( uTruthMin > uPerm )
00560             uTruthMin = uPerm;
00561     }
00562     return uTruthMin;
00563 }

void Extra_TruthChangePhase ( unsigned *  pTruth,
int  nVars,
int  iVar 
)

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

Synopsis [Changes phase of the function w.r.t. one variable.]

Description []

SideEffects []

SeeAlso []

Definition at line 716 of file extraUtilTruth.c.

00717 {
00718     int nWords = Extra_TruthWordNum( nVars );
00719     int i, k, Step;
00720     unsigned Temp;
00721 
00722     assert( iVar < nVars );
00723     switch ( iVar )
00724     {
00725     case 0:
00726         for ( i = 0; i < nWords; i++ )
00727             pTruth[i] = ((pTruth[i] & 0x55555555) << 1) | ((pTruth[i] & 0xAAAAAAAA) >> 1);
00728         return;
00729     case 1:
00730         for ( i = 0; i < nWords; i++ )
00731             pTruth[i] = ((pTruth[i] & 0x33333333) << 2) | ((pTruth[i] & 0xCCCCCCCC) >> 2);
00732         return;
00733     case 2:
00734         for ( i = 0; i < nWords; i++ )
00735             pTruth[i] = ((pTruth[i] & 0x0F0F0F0F) << 4) | ((pTruth[i] & 0xF0F0F0F0) >> 4);
00736         return;
00737     case 3:
00738         for ( i = 0; i < nWords; i++ )
00739             pTruth[i] = ((pTruth[i] & 0x00FF00FF) << 8) | ((pTruth[i] & 0xFF00FF00) >> 8);
00740         return;
00741     case 4:
00742         for ( i = 0; i < nWords; i++ )
00743             pTruth[i] = ((pTruth[i] & 0x0000FFFF) << 16) | ((pTruth[i] & 0xFFFF0000) >> 16);
00744         return;
00745     default:
00746         Step = (1 << (iVar - 5));
00747         for ( k = 0; k < nWords; k += 2*Step )
00748         {
00749             for ( i = 0; i < Step; i++ )
00750             {
00751                 Temp = pTruth[i];
00752                 pTruth[i] = pTruth[Step+i];
00753                 pTruth[Step+i] = Temp;
00754             }
00755             pTruth += 2*Step;
00756         }
00757         return;
00758     }
00759 }

static void Extra_TruthClear ( unsigned *  pOut,
int  nVars 
) [inline, static]

Definition at line 493 of file extra.h.

00494 {
00495     int w;
00496     for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
00497         pOut[w] = 0;
00498 }

void Extra_TruthCofactor0 ( unsigned *  pTruth,
int  nVars,
int  iVar 
)

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

Synopsis [Computes negative cofactor of the function.]

Description []

SideEffects []

SeeAlso []

Definition at line 447 of file extraUtilTruth.c.

00448 {
00449     int nWords = Extra_TruthWordNum( nVars );
00450     int i, k, Step;
00451 
00452     assert( iVar < nVars );
00453     switch ( iVar )
00454     {
00455     case 0:
00456         for ( i = 0; i < nWords; i++ )
00457             pTruth[i] = (pTruth[i] & 0x55555555) | ((pTruth[i] & 0x55555555) << 1);
00458         return;
00459     case 1:
00460         for ( i = 0; i < nWords; i++ )
00461             pTruth[i] = (pTruth[i] & 0x33333333) | ((pTruth[i] & 0x33333333) << 2);
00462         return;
00463     case 2:
00464         for ( i = 0; i < nWords; i++ )
00465             pTruth[i] = (pTruth[i] & 0x0F0F0F0F) | ((pTruth[i] & 0x0F0F0F0F) << 4);
00466         return;
00467     case 3:
00468         for ( i = 0; i < nWords; i++ )
00469             pTruth[i] = (pTruth[i] & 0x00FF00FF) | ((pTruth[i] & 0x00FF00FF) << 8);
00470         return;
00471     case 4:
00472         for ( i = 0; i < nWords; i++ )
00473             pTruth[i] = (pTruth[i] & 0x0000FFFF) | ((pTruth[i] & 0x0000FFFF) << 16);
00474         return;
00475     default:
00476         Step = (1 << (iVar - 5));
00477         for ( k = 0; k < nWords; k += 2*Step )
00478         {
00479             for ( i = 0; i < Step; i++ )
00480                 pTruth[Step+i] = pTruth[i];
00481             pTruth += 2*Step;
00482         }
00483         return;
00484     }
00485 }

void Extra_TruthCofactor1 ( unsigned *  pTruth,
int  nVars,
int  iVar 
)

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

Synopsis [Computes positive cofactor of the function.]

Description []

SideEffects []

SeeAlso []

Definition at line 396 of file extraUtilTruth.c.

00397 {
00398     int nWords = Extra_TruthWordNum( nVars );
00399     int i, k, Step;
00400 
00401     assert( iVar < nVars );
00402     switch ( iVar )
00403     {
00404     case 0:
00405         for ( i = 0; i < nWords; i++ )
00406             pTruth[i] = (pTruth[i] & 0xAAAAAAAA) | ((pTruth[i] & 0xAAAAAAAA) >> 1);
00407         return;
00408     case 1:
00409         for ( i = 0; i < nWords; i++ )
00410             pTruth[i] = (pTruth[i] & 0xCCCCCCCC) | ((pTruth[i] & 0xCCCCCCCC) >> 2);
00411         return;
00412     case 2:
00413         for ( i = 0; i < nWords; i++ )
00414             pTruth[i] = (pTruth[i] & 0xF0F0F0F0) | ((pTruth[i] & 0xF0F0F0F0) >> 4);
00415         return;
00416     case 3:
00417         for ( i = 0; i < nWords; i++ )
00418             pTruth[i] = (pTruth[i] & 0xFF00FF00) | ((pTruth[i] & 0xFF00FF00) >> 8);
00419         return;
00420     case 4:
00421         for ( i = 0; i < nWords; i++ )
00422             pTruth[i] = (pTruth[i] & 0xFFFF0000) | ((pTruth[i] & 0xFFFF0000) >> 16);
00423         return;
00424     default:
00425         Step = (1 << (iVar - 5));
00426         for ( k = 0; k < nWords; k += 2*Step )
00427         {
00428             for ( i = 0; i < Step; i++ )
00429                 pTruth[i] = pTruth[Step+i];
00430             pTruth += 2*Step;
00431         }
00432         return;
00433     }
00434 }

static void Extra_TruthCopy ( unsigned *  pOut,
unsigned *  pIn,
int  nVars 
) [inline, static]

Definition at line 487 of file extra.h.

00488 {
00489     int w;
00490     for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
00491         pOut[w] = pIn[w];
00492 }

static int Extra_TruthCountOnes ( unsigned *  pIn,
int  nVars 
) [inline, static]

Definition at line 448 of file extra.h.

00449 {
00450     int w, Counter = 0;
00451     for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
00452         Counter += Extra_WordCountOnes(pIn[w]);
00453     return Counter;
00454 }

void Extra_TruthCountOnesInCofs ( unsigned *  pTruth,
int  nVars,
short *  pStore 
)

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

Synopsis [Counts the number of 1's in each cofactor.]

Description [The resulting numbers are stored in the array of shorts, whose length is 2*nVars. The number of 1's is counted in a different space than the original function. For example, if the function depends on k variables, the cofactors are assumed to depend on k-1 variables.]

SideEffects []

SeeAlso []

Definition at line 825 of file extraUtilTruth.c.

00826 {
00827     int nWords = Extra_TruthWordNum( nVars );
00828     int i, k, Counter;
00829     memset( pStore, 0, sizeof(short) * 2 * nVars );
00830     if ( nVars <= 5 )
00831     {
00832         if ( nVars > 0 )
00833         {
00834             pStore[2*0+0] = Extra_WordCountOnes( pTruth[0] & 0x55555555 );
00835             pStore[2*0+1] = Extra_WordCountOnes( pTruth[0] & 0xAAAAAAAA );
00836         }
00837         if ( nVars > 1 )
00838         {
00839             pStore[2*1+0] = Extra_WordCountOnes( pTruth[0] & 0x33333333 );
00840             pStore[2*1+1] = Extra_WordCountOnes( pTruth[0] & 0xCCCCCCCC );
00841         }
00842         if ( nVars > 2 )
00843         {
00844             pStore[2*2+0] = Extra_WordCountOnes( pTruth[0] & 0x0F0F0F0F );
00845             pStore[2*2+1] = Extra_WordCountOnes( pTruth[0] & 0xF0F0F0F0 );
00846         }
00847         if ( nVars > 3 )
00848         {
00849             pStore[2*3+0] = Extra_WordCountOnes( pTruth[0] & 0x00FF00FF );
00850             pStore[2*3+1] = Extra_WordCountOnes( pTruth[0] & 0xFF00FF00 );
00851         }
00852         if ( nVars > 4 )
00853         {
00854             pStore[2*4+0] = Extra_WordCountOnes( pTruth[0] & 0x0000FFFF );
00855             pStore[2*4+1] = Extra_WordCountOnes( pTruth[0] & 0xFFFF0000 );
00856         }
00857         return;
00858     }
00859     // nVars >= 6
00860     // count 1's for all other variables
00861     for ( k = 0; k < nWords; k++ )
00862     {
00863         Counter = Extra_WordCountOnes( pTruth[k] );
00864         for ( i = 5; i < nVars; i++ )
00865             if ( k & (1 << (i-5)) )
00866                 pStore[2*i+1] += Counter;
00867             else
00868                 pStore[2*i+0] += Counter;
00869     }
00870     // count 1's for the first five variables
00871     for ( k = 0; k < nWords/2; k++ )
00872     {
00873         pStore[2*0+0] += Extra_WordCountOnes( (pTruth[0] & 0x55555555) | ((pTruth[1] & 0x55555555) <<  1) );
00874         pStore[2*0+1] += Extra_WordCountOnes( (pTruth[0] & 0xAAAAAAAA) | ((pTruth[1] & 0xAAAAAAAA) >>  1) );
00875         pStore[2*1+0] += Extra_WordCountOnes( (pTruth[0] & 0x33333333) | ((pTruth[1] & 0x33333333) <<  2) );
00876         pStore[2*1+1] += Extra_WordCountOnes( (pTruth[0] & 0xCCCCCCCC) | ((pTruth[1] & 0xCCCCCCCC) >>  2) );
00877         pStore[2*2+0] += Extra_WordCountOnes( (pTruth[0] & 0x0F0F0F0F) | ((pTruth[1] & 0x0F0F0F0F) <<  4) );
00878         pStore[2*2+1] += Extra_WordCountOnes( (pTruth[0] & 0xF0F0F0F0) | ((pTruth[1] & 0xF0F0F0F0) >>  4) );
00879         pStore[2*3+0] += Extra_WordCountOnes( (pTruth[0] & 0x00FF00FF) | ((pTruth[1] & 0x00FF00FF) <<  8) );
00880         pStore[2*3+1] += Extra_WordCountOnes( (pTruth[0] & 0xFF00FF00) | ((pTruth[1] & 0xFF00FF00) >>  8) );
00881         pStore[2*4+0] += Extra_WordCountOnes( (pTruth[0] & 0x0000FFFF) | ((pTruth[1] & 0x0000FFFF) << 16) );
00882         pStore[2*4+1] += Extra_WordCountOnes( (pTruth[0] & 0xFFFF0000) | ((pTruth[1] & 0xFFFF0000) >> 16) );
00883         pTruth += 2;
00884     }
00885 }

unsigned** Extra_TruthElementary ( int  nVars  ) 

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

Synopsis [Derive elementary truth tables.]

Description []

SideEffects []

SeeAlso []

Definition at line 74 of file extraUtilTruth.c.

00075 {
00076     unsigned ** pRes;
00077     int i, k, nWords;
00078     nWords = Extra_TruthWordNum(nVars);
00079     pRes = (unsigned **)Extra_ArrayAlloc( nVars, nWords, 4 );
00080     for ( i = 0; i < nVars; i++ )
00081     {
00082         if ( i < 5 )
00083         {
00084             for ( k = 0; k < nWords; k++ )
00085                 pRes[i][k] = s_VarMasks[i][1];
00086         }
00087         else
00088         {
00089             for ( k = 0; k < nWords; k++ )
00090                 if ( k & (1 << (i-5)) )
00091                     pRes[i][k] = ~(unsigned)0;
00092                 else
00093                     pRes[i][k] = 0;
00094         }
00095     }
00096     return pRes;
00097 }

void Extra_TruthExist ( unsigned *  pTruth,
int  nVars,
int  iVar 
)

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

Synopsis [Existentially quantifies the variable.]

Description []

SideEffects []

SeeAlso []

Definition at line 499 of file extraUtilTruth.c.

00500 {
00501     int nWords = Extra_TruthWordNum( nVars );
00502     int i, k, Step;
00503 
00504     assert( iVar < nVars );
00505     switch ( iVar )
00506     {
00507     case 0:
00508         for ( i = 0; i < nWords; i++ )
00509             pTruth[i] |=  ((pTruth[i] & 0xAAAAAAAA) >> 1) | ((pTruth[i] & 0x55555555) << 1);
00510         return;
00511     case 1:
00512         for ( i = 0; i < nWords; i++ )
00513             pTruth[i] |=  ((pTruth[i] & 0xCCCCCCCC) >> 2) | ((pTruth[i] & 0x33333333) << 2);
00514         return;
00515     case 2:
00516         for ( i = 0; i < nWords; i++ )
00517             pTruth[i] |=  ((pTruth[i] & 0xF0F0F0F0) >> 4) | ((pTruth[i] & 0x0F0F0F0F) << 4);
00518         return;
00519     case 3:
00520         for ( i = 0; i < nWords; i++ )
00521             pTruth[i] |=  ((pTruth[i] & 0xFF00FF00) >> 8) | ((pTruth[i] & 0x00FF00FF) << 8);
00522         return;
00523     case 4:
00524         for ( i = 0; i < nWords; i++ )
00525             pTruth[i] |=  ((pTruth[i] & 0xFFFF0000) >> 16) | ((pTruth[i] & 0x0000FFFF) << 16);
00526         return;
00527     default:
00528         Step = (1 << (iVar - 5));
00529         for ( k = 0; k < nWords; k += 2*Step )
00530         {
00531             for ( i = 0; i < Step; i++ )
00532             {
00533                 pTruth[i]     |= pTruth[Step+i];
00534                 pTruth[Step+i] = pTruth[i];
00535             }
00536             pTruth += 2*Step;
00537         }
00538         return;
00539     }
00540 }

void Extra_TruthExpand ( int  nVars,
int  nWords,
unsigned *  puTruth,
unsigned  uPhase,
unsigned *  puTruthR 
)

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

Synopsis [Computes a phase of the 8-var function.]

Description []

SideEffects []

SeeAlso []

Definition at line 1317 of file extraUtilMisc.c.

01318 {
01319     // elementary truth tables
01320     static unsigned uTruths[8][8] = {
01321         { 0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA },
01322         { 0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC },
01323         { 0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0 },
01324         { 0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00 },
01325         { 0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000 }, 
01326         { 0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF }, 
01327         { 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF }, 
01328         { 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF } 
01329     };
01330     static char Cases[256] = {
01331          0, // 00000000
01332          0, // 00000001
01333          1, // 00000010
01334          0, // 00000011
01335          2, // 00000100
01336         -1, // 00000101
01337         -1, // 00000110
01338          0, // 00000111
01339          3, // 00001000
01340         -1, // 00001001
01341         -1, // 00001010
01342         -1, // 00001011
01343         -1, // 00001100
01344         -1, // 00001101
01345         -1, // 00001110
01346          0, // 00001111
01347          4, // 00010000
01348         -1, // 00010001
01349         -1, // 00010010
01350         -1, // 00010011
01351         -1, // 00010100
01352         -1, // 00010101
01353         -1, // 00010110
01354         -1, // 00010111
01355         -1, // 00011000
01356         -1, // 00011001
01357         -1, // 00011010
01358         -1, // 00011011
01359         -1, // 00011100
01360         -1, // 00011101
01361         -1, // 00011110
01362          0, // 00011111
01363          5, // 00100000
01364         -1, // 00100001
01365         -1, // 00100010
01366         -1, // 00100011
01367         -1, // 00100100
01368         -1, // 00100101
01369         -1, // 00100110
01370         -1, // 00100111
01371         -1, // 00101000
01372         -1, // 00101001
01373         -1, // 00101010
01374         -1, // 00101011
01375         -1, // 00101100
01376         -1, // 00101101
01377         -1, // 00101110
01378         -1, // 00101111
01379         -1, // 00110000
01380         -1, // 00110001
01381         -1, // 00110010
01382         -1, // 00110011
01383         -1, // 00110100
01384         -1, // 00110101
01385         -1, // 00110110
01386         -1, // 00110111
01387         -1, // 00111000
01388         -1, // 00111001
01389         -1, // 00111010
01390         -1, // 00111011
01391         -1, // 00111100
01392         -1, // 00111101
01393         -1, // 00111110
01394          0, // 00111111
01395          6, // 01000000
01396         -1, // 01000001
01397         -1, // 01000010
01398         -1, // 01000011
01399         -1, // 01000100
01400         -1, // 01000101
01401         -1, // 01000110
01402         -1, // 01000111
01403         -1, // 01001000
01404         -1, // 01001001
01405         -1, // 01001010
01406         -1, // 01001011
01407         -1, // 01001100
01408         -1, // 01001101
01409         -1, // 01001110
01410         -1, // 01001111
01411         -1, // 01010000
01412         -1, // 01010001
01413         -1, // 01010010
01414         -1, // 01010011
01415         -1, // 01010100
01416         -1, // 01010101
01417         -1, // 01010110
01418         -1, // 01010111
01419         -1, // 01011000
01420         -1, // 01011001
01421         -1, // 01011010
01422         -1, // 01011011
01423         -1, // 01011100
01424         -1, // 01011101
01425         -1, // 01011110
01426         -1, // 01011111
01427         -1, // 01100000
01428         -1, // 01100001
01429         -1, // 01100010
01430         -1, // 01100011
01431         -1, // 01100100
01432         -1, // 01100101
01433         -1, // 01100110
01434         -1, // 01100111
01435         -1, // 01101000
01436         -1, // 01101001
01437         -1, // 01101010
01438         -1, // 01101011
01439         -1, // 01101100
01440         -1, // 01101101
01441         -1, // 01101110
01442         -1, // 01101111
01443         -1, // 01110000
01444         -1, // 01110001
01445         -1, // 01110010
01446         -1, // 01110011
01447         -1, // 01110100
01448         -1, // 01110101
01449         -1, // 01110110
01450         -1, // 01110111
01451         -1, // 01111000
01452         -1, // 01111001
01453         -1, // 01111010
01454         -1, // 01111011
01455         -1, // 01111100
01456         -1, // 01111101
01457         -1, // 01111110
01458          0, // 01111111
01459          7, // 10000000
01460         -1, // 10000001
01461         -1, // 10000010
01462         -1, // 10000011
01463         -1, // 10000100
01464         -1, // 10000101
01465         -1, // 10000110
01466         -1, // 10000111
01467         -1, // 10001000
01468         -1, // 10001001
01469         -1, // 10001010
01470         -1, // 10001011
01471         -1, // 10001100
01472         -1, // 10001101
01473         -1, // 10001110
01474         -1, // 10001111
01475         -1, // 10010000
01476         -1, // 10010001
01477         -1, // 10010010
01478         -1, // 10010011
01479         -1, // 10010100
01480         -1, // 10010101
01481         -1, // 10010110
01482         -1, // 10010111
01483         -1, // 10011000
01484         -1, // 10011001
01485         -1, // 10011010
01486         -1, // 10011011
01487         -1, // 10011100
01488         -1, // 10011101
01489         -1, // 10011110
01490         -1, // 10011111
01491         -1, // 10100000
01492         -1, // 10100001
01493         -1, // 10100010
01494         -1, // 10100011
01495         -1, // 10100100
01496         -1, // 10100101
01497         -1, // 10100110
01498         -1, // 10100111
01499         -1, // 10101000
01500         -1, // 10101001
01501         -1, // 10101010
01502         -1, // 10101011
01503         -1, // 10101100
01504         -1, // 10101101
01505         -1, // 10101110
01506         -1, // 10101111
01507         -1, // 10110000
01508         -1, // 10110001
01509         -1, // 10110010
01510         -1, // 10110011
01511         -1, // 10110100
01512         -1, // 10110101
01513         -1, // 10110110
01514         -1, // 10110111
01515         -1, // 10111000
01516         -1, // 10111001
01517         -1, // 10111010
01518         -1, // 10111011
01519         -1, // 10111100
01520         -1, // 10111101
01521         -1, // 10111110
01522         -1, // 10111111
01523         -1, // 11000000
01524         -1, // 11000001
01525         -1, // 11000010
01526         -1, // 11000011
01527         -1, // 11000100
01528         -1, // 11000101
01529         -1, // 11000110
01530         -1, // 11000111
01531         -1, // 11001000
01532         -1, // 11001001
01533         -1, // 11001010
01534         -1, // 11001011
01535         -1, // 11001100
01536         -1, // 11001101
01537         -1, // 11001110
01538         -1, // 11001111
01539         -1, // 11010000
01540         -1, // 11010001
01541         -1, // 11010010
01542         -1, // 11010011
01543         -1, // 11010100
01544         -1, // 11010101
01545         -1, // 11010110
01546         -1, // 11010111
01547         -1, // 11011000
01548         -1, // 11011001
01549         -1, // 11011010
01550         -1, // 11011011
01551         -1, // 11011100
01552         -1, // 11011101
01553         -1, // 11011110
01554         -1, // 11011111
01555         -1, // 11100000
01556         -1, // 11100001
01557         -1, // 11100010
01558         -1, // 11100011
01559         -1, // 11100100
01560         -1, // 11100101
01561         -1, // 11100110
01562         -1, // 11100111
01563         -1, // 11101000
01564         -1, // 11101001
01565         -1, // 11101010
01566         -1, // 11101011
01567         -1, // 11101100
01568         -1, // 11101101
01569         -1, // 11101110
01570         -1, // 11101111
01571         -1, // 11110000
01572         -1, // 11110001
01573         -1, // 11110010
01574         -1, // 11110011
01575         -1, // 11110100
01576         -1, // 11110101
01577         -1, // 11110110
01578         -1, // 11110111
01579         -1, // 11111000
01580         -1, // 11111001
01581         -1, // 11111010
01582         -1, // 11111011
01583         -1, // 11111100
01584         -1, // 11111101
01585         -1, // 11111110
01586          0  // 11111111
01587     };
01588     static char Perms[256][8] = {
01589         { 0, 1, 2, 3, 4, 5, 6, 7 }, // 00000000
01590         { 0, 1, 2, 3, 4, 5, 6, 7 }, // 00000001
01591         { 1, 0, 2, 3, 4, 5, 6, 7 }, // 00000010
01592         { 0, 1, 2, 3, 4, 5, 6, 7 }, // 00000011
01593         { 1, 2, 0, 3, 4, 5, 6, 7 }, // 00000100
01594         { 0, 2, 1, 3, 4, 5, 6, 7 }, // 00000101
01595         { 2, 0, 1, 3, 4, 5, 6, 7 }, // 00000110
01596         { 0, 1, 2, 3, 4, 5, 6, 7 }, // 00000111
01597         { 1, 2, 3, 0, 4, 5, 6, 7 }, // 00001000
01598         { 0, 2, 3, 1, 4, 5, 6, 7 }, // 00001001
01599         { 2, 0, 3, 1, 4, 5, 6, 7 }, // 00001010
01600         { 0, 1, 3, 2, 4, 5, 6, 7 }, // 00001011
01601         { 2, 3, 0, 1, 4, 5, 6, 7 }, // 00001100
01602         { 0, 3, 1, 2, 4, 5, 6, 7 }, // 00001101
01603         { 3, 0, 1, 2, 4, 5, 6, 7 }, // 00001110
01604         { 0, 1, 2, 3, 4, 5, 6, 7 }, // 00001111
01605         { 1, 2, 3, 4, 0, 5, 6, 7 }, // 00010000
01606         { 0, 2, 3, 4, 1, 5, 6, 7 }, // 00010001
01607         { 2, 0, 3, 4, 1, 5, 6, 7 }, // 00010010
01608         { 0, 1, 3, 4, 2, 5, 6, 7 }, // 00010011
01609         { 2, 3, 0, 4, 1, 5, 6, 7 }, // 00010100
01610         { 0, 3, 1, 4, 2, 5, 6, 7 }, // 00010101
01611         { 3, 0, 1, 4, 2, 5, 6, 7 }, // 00010110
01612         { 0, 1, 2, 4, 3, 5, 6, 7 }, // 00010111
01613         { 2, 3, 4, 0, 1, 5, 6, 7 }, // 00011000
01614         { 0, 3, 4, 1, 2, 5, 6, 7 }, // 00011001
01615         { 3, 0, 4, 1, 2, 5, 6, 7 }, // 00011010
01616         { 0, 1, 4, 2, 3, 5, 6, 7 }, // 00011011
01617         { 3, 4, 0, 1, 2, 5, 6, 7 }, // 00011100
01618         { 0, 4, 1, 2, 3, 5, 6, 7 }, // 00011101
01619         { 4, 0, 1, 2, 3, 5, 6, 7 }, // 00011110
01620         { 0, 1, 2, 3, 4, 5, 6, 7 }, // 00011111
01621         { 1, 2, 3, 4, 5, 0, 6, 7 }, // 00100000
01622         { 0, 2, 3, 4, 5, 1, 6, 7 }, // 00100001
01623         { 2, 0, 3, 4, 5, 1, 6, 7 }, // 00100010
01624         { 0, 1, 3, 4, 5, 2, 6, 7 }, // 00100011
01625         { 2, 3, 0, 4, 5, 1, 6, 7 }, // 00100100
01626         { 0, 3, 1, 4, 5, 2, 6, 7 }, // 00100101
01627         { 3, 0, 1, 4, 5, 2, 6, 7 }, // 00100110
01628         { 0, 1, 2, 4, 5, 3, 6, 7 }, // 00100111
01629         { 2, 3, 4, 0, 5, 1, 6, 7 }, // 00101000
01630         { 0, 3, 4, 1, 5, 2, 6, 7 }, // 00101001
01631         { 3, 0, 4, 1, 5, 2, 6, 7 }, // 00101010
01632         { 0, 1, 4, 2, 5, 3, 6, 7 }, // 00101011
01633         { 3, 4, 0, 1, 5, 2, 6, 7 }, // 00101100
01634         { 0, 4, 1, 2, 5, 3, 6, 7 }, // 00101101
01635         { 4, 0, 1, 2, 5, 3, 6, 7 }, // 00101110
01636         { 0, 1, 2, 3, 5, 4, 6, 7 }, // 00101111
01637         { 2, 3, 4, 5, 0, 1, 6, 7 }, // 00110000
01638         { 0, 3, 4, 5, 1, 2, 6, 7 }, // 00110001
01639         { 3, 0, 4, 5, 1, 2, 6, 7 }, // 00110010
01640         { 0, 1, 4, 5, 2, 3, 6, 7 }, // 00110011
01641         { 3, 4, 0, 5, 1, 2, 6, 7 }, // 00110100
01642         { 0, 4, 1, 5, 2, 3, 6, 7 }, // 00110101
01643         { 4, 0, 1, 5, 2, 3, 6, 7 }, // 00110110
01644         { 0, 1, 2, 5, 3, 4, 6, 7 }, // 00110111
01645         { 3, 4, 5, 0, 1, 2, 6, 7 }, // 00111000
01646         { 0, 4, 5, 1, 2, 3, 6, 7 }, // 00111001
01647         { 4, 0, 5, 1, 2, 3, 6, 7 }, // 00111010
01648         { 0, 1, 5, 2, 3, 4, 6, 7 }, // 00111011
01649         { 4, 5, 0, 1, 2, 3, 6, 7 }, // 00111100
01650         { 0, 5, 1, 2, 3, 4, 6, 7 }, // 00111101
01651         { 5, 0, 1, 2, 3, 4, 6, 7 }, // 00111110
01652         { 0, 1, 2, 3, 4, 5, 6, 7 }, // 00111111
01653         { 1, 2, 3, 4, 5, 6, 0, 7 }, // 01000000
01654         { 0, 2, 3, 4, 5, 6, 1, 7 }, // 01000001
01655         { 2, 0, 3, 4, 5, 6, 1, 7 }, // 01000010
01656         { 0, 1, 3, 4, 5, 6, 2, 7 }, // 01000011
01657         { 2, 3, 0, 4, 5, 6, 1, 7 }, // 01000100
01658         { 0, 3, 1, 4, 5, 6, 2, 7 }, // 01000101
01659         { 3, 0, 1, 4, 5, 6, 2, 7 }, // 01000110
01660         { 0, 1, 2, 4, 5, 6, 3, 7 }, // 01000111
01661         { 2, 3, 4, 0, 5, 6, 1, 7 }, // 01001000
01662         { 0, 3, 4, 1, 5, 6, 2, 7 }, // 01001001
01663         { 3, 0, 4, 1, 5, 6, 2, 7 }, // 01001010
01664         { 0, 1, 4, 2, 5, 6, 3, 7 }, // 01001011
01665         { 3, 4, 0, 1, 5, 6, 2, 7 }, // 01001100
01666         { 0, 4, 1, 2, 5, 6, 3, 7 }, // 01001101
01667         { 4, 0, 1, 2, 5, 6, 3, 7 }, // 01001110
01668         { 0, 1, 2, 3, 5, 6, 4, 7 }, // 01001111
01669         { 2, 3, 4, 5, 0, 6, 1, 7 }, // 01010000
01670         { 0, 3, 4, 5, 1, 6, 2, 7 }, // 01010001
01671         { 3, 0, 4, 5, 1, 6, 2, 7 }, // 01010010
01672         { 0, 1, 4, 5, 2, 6, 3, 7 }, // 01010011
01673         { 3, 4, 0, 5, 1, 6, 2, 7 }, // 01010100
01674         { 0, 4, 1, 5, 2, 6, 3, 7 }, // 01010101
01675         { 4, 0, 1, 5, 2, 6, 3, 7 }, // 01010110
01676         { 0, 1, 2, 5, 3, 6, 4, 7 }, // 01010111
01677         { 3, 4, 5, 0, 1, 6, 2, 7 }, // 01011000
01678         { 0, 4, 5, 1, 2, 6, 3, 7 }, // 01011001
01679         { 4, 0, 5, 1, 2, 6, 3, 7 }, // 01011010
01680         { 0, 1, 5, 2, 3, 6, 4, 7 }, // 01011011
01681         { 4, 5, 0, 1, 2, 6, 3, 7 }, // 01011100
01682         { 0, 5, 1, 2, 3, 6, 4, 7 }, // 01011101
01683         { 5, 0, 1, 2, 3, 6, 4, 7 }, // 01011110
01684         { 0, 1, 2, 3, 4, 6, 5, 7 }, // 01011111
01685         { 2, 3, 4, 5, 6, 0, 1, 7 }, // 01100000
01686         { 0, 3, 4, 5, 6, 1, 2, 7 }, // 01100001
01687         { 3, 0, 4, 5, 6, 1, 2, 7 }, // 01100010
01688         { 0, 1, 4, 5, 6, 2, 3, 7 }, // 01100011
01689         { 3, 4, 0, 5, 6, 1, 2, 7 }, // 01100100
01690         { 0, 4, 1, 5, 6, 2, 3, 7 }, // 01100101
01691         { 4, 0, 1, 5, 6, 2, 3, 7 }, // 01100110
01692         { 0, 1, 2, 5, 6, 3, 4, 7 }, // 01100111
01693         { 3, 4, 5, 0, 6, 1, 2, 7 }, // 01101000
01694         { 0, 4, 5, 1, 6, 2, 3, 7 }, // 01101001
01695         { 4, 0, 5, 1, 6, 2, 3, 7 }, // 01101010
01696         { 0, 1, 5, 2, 6, 3, 4, 7 }, // 01101011
01697         { 4, 5, 0, 1, 6, 2, 3, 7 }, // 01101100
01698         { 0, 5, 1, 2, 6, 3, 4, 7 }, // 01101101
01699         { 5, 0, 1, 2, 6, 3, 4, 7 }, // 01101110
01700         { 0, 1, 2, 3, 6, 4, 5, 7 }, // 01101111
01701         { 3, 4, 5, 6, 0, 1, 2, 7 }, // 01110000
01702         { 0, 4, 5, 6, 1, 2, 3, 7 }, // 01110001
01703         { 4, 0, 5, 6, 1, 2, 3, 7 }, // 01110010
01704         { 0, 1, 5, 6, 2, 3, 4, 7 }, // 01110011
01705         { 4, 5, 0, 6, 1, 2, 3, 7 }, // 01110100
01706         { 0, 5, 1, 6, 2, 3, 4, 7 }, // 01110101
01707         { 5, 0, 1, 6, 2, 3, 4, 7 }, // 01110110
01708         { 0, 1, 2, 6, 3, 4, 5, 7 }, // 01110111
01709         { 4, 5, 6, 0, 1, 2, 3, 7 }, // 01111000
01710         { 0, 5, 6, 1, 2, 3, 4, 7 }, // 01111001
01711         { 5, 0, 6, 1, 2, 3, 4, 7 }, // 01111010
01712         { 0, 1, 6, 2, 3, 4, 5, 7 }, // 01111011
01713         { 5, 6, 0, 1, 2, 3, 4, 7 }, // 01111100
01714         { 0, 6, 1, 2, 3, 4, 5, 7 }, // 01111101
01715         { 6, 0, 1, 2, 3, 4, 5, 7 }, // 01111110
01716         { 0, 1, 2, 3, 4, 5, 6, 7 }, // 01111111
01717         { 1, 2, 3, 4, 5, 6, 7, 0 }, // 10000000
01718         { 0, 2, 3, 4, 5, 6, 7, 1 }, // 10000001
01719         { 2, 0, 3, 4, 5, 6, 7, 1 }, // 10000010
01720         { 0, 1, 3, 4, 5, 6, 7, 2 }, // 10000011
01721         { 2, 3, 0, 4, 5, 6, 7, 1 }, // 10000100
01722         { 0, 3, 1, 4, 5, 6, 7, 2 }, // 10000101
01723         { 3, 0, 1, 4, 5, 6, 7, 2 }, // 10000110
01724         { 0, 1, 2, 4, 5, 6, 7, 3 }, // 10000111
01725         { 2, 3, 4, 0, 5, 6, 7, 1 }, // 10001000
01726         { 0, 3, 4, 1, 5, 6, 7, 2 }, // 10001001
01727         { 3, 0, 4, 1, 5, 6, 7, 2 }, // 10001010
01728         { 0, 1, 4, 2, 5, 6, 7, 3 }, // 10001011
01729         { 3, 4, 0, 1, 5, 6, 7, 2 }, // 10001100
01730         { 0, 4, 1, 2, 5, 6, 7, 3 }, // 10001101
01731         { 4, 0, 1, 2, 5, 6, 7, 3 }, // 10001110
01732         { 0, 1, 2, 3, 5, 6, 7, 4 }, // 10001111
01733         { 2, 3, 4, 5, 0, 6, 7, 1 }, // 10010000
01734         { 0, 3, 4, 5, 1, 6, 7, 2 }, // 10010001
01735         { 3, 0, 4, 5, 1, 6, 7, 2 }, // 10010010
01736         { 0, 1, 4, 5, 2, 6, 7, 3 }, // 10010011
01737         { 3, 4, 0, 5, 1, 6, 7, 2 }, // 10010100
01738         { 0, 4, 1, 5, 2, 6, 7, 3 }, // 10010101
01739         { 4, 0, 1, 5, 2, 6, 7, 3 }, // 10010110
01740         { 0, 1, 2, 5, 3, 6, 7, 4 }, // 10010111
01741         { 3, 4, 5, 0, 1, 6, 7, 2 }, // 10011000
01742         { 0, 4, 5, 1, 2, 6, 7, 3 }, // 10011001
01743         { 4, 0, 5, 1, 2, 6, 7, 3 }, // 10011010
01744         { 0, 1, 5, 2, 3, 6, 7, 4 }, // 10011011
01745         { 4, 5, 0, 1, 2, 6, 7, 3 }, // 10011100
01746         { 0, 5, 1, 2, 3, 6, 7, 4 }, // 10011101
01747         { 5, 0, 1, 2, 3, 6, 7, 4 }, // 10011110
01748         { 0, 1, 2, 3, 4, 6, 7, 5 }, // 10011111
01749         { 2, 3, 4, 5, 6, 0, 7, 1 }, // 10100000
01750         { 0, 3, 4, 5, 6, 1, 7, 2 }, // 10100001
01751         { 3, 0, 4, 5, 6, 1, 7, 2 }, // 10100010
01752         { 0, 1, 4, 5, 6, 2, 7, 3 }, // 10100011
01753         { 3, 4, 0, 5, 6, 1, 7, 2 }, // 10100100
01754         { 0, 4, 1, 5, 6, 2, 7, 3 }, // 10100101
01755         { 4, 0, 1, 5, 6, 2, 7, 3 }, // 10100110
01756         { 0, 1, 2, 5, 6, 3, 7, 4 }, // 10100111
01757         { 3, 4, 5, 0, 6, 1, 7, 2 }, // 10101000
01758         { 0, 4, 5, 1, 6, 2, 7, 3 }, // 10101001
01759         { 4, 0, 5, 1, 6, 2, 7, 3 }, // 10101010
01760         { 0, 1, 5, 2, 6, 3, 7, 4 }, // 10101011
01761         { 4, 5, 0, 1, 6, 2, 7, 3 }, // 10101100
01762         { 0, 5, 1, 2, 6, 3, 7, 4 }, // 10101101
01763         { 5, 0, 1, 2, 6, 3, 7, 4 }, // 10101110
01764         { 0, 1, 2, 3, 6, 4, 7, 5 }, // 10101111
01765         { 3, 4, 5, 6, 0, 1, 7, 2 }, // 10110000
01766         { 0, 4, 5, 6, 1, 2, 7, 3 }, // 10110001
01767         { 4, 0, 5, 6, 1, 2, 7, 3 }, // 10110010
01768         { 0, 1, 5, 6, 2, 3, 7, 4 }, // 10110011
01769         { 4, 5, 0, 6, 1, 2, 7, 3 }, // 10110100
01770         { 0, 5, 1, 6, 2, 3, 7, 4 }, // 10110101
01771         { 5, 0, 1, 6, 2, 3, 7, 4 }, // 10110110
01772         { 0, 1, 2, 6, 3, 4, 7, 5 }, // 10110111
01773         { 4, 5, 6, 0, 1, 2, 7, 3 }, // 10111000
01774         { 0, 5, 6, 1, 2, 3, 7, 4 }, // 10111001
01775         { 5, 0, 6, 1, 2, 3, 7, 4 }, // 10111010
01776         { 0, 1, 6, 2, 3, 4, 7, 5 }, // 10111011
01777         { 5, 6, 0, 1, 2, 3, 7, 4 }, // 10111100
01778         { 0, 6, 1, 2, 3, 4, 7, 5 }, // 10111101
01779         { 6, 0, 1, 2, 3, 4, 7, 5 }, // 10111110
01780         { 0, 1, 2, 3, 4, 5, 7, 6 }, // 10111111
01781         { 2, 3, 4, 5, 6, 7, 0, 1 }, // 11000000
01782         { 0, 3, 4, 5, 6, 7, 1, 2 }, // 11000001
01783         { 3, 0, 4, 5, 6, 7, 1, 2 }, // 11000010
01784         { 0, 1, 4, 5, 6, 7, 2, 3 }, // 11000011
01785         { 3, 4, 0, 5, 6, 7, 1, 2 }, // 11000100
01786         { 0, 4, 1, 5, 6, 7, 2, 3 }, // 11000101
01787         { 4, 0, 1, 5, 6, 7, 2, 3 }, // 11000110
01788         { 0, 1, 2, 5, 6, 7, 3, 4 }, // 11000111
01789         { 3, 4, 5, 0, 6, 7, 1, 2 }, // 11001000
01790         { 0, 4, 5, 1, 6, 7, 2, 3 }, // 11001001
01791         { 4, 0, 5, 1, 6, 7, 2, 3 }, // 11001010
01792         { 0, 1, 5, 2, 6, 7, 3, 4 }, // 11001011
01793         { 4, 5, 0, 1, 6, 7, 2, 3 }, // 11001100
01794         { 0, 5, 1, 2, 6, 7, 3, 4 }, // 11001101
01795         { 5, 0, 1, 2, 6, 7, 3, 4 }, // 11001110
01796         { 0, 1, 2, 3, 6, 7, 4, 5 }, // 11001111
01797         { 3, 4, 5, 6, 0, 7, 1, 2 }, // 11010000
01798         { 0, 4, 5, 6, 1, 7, 2, 3 }, // 11010001
01799         { 4, 0, 5, 6, 1, 7, 2, 3 }, // 11010010
01800         { 0, 1, 5, 6, 2, 7, 3, 4 }, // 11010011
01801         { 4, 5, 0, 6, 1, 7, 2, 3 }, // 11010100
01802         { 0, 5, 1, 6, 2, 7, 3, 4 }, // 11010101
01803         { 5, 0, 1, 6, 2, 7, 3, 4 }, // 11010110
01804         { 0, 1, 2, 6, 3, 7, 4, 5 }, // 11010111
01805         { 4, 5, 6, 0, 1, 7, 2, 3 }, // 11011000
01806         { 0, 5, 6, 1, 2, 7, 3, 4 }, // 11011001
01807         { 5, 0, 6, 1, 2, 7, 3, 4 }, // 11011010
01808         { 0, 1, 6, 2, 3, 7, 4, 5 }, // 11011011
01809         { 5, 6, 0, 1, 2, 7, 3, 4 }, // 11011100
01810         { 0, 6, 1, 2, 3, 7, 4, 5 }, // 11011101
01811         { 6, 0, 1, 2, 3, 7, 4, 5 }, // 11011110
01812         { 0, 1, 2, 3, 4, 7, 5, 6 }, // 11011111
01813         { 3, 4, 5, 6, 7, 0, 1, 2 }, // 11100000
01814         { 0, 4, 5, 6, 7, 1, 2, 3 }, // 11100001
01815         { 4, 0, 5, 6, 7, 1, 2, 3 }, // 11100010
01816         { 0, 1, 5, 6, 7, 2, 3, 4 }, // 11100011
01817         { 4, 5, 0, 6, 7, 1, 2, 3 }, // 11100100
01818         { 0, 5, 1, 6, 7, 2, 3, 4 }, // 11100101
01819         { 5, 0, 1, 6, 7, 2, 3, 4 }, // 11100110
01820         { 0, 1, 2, 6, 7, 3, 4, 5 }, // 11100111
01821         { 4, 5, 6, 0, 7, 1, 2, 3 }, // 11101000
01822         { 0, 5, 6, 1, 7, 2, 3, 4 }, // 11101001
01823         { 5, 0, 6, 1, 7, 2, 3, 4 }, // 11101010
01824         { 0, 1, 6, 2, 7, 3, 4, 5 }, // 11101011
01825         { 5, 6, 0, 1, 7, 2, 3, 4 }, // 11101100
01826         { 0, 6, 1, 2, 7, 3, 4, 5 }, // 11101101
01827         { 6, 0, 1, 2, 7, 3, 4, 5 }, // 11101110
01828         { 0, 1, 2, 3, 7, 4, 5, 6 }, // 11101111
01829         { 4, 5, 6, 7, 0, 1, 2, 3 }, // 11110000
01830         { 0, 5, 6, 7, 1, 2, 3, 4 }, // 11110001
01831         { 5, 0, 6, 7, 1, 2, 3, 4 }, // 11110010
01832         { 0, 1, 6, 7, 2, 3, 4, 5 }, // 11110011
01833         { 5, 6, 0, 7, 1, 2, 3, 4 }, // 11110100
01834         { 0, 6, 1, 7, 2, 3, 4, 5 }, // 11110101
01835         { 6, 0, 1, 7, 2, 3, 4, 5 }, // 11110110
01836         { 0, 1, 2, 7, 3, 4, 5, 6 }, // 11110111
01837         { 5, 6, 7, 0, 1, 2, 3, 4 }, // 11111000
01838         { 0, 6, 7, 1, 2, 3, 4, 5 }, // 11111001
01839         { 6, 0, 7, 1, 2, 3, 4, 5 }, // 11111010
01840         { 0, 1, 7, 2, 3, 4, 5, 6 }, // 11111011
01841         { 6, 7, 0, 1, 2, 3, 4, 5 }, // 11111100
01842         { 0, 7, 1, 2, 3, 4, 5, 6 }, // 11111101
01843         { 7, 0, 1, 2, 3, 4, 5, 6 }, // 11111110
01844         { 0, 1, 2, 3, 4, 5, 6, 7 }  // 11111111
01845     };
01846 
01847     assert( uPhase > 0 && uPhase < (unsigned)(1 << nVars) );
01848 
01849     // the same function
01850     if ( Cases[uPhase] == 0 )
01851     {
01852         int i;
01853         for ( i = 0; i < nWords; i++ )
01854             puTruthR[i] = puTruth[i];
01855         return;
01856     }
01857 
01858     // an elementary variable
01859     if ( Cases[uPhase] > 0 )
01860     {
01861         int i;
01862         for ( i = 0; i < nWords; i++ )
01863             puTruthR[i] = uTruths[Cases[uPhase]][i];
01864         return;
01865     }
01866 
01867     // truth table takes one word
01868     if ( nWords == 1 )
01869     {
01870         int i, k, nMints, iRes;
01871         char * pPerm = Perms[uPhase];
01872         puTruthR[0] = 0;
01873         nMints = (1 << nVars);
01874         for ( i = 0; i < nMints; i++ )
01875             if ( puTruth[0] & (1 << i) )
01876             {
01877                 for ( iRes = 0, k = 0; k < nVars; k++ )
01878                     if ( i & (1 << pPerm[k]) )
01879                         iRes |= (1 << k);
01880                 puTruthR[0] |= (1 << iRes);
01881             }
01882         return;
01883     }
01884     else if ( nWords == 2 )
01885     {
01886         int i, k, iRes;
01887         char * pPerm = Perms[uPhase];
01888         puTruthR[0] = puTruthR[1] = 0;
01889         for ( i = 0; i < 32; i++ )
01890         {
01891             if ( puTruth[0] & (1 << i) )
01892             {
01893                 for ( iRes = 0, k = 0; k < 6; k++ )
01894                     if ( i & (1 << pPerm[k]) )
01895                         iRes |= (1 << k);
01896                 if ( iRes < 32 )
01897                     puTruthR[0] |= (1 << iRes);
01898                 else
01899                     puTruthR[1] |= (1 << (iRes-32));
01900             }
01901         }
01902         for ( ; i < 64; i++ )
01903         {
01904             if ( puTruth[1] & (1 << (i-32)) )
01905             {
01906                 for ( iRes = 0, k = 0; k < 6; k++ )
01907                     if ( i & (1 << pPerm[k]) )
01908                         iRes |= (1 << k);
01909                 if ( iRes < 32 )
01910                     puTruthR[0] |= (1 << iRes);
01911                 else
01912                     puTruthR[1] |= (1 << (iRes-32));
01913             }
01914         }
01915     }
01916     // truth table takes more than one word
01917     else
01918     {
01919         int i, k, nMints, iRes;
01920         char * pPerm = Perms[uPhase];
01921         for ( i = 0; i < nWords; i++ )
01922             puTruthR[i] = 0;
01923         nMints = (1 << nVars);
01924         for ( i = 0; i < nMints; i++ )
01925             if ( puTruth[i>>5] & (1 << (i&31)) )
01926             {
01927                 for ( iRes = 0, k = 0; k < 5; k++ )
01928                     if ( i & (1 << pPerm[k]) )
01929                         iRes |= (1 << k);
01930                 puTruthR[iRes>>5] |= (1 << (iRes&31));
01931             }
01932     }
01933 }

static void Extra_TruthFill ( unsigned *  pOut,
int  nVars 
) [inline, static]

Definition at line 499 of file extra.h.

00500 {
00501     int w;
00502     for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
00503         pOut[w] = ~(unsigned)0;
00504 }

void Extra_TruthForall ( unsigned *  pTruth,
int  nVars,
int  iVar 
)

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

Synopsis [Existentially quantifies the variable.]

Description []

SideEffects []

SeeAlso []

Definition at line 553 of file extraUtilTruth.c.

00554 {
00555     int nWords = Extra_TruthWordNum( nVars );
00556     int i, k, Step;
00557 
00558     assert( iVar < nVars );
00559     switch ( iVar )
00560     {
00561     case 0:
00562         for ( i = 0; i < nWords; i++ )
00563             pTruth[i] &=  ((pTruth[i] & 0xAAAAAAAA) >> 1) | ((pTruth[i] & 0x55555555) << 1);
00564         return;
00565     case 1:
00566         for ( i = 0; i < nWords; i++ )
00567             pTruth[i] &=  ((pTruth[i] & 0xCCCCCCCC) >> 2) | ((pTruth[i] & 0x33333333) << 2);
00568         return;
00569     case 2:
00570         for ( i = 0; i < nWords; i++ )
00571             pTruth[i] &=  ((pTruth[i] & 0xF0F0F0F0) >> 4) | ((pTruth[i] & 0x0F0F0F0F) << 4);
00572         return;
00573     case 3:
00574         for ( i = 0; i < nWords; i++ )
00575             pTruth[i] &=  ((pTruth[i] & 0xFF00FF00) >> 8) | ((pTruth[i] & 0x00FF00FF) << 8);
00576         return;
00577     case 4:
00578         for ( i = 0; i < nWords; i++ )
00579             pTruth[i] &=  ((pTruth[i] & 0xFFFF0000) >> 16) | ((pTruth[i] & 0x0000FFFF) << 16);
00580         return;
00581     default:
00582         Step = (1 << (iVar - 5));
00583         for ( k = 0; k < nWords; k += 2*Step )
00584         {
00585             for ( i = 0; i < Step; i++ )
00586             {
00587                 pTruth[i]     &= pTruth[Step+i];
00588                 pTruth[Step+i] = pTruth[i];
00589             }
00590             pTruth += 2*Step;
00591         }
00592         return;
00593     }
00594 }

static int Extra_TruthHasBit ( unsigned *  p,
int  Bit 
) [inline, static]

Definition at line 438 of file extra.h.

00438 { return (p[Bit>>5] & (1<<(Bit & 31))) > 0;   }

unsigned Extra_TruthHash ( unsigned *  pIn,
int  nWords 
)

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

Synopsis [Canonicize the truth table.]

Description []

SideEffects []

SeeAlso []

Definition at line 899 of file extraUtilTruth.c.

00900 {
00901     // The 1,024 smallest prime numbers used to compute the hash value
00902     // http://www.math.utah.edu/~alfeld/math/primelist.html
00903     static int HashPrimes[1024] = { 2, 3, 5, 
00904     7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 
00905     101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 
00906     193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 
00907     293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 
00908     409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 
00909     521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 
00910     641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 
00911     757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 
00912     881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 
00913     1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 
00914     1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 
00915     1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 
00916     1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 
00917     1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 
00918     1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 
00919     1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 
00920     1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 
00921     1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 
00922     1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 
00923     2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 
00924     2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 
00925     2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 
00926     2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 
00927     2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 
00928     2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 
00929     2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 
00930     2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 
00931     2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023, 
00932     3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 
00933     3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 
00934     3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, 3371, 3373, 
00935     3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 
00936     3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 
00937     3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 
00938     3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833, 
00939     3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 3931, 
00940     3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 
00941     4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 
00942     4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 
00943     4289, 4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 
00944     4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 
00945     4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657, 
00946     4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759, 4783, 4787, 4789, 
00947     4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 
00948     4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 
00949     5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 
00950     5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 
00951     5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 
00952     5417, 5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 
00953     5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 
00954     5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 
00955     5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 
00956     5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, 
00957     6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 
00958     6131, 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 
00959     6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 
00960     6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 
00961     6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607, 
00962     6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 
00963     6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, 6857, 
00964     6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 
00965     6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 
00966     7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 
00967     7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 
00968     7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, 
00969     7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 
00970     7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 
00971     7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873, 
00972     7877, 7879, 7883, 7901, 7907, 7919, 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 
00973     8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123, 
00974     8147, 8161 };
00975     int i;
00976     unsigned uHashKey;
00977     assert( nWords <= 1024 );
00978     uHashKey = 0;
00979     for ( i = 0; i < nWords; i++ )
00980         uHashKey ^= HashPrimes[i] * pIn[i];
00981     return uHashKey;
00982 }

static int Extra_TruthIsConst0 ( unsigned *  pIn,
int  nVars 
) [inline, static]

Definition at line 463 of file extra.h.

00464 {
00465     int w;
00466     for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
00467         if ( pIn[w] )
00468             return 0;
00469     return 1;
00470 }

static int Extra_TruthIsConst1 ( unsigned *  pIn,
int  nVars 
) [inline, static]

Definition at line 471 of file extra.h.

00472 {
00473     int w;
00474     for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
00475         if ( pIn[w] != ~(unsigned)0 )
00476             return 0;
00477     return 1;
00478 }

static int Extra_TruthIsEqual ( unsigned *  pIn0,
unsigned *  pIn1,
int  nVars 
) [inline, static]

Definition at line 455 of file extra.h.

00456 {
00457     int w;
00458     for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
00459         if ( pIn0[w] != pIn1[w] )
00460             return 0;
00461     return 1;
00462 }

static int Extra_TruthIsImply ( unsigned *  pIn1,
unsigned *  pIn2,
int  nVars 
) [inline, static]

Definition at line 479 of file extra.h.

00480 {
00481     int w;
00482     for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
00483         if ( pIn1[w] & ~pIn2[w] )
00484             return 0;
00485     return 1;
00486 }

int Extra_TruthMinCofSuppOverlap ( unsigned *  pTruth,
int  nVars,
int *  pVarMin 
)

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

Synopsis [Computes minimum overlap in supports of cofactors.]

Description []

SideEffects []

SeeAlso []

Definition at line 772 of file extraUtilTruth.c.

00773 {
00774     static unsigned uCofactor[16];
00775     int i, ValueCur, ValueMin, VarMin;
00776     unsigned uSupp0, uSupp1;
00777     int nVars0, nVars1;
00778     assert( nVars <= 9 );
00779     ValueMin = 32;
00780     VarMin   = -1;
00781     for ( i = 0; i < nVars; i++ )
00782     {
00783         // get negative cofactor
00784         Extra_TruthCopy( uCofactor, pTruth, nVars );
00785         Extra_TruthCofactor0( uCofactor, nVars, i );
00786         uSupp0 = Extra_TruthSupport( uCofactor, nVars );
00787         nVars0 = Extra_WordCountOnes( uSupp0 );
00788 //Extra_PrintBinary( stdout, &uSupp0, 8 ); printf( "\n" );
00789         // get positive cofactor
00790         Extra_TruthCopy( uCofactor, pTruth, nVars );
00791         Extra_TruthCofactor1( uCofactor, nVars, i );
00792         uSupp1 = Extra_TruthSupport( uCofactor, nVars );
00793         nVars1 = Extra_WordCountOnes( uSupp1 );
00794 //Extra_PrintBinary( stdout, &uSupp1, 8 ); printf( "\n" );
00795         // get the number of common vars
00796         ValueCur = Extra_WordCountOnes( uSupp0 & uSupp1 );
00797         if ( ValueMin > ValueCur && nVars0 <= 5 && nVars1 <= 5 )
00798         {
00799             ValueMin = ValueCur;
00800             VarMin = i;
00801         }
00802         if ( ValueMin == 0 )
00803             break;
00804     }
00805     if ( pVarMin )
00806         *pVarMin = VarMin;
00807     return ValueMin;
00808 }

void Extra_TruthMux ( unsigned *  pOut,
unsigned *  pCof0,
unsigned *  pCof1,
int  nVars,
int  iVar 
)

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

Synopsis [Computes negative cofactor of the function.]

Description []

SideEffects []

SeeAlso []

Definition at line 608 of file extraUtilTruth.c.

00609 {
00610     int nWords = Extra_TruthWordNum( nVars );
00611     int i, k, Step;
00612 
00613     assert( iVar < nVars );
00614     switch ( iVar )
00615     {
00616     case 0:
00617         for ( i = 0; i < nWords; i++ )
00618             pOut[i] = (pCof0[i] & 0x55555555) | (pCof1[i] & 0xAAAAAAAA);
00619         return;
00620     case 1:
00621         for ( i = 0; i < nWords; i++ )
00622             pOut[i] = (pCof0[i] & 0x33333333) | (pCof1[i] & 0xCCCCCCCC);
00623         return;
00624     case 2:
00625         for ( i = 0; i < nWords; i++ )
00626             pOut[i] = (pCof0[i] & 0x0F0F0F0F) | (pCof1[i] & 0xF0F0F0F0);
00627         return;
00628     case 3:
00629         for ( i = 0; i < nWords; i++ )
00630             pOut[i] = (pCof0[i] & 0x00FF00FF) | (pCof1[i] & 0xFF00FF00);
00631         return;
00632     case 4:
00633         for ( i = 0; i < nWords; i++ )
00634             pOut[i] = (pCof0[i] & 0x0000FFFF) | (pCof1[i] & 0xFFFF0000);
00635         return;
00636     default:
00637         Step = (1 << (iVar - 5));
00638         for ( k = 0; k < nWords; k += 2*Step )
00639         {
00640             for ( i = 0; i < Step; i++ )
00641             {
00642                 pOut[i]      = pCof0[i];
00643                 pOut[Step+i] = pCof1[Step+i];
00644             }
00645             pOut += 2*Step;
00646         }
00647         return;
00648     }
00649 }

static void Extra_TruthNand ( unsigned *  pOut,
unsigned *  pIn0,
unsigned *  pIn1,
int  nVars 
) [inline, static]

Definition at line 529 of file extra.h.

00530 {
00531     int w;
00532     for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
00533         pOut[w] = ~(pIn0[w] & pIn1[w]);
00534 }

static void Extra_TruthNot ( unsigned *  pOut,
unsigned *  pIn,
int  nVars 
) [inline, static]

Definition at line 505 of file extra.h.

00506 {
00507     int w;
00508     for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
00509         pOut[w] = ~pIn[w];
00510 }

static void Extra_TruthOr ( unsigned *  pOut,
unsigned *  pIn0,
unsigned *  pIn1,
int  nVars 
) [inline, static]

Definition at line 517 of file extra.h.

00518 {
00519     int w;
00520     for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
00521         pOut[w] = pIn0[w] | pIn1[w];
00522 }

unsigned short** Extra_TruthPerm43 (  ) 

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

Synopsis [Allocated lookup table for truth table permutation.]

Description []

SideEffects []

SeeAlso []

Definition at line 1946 of file extraUtilMisc.c.

01947 {
01948     unsigned short ** pTable;
01949     unsigned uTruth;
01950     int i, k;
01951     pTable = (unsigned short **)Extra_ArrayAlloc( 256, 16, 2 );
01952     for ( i = 0; i < 256; i++ )
01953     {
01954         uTruth = (i << 8) | i;
01955         for ( k = 0; k < 16; k++ )
01956             pTable[i][k] = Extra_TruthPerm4One( uTruth, k );
01957     }
01958     return pTable;
01959 }

unsigned short Extra_TruthPerm4One ( unsigned  uTruth,
int  Phase 
)

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

Synopsis [Computes a phase of the 3-var function.]

Description []

SideEffects []

SeeAlso []

Definition at line 943 of file extraUtilMisc.c.

00944 {
00945     // cases
00946     static unsigned short Cases[16] = {
00947         0,      // 0000  - skip
00948         0,      // 0001  - skip
00949         0xCCCC, // 0010  - single var
00950         0,      // 0011  - skip
00951         0xF0F0, // 0100  - single var
00952         1,      // 0101
00953         1,      // 0110
00954         0,      // 0111  - skip
00955         0xFF00, // 1000  - single var
00956         1,      // 1001
00957         1,      // 1010
00958         1,      // 1011
00959         1,      // 1100
00960         1,      // 1101
00961         1,      // 1110
00962         0       // 1111  - skip
00963     };
00964     // permutations
00965     static int Perms[16][4] = {
00966         { 0, 0, 0, 0 }, // 0000  - skip
00967         { 0, 0, 0, 0 }, // 0001  - skip
00968         { 0, 0, 0, 0 }, // 0010  - single var
00969         { 0, 0, 0, 0 }, // 0011  - skip
00970         { 0, 0, 0, 0 }, // 0100  - single var
00971         { 0, 2, 1, 3 }, // 0101
00972         { 2, 0, 1, 3 }, // 0110
00973         { 0, 0, 0, 0 }, // 0111  - skip
00974         { 0, 0, 0, 0 }, // 1000  - single var
00975         { 0, 2, 3, 1 }, // 1001
00976         { 2, 0, 3, 1 }, // 1010
00977         { 0, 1, 3, 2 }, // 1011
00978         { 2, 3, 0, 1 }, // 1100
00979         { 0, 3, 1, 2 }, // 1101
00980         { 3, 0, 1, 2 }, // 1110
00981         { 0, 0, 0, 0 }  // 1111  - skip
00982     };
00983     int i, k, iRes;
00984     unsigned uTruthRes;
00985     assert( Phase >= 0 && Phase < 16 );
00986     if ( Cases[Phase] == 0 )
00987         return uTruth;
00988     if ( Cases[Phase] > 1 )
00989         return Cases[Phase];
00990     uTruthRes = 0;
00991     for ( i = 0; i < 16; i++ )
00992         if ( uTruth & (1 << i) )
00993         {
00994             for ( iRes = 0, k = 0; k < 4; k++ )
00995                 if ( i & (1 << Perms[Phase][k]) )
00996                     iRes |= (1 << k);
00997             uTruthRes |= (1 << iRes);
00998         }
00999     return uTruthRes;
01000 }

unsigned** Extra_TruthPerm53 (  ) 

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

Synopsis [Allocated lookup table for truth table permutation.]

Description []

SideEffects []

SeeAlso []

Definition at line 1972 of file extraUtilMisc.c.

01973 {
01974     unsigned ** pTable;
01975     unsigned uTruth;
01976     int i, k;
01977     pTable = (unsigned **)Extra_ArrayAlloc( 256, 32, 4 );
01978     for ( i = 0; i < 256; i++ )
01979     {
01980         uTruth = (i << 24) | (i << 16) | (i << 8) | i;
01981         for ( k = 0; k < 32; k++ )
01982             pTable[i][k] = Extra_TruthPerm5One( uTruth, k );
01983     }
01984     return pTable;
01985 }

unsigned** Extra_TruthPerm54 (  ) 

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

Synopsis [Allocated lookup table for truth table permutation.]

Description []

SideEffects []

SeeAlso []

Definition at line 1998 of file extraUtilMisc.c.

01999 {
02000     unsigned ** pTable;
02001     unsigned uTruth;
02002     int i;
02003     pTable = (unsigned **)Extra_ArrayAlloc( 256*256, 4, 4 );
02004     for ( i = 0; i < 256*256; i++ )
02005     {
02006         uTruth = (i << 16) | i;
02007         pTable[i][0] = Extra_TruthPerm5One( uTruth, 31-8 );
02008         pTable[i][1] = Extra_TruthPerm5One( uTruth, 31-4 );
02009         pTable[i][2] = Extra_TruthPerm5One( uTruth, 31-2 );
02010         pTable[i][3] = Extra_TruthPerm5One( uTruth, 31-1 );
02011     }
02012     return pTable;
02013 }

unsigned Extra_TruthPerm5One ( unsigned  uTruth,
int  Phase 
)

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

Synopsis [Computes a phase of the 3-var function.]

Description []

SideEffects []

SeeAlso []

Definition at line 1013 of file extraUtilMisc.c.

01014 {
01015     // cases
01016     static unsigned Cases[32] = {
01017         0,          // 00000  - skip
01018         0,          // 00001  - skip
01019         0xCCCCCCCC, // 00010  - single var
01020         0,          // 00011  - skip
01021         0xF0F0F0F0, // 00100  - single var
01022         1,          // 00101
01023         1,          // 00110
01024         0,          // 00111  - skip
01025         0xFF00FF00, // 01000  - single var
01026         1,          // 01001
01027         1,          // 01010
01028         1,          // 01011
01029         1,          // 01100
01030         1,          // 01101
01031         1,          // 01110
01032         0,          // 01111  - skip
01033         0xFFFF0000, // 10000  - skip
01034         1,          // 10001
01035         1,          // 10010
01036         1,          // 10011
01037         1,          // 10100
01038         1,          // 10101
01039         1,          // 10110
01040         1,          // 10111  - four var
01041         1,          // 11000
01042         1,          // 11001
01043         1,          // 11010
01044         1,          // 11011  - four var
01045         1,          // 11100
01046         1,          // 11101  - four var
01047         1,          // 11110  - four var
01048         0           // 11111  - skip
01049     };
01050     // permutations
01051     static int Perms[32][5] = {
01052         { 0, 0, 0, 0, 0 }, // 00000  - skip
01053         { 0, 0, 0, 0, 0 }, // 00001  - skip
01054         { 0, 0, 0, 0, 0 }, // 00010  - single var
01055         { 0, 0, 0, 0, 0 }, // 00011  - skip
01056         { 0, 0, 0, 0, 0 }, // 00100  - single var
01057         { 0, 2, 1, 3, 4 }, // 00101
01058         { 2, 0, 1, 3, 4 }, // 00110
01059         { 0, 0, 0, 0, 0 }, // 00111  - skip
01060         { 0, 0, 0, 0, 0 }, // 01000  - single var
01061         { 0, 2, 3, 1, 4 }, // 01001
01062         { 2, 0, 3, 1, 4 }, // 01010
01063         { 0, 1, 3, 2, 4 }, // 01011
01064         { 2, 3, 0, 1, 4 }, // 01100
01065         { 0, 3, 1, 2, 4 }, // 01101
01066         { 3, 0, 1, 2, 4 }, // 01110
01067         { 0, 0, 0, 0, 0 }, // 01111  - skip
01068         { 0, 0, 0, 0, 0 }, // 10000  - single var
01069         { 0, 4, 2, 3, 1 }, // 10001
01070         { 4, 0, 2, 3, 1 }, // 10010
01071         { 0, 1, 3, 4, 2 }, // 10011
01072         { 2, 3, 0, 4, 1 }, // 10100
01073         { 0, 3, 1, 4, 2 }, // 10101
01074         { 3, 0, 1, 4, 2 }, // 10110
01075         { 0, 1, 2, 4, 3 }, // 10111  - four var
01076         { 2, 3, 4, 0, 1 }, // 11000
01077         { 0, 3, 4, 1, 2 }, // 11001
01078         { 3, 0, 4, 1, 2 }, // 11010
01079         { 0, 1, 4, 2, 3 }, // 11011  - four var
01080         { 3, 4, 0, 1, 2 }, // 11100
01081         { 0, 4, 1, 2, 3 }, // 11101  - four var
01082         { 4, 0, 1, 2, 3 }, // 11110  - four var
01083         { 0, 0, 0, 0, 0 }  // 11111  - skip
01084     };
01085     int i, k, iRes;
01086     unsigned uTruthRes;
01087     assert( Phase >= 0 && Phase < 32 );
01088     if ( Cases[Phase] == 0 )
01089         return uTruth;
01090     if ( Cases[Phase] > 1 )
01091         return Cases[Phase];
01092     uTruthRes = 0;
01093     for ( i = 0; i < 32; i++ )
01094         if ( uTruth & (1 << i) )
01095         {
01096             for ( iRes = 0, k = 0; k < 5; k++ )
01097                 if ( i & (1 << Perms[Phase][k]) )
01098                     iRes |= (1 << k);
01099             uTruthRes |= (1 << iRes);
01100         }
01101     return uTruthRes;
01102 }

void Extra_TruthPerm6One ( unsigned *  uTruth,
int  Phase,
unsigned *  uTruthRes 
)

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

Synopsis [Computes a phase of the 3-var function.]

Description []

SideEffects []

SeeAlso []

Definition at line 1115 of file extraUtilMisc.c.

01116 {
01117     // cases
01118     static unsigned Cases[64] = {
01119         0,          // 000000  - skip
01120         0,          // 000001  - skip
01121         0xCCCCCCCC, // 000010  - single var
01122         0,          // 000011  - skip
01123         0xF0F0F0F0, // 000100  - single var
01124         1,          // 000101
01125         1,          // 000110
01126         0,          // 000111  - skip
01127         0xFF00FF00, // 001000  - single var
01128         1,          // 001001
01129         1,          // 001010
01130         1,          // 001011
01131         1,          // 001100
01132         1,          // 001101
01133         1,          // 001110
01134         0,          // 001111  - skip
01135         0xFFFF0000, // 010000  - skip
01136         1,          // 010001
01137         1,          // 010010
01138         1,          // 010011
01139         1,          // 010100
01140         1,          // 010101
01141         1,          // 010110
01142         1,          // 010111  - four var
01143         1,          // 011000
01144         1,          // 011001
01145         1,          // 011010
01146         1,          // 011011  - four var
01147         1,          // 011100
01148         1,          // 011101  - four var
01149         1,          // 011110  - four var
01150         0,          // 011111  - skip
01151         0xFFFFFFFF, // 100000  - single var
01152         1,          // 100001 
01153         1,          // 100010  
01154         1,          // 100011  
01155         1,          // 100100  
01156         1,          // 100101
01157         1,          // 100110
01158         1,          // 100111  
01159         1,          // 101000  
01160         1,          // 101001
01161         1,          // 101010
01162         1,          // 101011
01163         1,          // 101100
01164         1,          // 101101
01165         1,          // 101110
01166         1,          // 101111  
01167         1,          // 110000  
01168         1,          // 110001
01169         1,          // 110010
01170         1,          // 110011
01171         1,          // 110100
01172         1,          // 110101
01173         1,          // 110110
01174         1,          // 110111  
01175         1,          // 111000
01176         1,          // 111001
01177         1,          // 111010
01178         1,          // 111011  
01179         1,          // 111100
01180         1,          // 111101  
01181         1,          // 111110  
01182         0           // 111111  - skip
01183     };
01184     // permutations
01185     static int Perms[64][6] = {
01186         { 0, 0, 0, 0, 0, 0 }, // 000000  - skip
01187         { 0, 0, 0, 0, 0, 0 }, // 000001  - skip
01188         { 0, 0, 0, 0, 0, 0 }, // 000010  - single var
01189         { 0, 0, 0, 0, 0, 0 }, // 000011  - skip
01190         { 0, 0, 0, 0, 0, 0 }, // 000100  - single var
01191         { 0, 2, 1, 3, 4, 5 }, // 000101
01192         { 2, 0, 1, 3, 4, 5 }, // 000110
01193         { 0, 0, 0, 0, 0, 0 }, // 000111  - skip
01194         { 0, 0, 0, 0, 0, 0 }, // 001000  - single var
01195         { 0, 2, 3, 1, 4, 5 }, // 001001
01196         { 2, 0, 3, 1, 4, 5 }, // 001010
01197         { 0, 1, 3, 2, 4, 5 }, // 001011
01198         { 2, 3, 0, 1, 4, 5 }, // 001100
01199         { 0, 3, 1, 2, 4, 5 }, // 001101
01200         { 3, 0, 1, 2, 4, 5 }, // 001110
01201         { 0, 0, 0, 0, 0, 0 }, // 001111  - skip
01202         { 0, 0, 0, 0, 0, 0 }, // 010000  - skip
01203         { 0, 4, 2, 3, 1, 5 }, // 010001
01204         { 4, 0, 2, 3, 1, 5 }, // 010010
01205         { 0, 1, 3, 4, 2, 5 }, // 010011
01206         { 2, 3, 0, 4, 1, 5 }, // 010100
01207         { 0, 3, 1, 4, 2, 5 }, // 010101
01208         { 3, 0, 1, 4, 2, 5 }, // 010110
01209         { 0, 1, 2, 4, 3, 5 }, // 010111  - four var
01210         { 2, 3, 4, 0, 1, 5 }, // 011000
01211         { 0, 3, 4, 1, 2, 5 }, // 011001
01212         { 3, 0, 4, 1, 2, 5 }, // 011010
01213         { 0, 1, 4, 2, 3, 5 }, // 011011  - four var
01214         { 3, 4, 0, 1, 2, 5 }, // 011100
01215         { 0, 4, 1, 2, 3, 5 }, // 011101  - four var
01216         { 4, 0, 1, 2, 3, 5 }, // 011110  - four var
01217         { 0, 0, 0, 0, 0, 0 }, // 011111  - skip
01218         { 0, 0, 0, 0, 0, 0 }, // 100000  - single var
01219         { 0, 2, 3, 4, 5, 1 }, // 100001 
01220         { 2, 0, 3, 4, 5, 1 }, // 100010  
01221         { 0, 1, 3, 4, 5, 2 }, // 100011  
01222         { 2, 3, 0, 4, 5, 1 }, // 100100  
01223         { 0, 3, 1, 4, 5, 2 }, // 100101
01224         { 3, 0, 1, 4, 5, 2 }, // 100110
01225         { 0, 1, 2, 4, 5, 3 }, // 100111  
01226         { 2, 3, 4, 0, 5, 1 }, // 101000  
01227         { 0, 3, 4, 1, 5, 2 }, // 101001
01228         { 3, 0, 4, 1, 5, 2 }, // 101010
01229         { 0, 1, 4, 2, 5, 3 }, // 101011
01230         { 3, 4, 0, 1, 5, 2 }, // 101100
01231         { 0, 4, 1, 2, 5, 3 }, // 101101
01232         { 4, 0, 1, 2, 5, 3 }, // 101110
01233         { 0, 1, 2, 3, 5, 4 }, // 101111  
01234         { 2, 3, 4, 5, 0, 1 }, // 110000  
01235         { 0, 3, 4, 5, 1, 2 }, // 110001
01236         { 3, 0, 4, 5, 1, 2 }, // 110010
01237         { 0, 1, 4, 5, 2, 3 }, // 110011
01238         { 3, 4, 0, 5, 1, 2 }, // 110100
01239         { 0, 4, 1, 5, 2, 3 }, // 110101
01240         { 4, 0, 1, 5, 2, 3 }, // 110110
01241         { 0, 1, 2, 5, 3, 4 }, // 110111  
01242         { 3, 4, 5, 0, 1, 2 }, // 111000
01243         { 0, 4, 5, 1, 2, 3 }, // 111001
01244         { 4, 0, 5, 1, 2, 3 }, // 111010
01245         { 0, 1, 5, 2, 3, 4 }, // 111011  
01246         { 4, 5, 0, 1, 2, 3 }, // 111100
01247         { 0, 5, 1, 2, 3, 4 }, // 111101  
01248         { 5, 0, 1, 2, 3, 4 }, // 111110  
01249         { 0, 0, 0, 0, 0, 0 }  // 111111  - skip
01250     };
01251     int i, k, iRes;
01252     assert( Phase >= 0 && Phase < 64 );
01253     if ( Cases[Phase] == 0 )
01254     {
01255         uTruthRes[0] = uTruth[0];
01256         uTruthRes[1] = uTruth[1];
01257         return;
01258     }
01259     if ( Cases[Phase] > 1 )
01260     {
01261         if ( Phase == 32 )
01262         {
01263             uTruthRes[0] = 0x00000000;
01264             uTruthRes[1] = 0xFFFFFFFF;
01265         }
01266         else
01267         {
01268             uTruthRes[0] = Cases[Phase];
01269             uTruthRes[1] = Cases[Phase];
01270         }
01271         return;
01272     }
01273     uTruthRes[0] = 0;
01274     uTruthRes[1] = 0;
01275     for ( i = 0; i < 64; i++ )
01276     {
01277         if ( i < 32 )
01278         {
01279             if ( uTruth[0] & (1 << i) )
01280             {
01281                 for ( iRes = 0, k = 0; k < 6; k++ )
01282                     if ( i & (1 << Perms[Phase][k]) )
01283                         iRes |= (1 << k);
01284                 if ( iRes < 32 )
01285                     uTruthRes[0] |= (1 << iRes);
01286                 else
01287                     uTruthRes[1] |= (1 << (iRes-32));
01288             }
01289         }
01290         else
01291         {
01292             if ( uTruth[1] & (1 << (i-32)) )
01293             {
01294                 for ( iRes = 0, k = 0; k < 6; k++ )
01295                     if ( i & (1 << Perms[Phase][k]) )
01296                         iRes |= (1 << k);
01297                 if ( iRes < 32 )
01298                     uTruthRes[0] |= (1 << iRes);
01299                 else
01300                     uTruthRes[1] |= (1 << (iRes-32));
01301             }
01302         }
01303     }
01304 }

unsigned Extra_TruthPermute ( unsigned  Truth,
char *  pPerms,
int  nVars,
int  fReverse 
)

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

Synopsis [Permutes the function.]

Description []

SideEffects []

SeeAlso []

Definition at line 390 of file extraUtilMisc.c.

00391 {
00392     unsigned Result;
00393     int * pMints;
00394     int * pMintsP;
00395     int nMints;
00396     int i, m;
00397 
00398     assert( nVars < 6 );
00399     nMints  = (1 << nVars);
00400     pMints  = ALLOC( int, nMints );
00401     pMintsP = ALLOC( int, nMints );
00402     for ( i = 0; i < nMints; i++ )
00403         pMints[i] = i;
00404 
00405     Extra_TruthPermute_int( pMints, nMints, pPerms, nVars, pMintsP );
00406 
00407     Result = 0;
00408     if ( fReverse )
00409     {
00410         for ( m = 0; m < nMints; m++ )
00411             if ( Truth & (1 << pMintsP[m]) )
00412                 Result |= (1 << m);
00413     }
00414     else
00415     {
00416         for ( m = 0; m < nMints; m++ )
00417             if ( Truth & (1 << m) )
00418                 Result |= (1 << pMintsP[m]);
00419     }
00420 
00421     free( pMints );
00422     free( pMintsP );
00423 
00424     return Result;
00425 }

unsigned Extra_TruthPolarize ( unsigned  uTruth,
int  Polarity,
int  nVars 
)

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

Synopsis [Changes the phase of the function.]

Description []

SideEffects []

SeeAlso []

Definition at line 438 of file extraUtilMisc.c.

00439 {
00440     // elementary truth tables
00441     static unsigned Signs[5] = {
00442         0xAAAAAAAA,    // 1010 1010 1010 1010 1010 1010 1010 1010
00443         0xCCCCCCCC,    // 1010 1010 1010 1010 1010 1010 1010 1010
00444         0xF0F0F0F0,    // 1111 0000 1111 0000 1111 0000 1111 0000
00445         0xFF00FF00,    // 1111 1111 0000 0000 1111 1111 0000 0000
00446         0xFFFF0000     // 1111 1111 1111 1111 0000 0000 0000 0000
00447     };
00448     unsigned uTruthRes, uCof0, uCof1;
00449     int nMints, Shift, v;
00450     assert( nVars < 6 );
00451     nMints = (1 << nVars);
00452     uTruthRes = uTruth;
00453     for ( v = 0; v < nVars; v++ )
00454         if ( Polarity & (1 << v) )
00455         {
00456             uCof0  = uTruth & ~Signs[v];
00457             uCof1  = uTruth &  Signs[v];
00458             Shift  = (1 << v);
00459             uCof0 <<= Shift;
00460             uCof1 >>= Shift;
00461             uTruth = uCof0 | uCof1;
00462         }
00463     return uTruth;
00464 }

unsigned Extra_TruthSemiCanonicize ( unsigned *  pInOut,
unsigned *  pAux,
int  nVars,
char *  pCanonPerm,
short *  pStore 
)

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

Synopsis [Canonicize the truth table.]

Description [Returns the phase. ]

SideEffects []

SeeAlso []

Definition at line 996 of file extraUtilTruth.c.

00997 {
00998     unsigned * pIn = pInOut, * pOut = pAux, * pTemp;
00999     int nWords = Extra_TruthWordNum( nVars );
01000     int i, Temp, fChange, Counter, nOnes;//, k, j, w, Limit;
01001     unsigned uCanonPhase;
01002 
01003     // canonicize output
01004     uCanonPhase = 0;
01005     nOnes = Extra_TruthCountOnes(pIn, nVars);
01006     if ( (nOnes > nWords * 16) || ((nOnes == nWords * 16) && (pIn[0] & 1)) )
01007     {
01008         uCanonPhase |= (1 << nVars);
01009         Extra_TruthNot( pIn, pIn, nVars );
01010     }
01011 
01012     // collect the minterm counts
01013     Extra_TruthCountOnesInCofs( pIn, nVars, pStore );
01014 
01015     // canonicize phase
01016     for ( i = 0; i < nVars; i++ )
01017     {
01018         if ( pStore[2*i+0] <= pStore[2*i+1] )
01019             continue;
01020         uCanonPhase |= (1 << i);
01021         Temp = pStore[2*i+0];
01022         pStore[2*i+0] = pStore[2*i+1];
01023         pStore[2*i+1] = Temp;
01024         Extra_TruthChangePhase( pIn, nVars, i );
01025     }
01026 
01027 //    Extra_PrintHexadecimal( stdout, pIn, nVars );
01028 //    printf( "\n" );
01029 
01030     // permute
01031     Counter = 0;
01032     do {
01033         fChange = 0;
01034         for ( i = 0; i < nVars-1; i++ )
01035         {
01036             if ( pStore[2*i] <= pStore[2*(i+1)] )
01037                 continue;
01038             Counter++;
01039             fChange = 1;
01040 
01041             Temp = pCanonPerm[i];
01042             pCanonPerm[i] = pCanonPerm[i+1];
01043             pCanonPerm[i+1] = Temp;
01044 
01045             Temp = pStore[2*i];
01046             pStore[2*i] = pStore[2*(i+1)];
01047             pStore[2*(i+1)] = Temp;
01048 
01049             Temp = pStore[2*i+1];
01050             pStore[2*i+1] = pStore[2*(i+1)+1];
01051             pStore[2*(i+1)+1] = Temp;
01052 
01053             Extra_TruthSwapAdjacentVars( pOut, pIn, nVars, i );
01054             pTemp = pIn; pIn = pOut; pOut = pTemp;
01055         }
01056     } while ( fChange );
01057 
01058 /*
01059     Extra_PrintBinary( stdout, &uCanonPhase, nVars+1 ); printf( " : " );
01060     for ( i = 0; i < nVars; i++ )
01061         printf( "%d=%d/%d  ", pCanonPerm[i], pStore[2*i], pStore[2*i+1] );
01062     printf( "  C = %d\n", Counter );
01063     Extra_PrintHexadecimal( stdout, pIn, nVars );
01064     printf( "\n" );
01065 */
01066 
01067 /*
01068     // process symmetric variable groups
01069     uSymms = 0;
01070     for ( i = 0; i < nVars-1; i++ )
01071     {
01072         if ( pStore[2*i] != pStore[2*(i+1)] ) // i and i+1 cannot be symmetric
01073             continue;
01074         if ( pStore[2*i] != pStore[2*i+1] )
01075             continue;
01076         if ( Extra_TruthVarsSymm( pIn, nVars, i, i+1 ) )
01077             continue;
01078         if ( Extra_TruthVarsAntiSymm( pIn, nVars, i, i+1 ) )
01079             Extra_TruthChangePhase( pIn, nVars, i+1 );
01080     }
01081 */
01082 
01083 /*
01084     // process symmetric variable groups
01085     uSymms = 0;
01086     for ( i = 0; i < nVars-1; i++ )
01087     {
01088         if ( pStore[2*i] != pStore[2*(i+1)] ) // i and i+1 cannot be symmetric
01089             continue;
01090         // i and i+1 can be symmetric
01091         // find the end of this group
01092         for ( k = i+1; k < nVars; k++ )
01093             if ( pStore[2*i] != pStore[2*k] ) 
01094                 break;
01095         Limit = k;
01096         assert( i < Limit-1 );
01097         // go through the variables in this group
01098         for ( j = i + 1; j < Limit; j++ )
01099         {
01100             // check symmetry
01101             if ( Extra_TruthVarsSymm( pIn, nVars, i, j ) )
01102             {
01103                 uSymms |= (1 << j);
01104                 continue;
01105             }
01106             // they are phase-unknown
01107             if ( pStore[2*i] == pStore[2*i+1] ) 
01108             {
01109                 if ( Extra_TruthVarsAntiSymm( pIn, nVars, i, j ) )
01110                 {
01111                     Extra_TruthChangePhase( pIn, nVars, j );
01112                     uCanonPhase ^= (1 << j);
01113                     uSymms |= (1 << j);
01114                     continue;
01115                 }
01116             }
01117 
01118             // they are not symmetric - move j as far as it goes in the group
01119             for ( k = j; k < Limit-1; k++ )
01120             {
01121                 Counter++;
01122 
01123                 Temp = pCanonPerm[k];
01124                 pCanonPerm[k] = pCanonPerm[k+1];
01125                 pCanonPerm[k+1] = Temp;
01126 
01127                 assert( pStore[2*k] == pStore[2*(k+1)] );
01128                 Extra_TruthSwapAdjacentVars( pOut, pIn, nVars, k );
01129                 pTemp = pIn; pIn = pOut; pOut = pTemp;
01130             }
01131             Limit--;
01132             j--;
01133         }
01134         i = Limit - 1;
01135     }
01136 */
01137 
01138     // swap if it was moved an even number of times
01139     if ( Counter & 1 )
01140         Extra_TruthCopy( pOut, pIn, nVars );
01141     return uCanonPhase;
01142 }

static void Extra_TruthSetBit ( unsigned *  p,
int  Bit 
) [inline, static]

Definition at line 436 of file extra.h.

00436 { p[Bit>>5] |= (1<<(Bit & 31));               }

static void Extra_TruthSharp ( unsigned *  pOut,
unsigned *  pIn0,
unsigned *  pIn1,
int  nVars 
) [inline, static]

Definition at line 523 of file extra.h.

00524 {
00525     int w;
00526     for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
00527         pOut[w] = pIn0[w] & ~pIn1[w];
00528 }

void Extra_TruthShrink ( unsigned *  pOut,
unsigned *  pIn,
int  nVars,
int  nVarsAll,
unsigned  Phase 
)

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

Synopsis [Shrinks the truth table according to the phase.]

Description [The input and output truth tables are in pIn/pOut. The current number of variables is nVars. The total number of variables in nVarsAll. The last argument (Phase) contains shows what variables should remain.]

SideEffects []

SeeAlso []

Definition at line 265 of file extraUtilTruth.c.

00266 {
00267     unsigned * pTemp;
00268     int i, k, Var = 0, Counter = 0;
00269     for ( i = 0; i < nVarsAll; i++ )
00270         if ( Phase & (1 << i) )
00271         {
00272             for ( k = i-1; k >= Var; k-- )
00273             {
00274                 Extra_TruthSwapAdjacentVars( pOut, pIn, nVarsAll, k );
00275                 pTemp = pIn; pIn = pOut; pOut = pTemp;
00276                 Counter++;
00277             }
00278             Var++;
00279         }
00280     assert( Var == nVars );
00281     // swap if it was moved an even number of times
00282     if ( !(Counter & 1) )
00283         Extra_TruthCopy( pOut, pIn, nVarsAll );
00284 }

void Extra_TruthStretch ( unsigned *  pOut,
unsigned *  pIn,
int  nVars,
int  nVarsAll,
unsigned  Phase 
)

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

Synopsis [Expands the truth table according to the phase.]

Description [The input and output truth tables are in pIn/pOut. The current number of variables is nVars. The total number of variables in nVarsAll. The last argument (Phase) contains shows where the variables should go.]

SideEffects []

SeeAlso []

Definition at line 231 of file extraUtilTruth.c.

00232 {
00233     unsigned * pTemp;
00234     int i, k, Var = nVars - 1, Counter = 0;
00235     for ( i = nVarsAll - 1; i >= 0; i-- )
00236         if ( Phase & (1 << i) )
00237         {
00238             for ( k = Var; k < i; k++ )
00239             {
00240                 Extra_TruthSwapAdjacentVars( pOut, pIn, nVarsAll, k );
00241                 pTemp = pIn; pIn = pOut; pOut = pTemp;
00242                 Counter++;
00243             }
00244             Var--;
00245         }
00246     assert( Var == -1 );
00247     // swap if it was moved an even number of times
00248     if ( !(Counter & 1) )
00249         Extra_TruthCopy( pOut, pIn, nVarsAll );
00250 }

int Extra_TruthSupport ( unsigned *  pTruth,
int  nVars 
)

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

Synopsis [Returns support of the function.]

Description []

SideEffects []

SeeAlso []

Definition at line 374 of file extraUtilTruth.c.

00375 {
00376     int i, Support = 0;
00377     for ( i = 0; i < nVars; i++ )
00378         if ( Extra_TruthVarInSupport( pTruth, nVars, i ) )
00379             Support |= (1 << i);
00380     return Support;
00381 }

int Extra_TruthSupportSize ( unsigned *  pTruth,
int  nVars 
)

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

Synopsis [Returns the number of support vars.]

Description []

SideEffects []

SeeAlso []

Definition at line 355 of file extraUtilTruth.c.

00356 {
00357     int i, Counter = 0;
00358     for ( i = 0; i < nVars; i++ )
00359         Counter += Extra_TruthVarInSupport( pTruth, nVars, i );
00360     return Counter;
00361 }

void Extra_TruthSwapAdjacentVars ( unsigned *  pOut,
unsigned *  pIn,
int  nVars,
int  iVar 
)

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

Synopsis [Swaps two adjacent variables in the truth table.]

Description [Swaps var number Start and var number Start+1 (0-based numbers). The input truth table is pIn. The output truth table is pOut.]

SideEffects []

SeeAlso []

Definition at line 111 of file extraUtilTruth.c.

00112 {
00113     static unsigned PMasks[4][3] = {
00114         { 0x99999999, 0x22222222, 0x44444444 },
00115         { 0xC3C3C3C3, 0x0C0C0C0C, 0x30303030 },
00116         { 0xF00FF00F, 0x00F000F0, 0x0F000F00 },
00117         { 0xFF0000FF, 0x0000FF00, 0x00FF0000 }
00118     };
00119     int nWords = Extra_TruthWordNum( nVars );
00120     int i, k, Step, Shift;
00121 
00122     assert( iVar < nVars - 1 );
00123     if ( iVar < 4 )
00124     {
00125         Shift = (1 << iVar);
00126         for ( i = 0; i < nWords; i++ )
00127             pOut[i] = (pIn[i] & PMasks[iVar][0]) | ((pIn[i] & PMasks[iVar][1]) << Shift) | ((pIn[i] & PMasks[iVar][2]) >> Shift);
00128     }
00129     else if ( iVar > 4 )
00130     {
00131         Step = (1 << (iVar - 5));
00132         for ( k = 0; k < nWords; k += 4*Step )
00133         {
00134             for ( i = 0; i < Step; i++ )
00135                 pOut[i] = pIn[i];
00136             for ( i = 0; i < Step; i++ )
00137                 pOut[Step+i] = pIn[2*Step+i];
00138             for ( i = 0; i < Step; i++ )
00139                 pOut[2*Step+i] = pIn[Step+i];
00140             for ( i = 0; i < Step; i++ )
00141                 pOut[3*Step+i] = pIn[3*Step+i];
00142             pIn  += 4*Step;
00143             pOut += 4*Step;
00144         }
00145     }
00146     else // if ( iVar == 4 )
00147     {
00148         for ( i = 0; i < nWords; i += 2 )
00149         {
00150             pOut[i]   = (pIn[i]   & 0x0000FFFF) | ((pIn[i+1] & 0x0000FFFF) << 16);
00151             pOut[i+1] = (pIn[i+1] & 0xFFFF0000) | ((pIn[i]   & 0xFFFF0000) >> 16);
00152         }
00153     }
00154 }

int Extra_TruthVarInSupport ( unsigned *  pTruth,
int  nVars,
int  iVar 
)

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

Synopsis [Returns 1 if TT depends on the given variable.]

Description []

SideEffects []

SeeAlso []

Definition at line 298 of file extraUtilTruth.c.

00299 {
00300     int nWords = Extra_TruthWordNum( nVars );
00301     int i, k, Step;
00302 
00303     assert( iVar < nVars );
00304     switch ( iVar )
00305     {
00306     case 0:
00307         for ( i = 0; i < nWords; i++ )
00308             if ( (pTruth[i] & 0x55555555) != ((pTruth[i] & 0xAAAAAAAA) >> 1) )
00309                 return 1;
00310         return 0;
00311     case 1:
00312         for ( i = 0; i < nWords; i++ )
00313             if ( (pTruth[i] & 0x33333333) != ((pTruth[i] & 0xCCCCCCCC) >> 2) )
00314                 return 1;
00315         return 0;
00316     case 2:
00317         for ( i = 0; i < nWords; i++ )
00318             if ( (pTruth[i] & 0x0F0F0F0F) != ((pTruth[i] & 0xF0F0F0F0) >> 4) )
00319                 return 1;
00320         return 0;
00321     case 3:
00322         for ( i = 0; i < nWords; i++ )
00323             if ( (pTruth[i] & 0x00FF00FF) != ((pTruth[i] & 0xFF00FF00) >> 8) )
00324                 return 1;
00325         return 0;
00326     case 4:
00327         for ( i = 0; i < nWords; i++ )
00328             if ( (pTruth[i] & 0x0000FFFF) != ((pTruth[i] & 0xFFFF0000) >> 16) )
00329                 return 1;
00330         return 0;
00331     default:
00332         Step = (1 << (iVar - 5));
00333         for ( k = 0; k < nWords; k += 2*Step )
00334         {
00335             for ( i = 0; i < Step; i++ )
00336                 if ( pTruth[i] != pTruth[Step+i] )
00337                     return 1;
00338             pTruth += 2*Step;
00339         }
00340         return 0;
00341     }
00342 }

static int Extra_TruthWordNum ( int  nVars  )  [inline, static]

Definition at line 434 of file extra.h.

00434 { return nVars <= 5 ? 1 : (1 << (nVars - 5)); }

static void Extra_TruthXorBit ( unsigned *  p,
int  Bit 
) [inline, static]

Definition at line 437 of file extra.h.

00437 { p[Bit>>5] ^= (1<<(Bit & 31));               }

Extra_UnateInfo_t* Extra_UnateComputeFast ( DdManager dd,
DdNode bFunc 
)

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 70 of file extraBddUnate.c.

00073 {
00074     DdNode * bSupp;
00075     DdNode * zRes;
00076     Extra_UnateInfo_t * p;
00077 
00078     bSupp = Cudd_Support( dd, bFunc );                      Cudd_Ref( bSupp );
00079     zRes  = Extra_zddUnateInfoCompute( dd, bFunc, bSupp );  Cudd_Ref( zRes );
00080 
00081     p = Extra_UnateInfoCreateFromZdd( dd, zRes, bSupp );
00082 
00083     Cudd_RecursiveDeref( dd, bSupp );
00084     Cudd_RecursiveDerefZdd( dd, zRes );
00085 
00086     return p;
00087 
00088 } /* end of Extra_UnateInfoCompute */

Extra_UnateInfo_t* Extra_UnateComputeSlow ( DdManager dd,
DdNode bFunc 
)

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

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

Description [Uses the naive way of comparing cofactors.]

SideEffects []

SeeAlso []

Definition at line 290 of file extraBddUnate.c.

00291 {
00292     int nSuppSize;
00293     DdNode * bSupp, * bTemp;
00294     Extra_UnateInfo_t * p;
00295     int i, Res;
00296 
00297     // compute the support
00298     bSupp = Cudd_Support( dd, bFunc );   Cudd_Ref( bSupp );
00299     nSuppSize = Extra_bddSuppSize( dd, bSupp );
00300 //printf( "Support = %d. ", nSuppSize );
00301 //Extra_bddPrint( dd, bSupp );
00302 //printf( "%d ", nSuppSize );
00303 
00304     // allocate the storage for symmetry info
00305     p = Extra_UnateInfoAllocate( nSuppSize );
00306 
00307     // assign the variables
00308     p->nVarsMax = dd->size;
00309     for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ )
00310     {
00311         Res = Extra_bddCheckUnateNaive( dd, bFunc, bTemp->index );
00312         p->pVars[i].iVar = bTemp->index;
00313         if ( Res == -1 )
00314             p->pVars[i].Neg = 1;
00315         else if ( Res == 1 )
00316             p->pVars[i].Pos = 1;
00317         p->nUnate += (Res != 0);
00318     }
00319     Cudd_RecursiveDeref( dd, bSupp );
00320     return p;
00321 
00322 } /* end of Extra_UnateComputeSlow */

Extra_UnateInfo_t* Extra_UnateInfoAllocate ( int  nVars  ) 

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

Synopsis [Allocates unateness information structure.]

Description []

SideEffects []

SeeAlso []

Definition at line 152 of file extraBddUnate.c.

00153 {
00154     Extra_UnateInfo_t * p;
00155     // allocate and clean the storage for unateness info
00156     p = ALLOC( Extra_UnateInfo_t, 1 );
00157     memset( p, 0, sizeof(Extra_UnateInfo_t) );
00158     p->nVars     = nVars;
00159     p->pVars     = ALLOC( Extra_UnateVar_t, nVars );  
00160     memset( p->pVars, 0, nVars * sizeof(Extra_UnateVar_t) );
00161     return p;
00162 } /* end of Extra_UnateInfoAllocate */

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

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 224 of file extraBddUnate.c.

00225 {
00226     Extra_UnateInfo_t * p;
00227     DdNode * bTemp, * zSet, * zCube, * zTemp;
00228     int * pMapVars2Nums;
00229     int i, nSuppSize;
00230 
00231     nSuppSize = Extra_bddSuppSize( dd, bSupp );
00232 
00233     // allocate and clean the storage for symmetry info
00234     p = Extra_UnateInfoAllocate( nSuppSize );
00235 
00236     // allocate the storage for the temporary map
00237     pMapVars2Nums = ALLOC( int, dd->size );
00238     memset( pMapVars2Nums, 0, dd->size * sizeof(int) );
00239 
00240     // assign the variables
00241     p->nVarsMax = dd->size;
00242     for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ )
00243     {
00244         p->pVars[i].iVar = bTemp->index;
00245         pMapVars2Nums[bTemp->index] = i;
00246     }
00247 
00248     // write the symmetry info into the structure
00249     zSet = zPairs;   Cudd_Ref( zSet );
00250 //    Cudd_zddPrintCover( dd, zPairs );    printf( "\n" );
00251     while ( zSet != z0 )
00252     {
00253         // get the next cube
00254         zCube  = Extra_zddSelectOneSubset( dd, zSet );    Cudd_Ref( zCube );
00255 
00256         // add this var to the data structure
00257         assert( cuddT(zCube) == z1 && cuddE(zCube) == z0 );
00258         if ( zCube->index & 1 ) // neg
00259             p->pVars[ pMapVars2Nums[zCube->index/2] ].Neg = 1;
00260         else
00261             p->pVars[ pMapVars2Nums[zCube->index/2] ].Pos = 1;
00262         // count the unate vars
00263         p->nUnate++;
00264 
00265         // update the cuver and deref the cube
00266         zSet = Cudd_zddDiff( dd, zTemp = zSet, zCube );     Cudd_Ref( zSet );
00267         Cudd_RecursiveDerefZdd( dd, zTemp );
00268         Cudd_RecursiveDerefZdd( dd, zCube );
00269 
00270     } // for each cube 
00271     Cudd_RecursiveDerefZdd( dd, zSet );
00272     FREE( pMapVars2Nums );
00273     return p;
00274 
00275 } /* end of Extra_UnateInfoCreateFromZdd */

void Extra_UnateInfoDissolve ( Extra_UnateInfo_t p  ) 

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

Synopsis [Deallocates symmetry information structure.]

Description []

SideEffects []

SeeAlso []

Definition at line 175 of file extraBddUnate.c.

00176 {
00177     free( p->pVars );
00178     free( p );
00179 } /* end of Extra_UnateInfoDissolve */

void Extra_UnateInfoPrint ( Extra_UnateInfo_t p  ) 

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

Synopsis [Allocates symmetry information structure.]

Description []

SideEffects []

SeeAlso []

Definition at line 192 of file extraBddUnate.c.

00193 {
00194     char * pBuffer;
00195     int i;
00196     pBuffer = ALLOC( char, p->nVarsMax+1 );
00197     memset( pBuffer, ' ', p->nVarsMax );
00198     pBuffer[p->nVarsMax] = 0;
00199     for ( i = 0; i < p->nVars; i++ )
00200         if ( p->pVars[i].Neg )
00201             pBuffer[ p->pVars[i].iVar ] = 'n';
00202         else if ( p->pVars[i].Pos )
00203             pBuffer[ p->pVars[i].iVar ] = 'p';
00204         else
00205             pBuffer[ p->pVars[i].iVar ] = '.';
00206     printf( "%s\n", pBuffer );
00207     free( pBuffer );
00208 } /* end of Extra_UnateInfoPrint */

char* Extra_UtilFileSearch ( char *  file,
char *  path,
char *  mode 
)

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

Synopsis [util_file_search()]

Description []

SideEffects []

SeeAlso []

Definition at line 246 of file extraUtilUtil.c.

00250 {
00251     int quit;
00252     char *buffer, *filename, *save_path, *cp;
00253 
00254     if (path == 0 || strcmp(path, "") == 0) {
00255         path = ".";             /* just look in the current directory */
00256     }
00257 
00258     save_path = path = Extra_UtilStrsav(path);
00259     quit = 0;
00260     do {
00261         cp = strchr(path, ':');
00262         if (cp != 0) {
00263             *cp = '\0';
00264         } else {
00265             quit = 1;
00266         }
00267 
00268         /* cons up the filename out of the path and file name */
00269         if (strcmp(path, ".") == 0) {
00270             buffer = Extra_UtilStrsav(file);
00271         } else {
00272             buffer = ALLOC(char, strlen(path) + strlen(file) + 4);
00273             (void) sprintf(buffer, "%s/%s", path, file);
00274         }
00275         filename = Extra_UtilTildeExpand(buffer);
00276         FREE(buffer);
00277 
00278         /* see if we can access it */
00279         if (Extra_UtilCheckFile(filename, mode)) {
00280             FREE(save_path);
00281             return filename;
00282         }
00283         FREE(filename);
00284         path = ++cp;
00285     } while (! quit); 
00286 
00287     FREE(save_path);
00288     return 0;
00289 }

int Extra_UtilGetopt ( int  argc,
char *  argv[],
char *  optstring 
)

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

Synopsis [util_getopt()]

Description []

SideEffects []

SeeAlso []

Definition at line 111 of file extraUtilUtil.c.

00112 {
00113     register int c;
00114     register char *place;
00115 
00116     globalUtilOptarg = NULL;
00117 
00118     if (pScanStr == NULL || *pScanStr == '\0') {
00119     if (globalUtilOptind == 0) globalUtilOptind++;
00120     if (globalUtilOptind >= argc) return EOF;
00121     place = argv[globalUtilOptind];
00122     if (place[0] != '-' || place[1] == '\0') return EOF;
00123     globalUtilOptind++;
00124     if (place[1] == '-' && place[2] == '\0') return EOF;
00125     pScanStr = place+1;
00126     }
00127 
00128     c = *pScanStr++;
00129     place = strchr(optstring, c);
00130     if (place == NULL || c == ':') {
00131     (void) fprintf(stderr, "%s: unknown option %c\n", argv[0], c);
00132     return '?';
00133     }
00134     if (*++place == ':') {
00135     if (*pScanStr != '\0') {
00136         globalUtilOptarg = pScanStr;
00137         pScanStr = NULL;
00138     } else {
00139         if (globalUtilOptind >= argc) {
00140         (void) fprintf(stderr, "%s: %c requires an argument\n", 
00141             argv[0], c);
00142         return '?';
00143         }
00144         globalUtilOptarg = argv[globalUtilOptind];
00145         globalUtilOptind++;
00146     }
00147     }
00148     return c;
00149 }

void Extra_UtilGetoptReset (  ) 

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

Synopsis [util_getopt_reset()]

Description []

SideEffects []

SeeAlso []

Definition at line 93 of file extraUtilUtil.c.

00094 {
00095     globalUtilOptarg = 0;
00096     globalUtilOptind = 0;
00097     pScanStr = 0;
00098 }

char* Extra_UtilPrintTime ( long  t  ) 

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

Synopsis [util_print_time()]

Description []

SideEffects []

SeeAlso []

Definition at line 162 of file extraUtilUtil.c.

00163 {
00164     static char s[40];
00165 
00166     (void) sprintf(s, "%ld.%02ld sec", t/1000, (t%1000)/10);
00167     return s;
00168 }

char* Extra_UtilStrsav ( char *  s  ) 

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

Synopsis [Extra_UtilStrsav()]

Description []

SideEffects []

SeeAlso []

Definition at line 182 of file extraUtilUtil.c.

00183 {
00184     if(s == NULL) {  /* added 7/95, for robustness */
00185        return s;
00186     }
00187     else {
00188        return strcpy(ALLOC(char, strlen(s)+1), s);
00189     }
00190 }

char* Extra_UtilTildeExpand ( char *  fname  ) 

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

Synopsis [util_tilde_expand()]

Description []

SideEffects []

SeeAlso []

Definition at line 203 of file extraUtilUtil.c.

00204 {
00205     return Extra_UtilStrsav( fname );
00206 }

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

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 546 of file extraBddMisc.c.

00551 {
00552     int i, size;
00553 
00554     /* Allocate and initialize support array for ddSupportStep. */
00555     size = ddMax( dd->size, dd->sizeZ );
00556     for ( i = 0; i < size; i++ )
00557         support[i] = 0;
00558 
00559     /* Compute support and clean up markers. */
00560     for ( i = 0; i < n; i++ )
00561         ddSupportStep( Cudd_Regular(F[i]), support );
00562     for ( i = 0; i < n; i++ )
00563         ddClearFlag( Cudd_Regular(F[i]) );
00564 
00565     return support;
00566 }

static int Extra_WordCountOnes ( unsigned  uWord  )  [inline, static]

Definition at line 440 of file extra.h.

00441 {
00442     uWord = (uWord & 0x55555555) + ((uWord>>1) & 0x55555555);
00443     uWord = (uWord & 0x33333333) + ((uWord>>2) & 0x33333333);
00444     uWord = (uWord & 0x0F0F0F0F) + ((uWord>>4) & 0x0F0F0F0F);
00445     uWord = (uWord & 0x00FF00FF) + ((uWord>>8) & 0x00FF00FF);
00446     return  (uWord & 0x0000FFFF) + (uWord>>16);
00447 }

DdNode* Extra_zddGetSingletons ( DdManager dd,
DdNode bVars 
)

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 154 of file extraBddSymm.c.

00157 {
00158     DdNode * res;
00159     do {
00160         dd->reordered = 0;
00161         res = extraZddGetSingletons( dd, bVars );
00162     } while (dd->reordered == 1);
00163     return(res);
00164 
00165 } /* end of Extra_zddGetSingletons */

DdNode* Extra_zddGetSingletonsBoth ( DdManager dd,
DdNode bVars 
)

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 128 of file extraBddUnate.c.

00131 {
00132     DdNode * res;
00133     do {
00134         dd->reordered = 0;
00135         res = extraZddGetSingletonsBoth( dd, bVars );
00136     } while (dd->reordered == 1);
00137     return(res);
00138 
00139 } /* end of Extra_zddGetSingletonsBoth */

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

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 127 of file extraBddSymm.c.

00132 {
00133     DdNode * res;
00134     do {
00135         dd->reordered = 0;
00136         res = extraZddGetSymmetricVars( dd, bF, bG, bVars );
00137     } while (dd->reordered == 1);
00138     return(res);
00139 
00140 } /* end of Extra_zddGetSymmetricVars */

DdNode* Extra_zddPrimes ( DdManager dd,
DdNode F 
)

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 907 of file extraBddMisc.c.

00908 {
00909     DdNode      *res;
00910     do {
00911                 dd->reordered = 0;
00912                 res = extraZddPrimes(dd, F);
00913                 if ( dd->reordered == 1 )
00914                         printf("\nReordering in Extra_zddPrimes()\n");
00915     } while (dd->reordered == 1);
00916     return(res);
00917 
00918 } /* end of Extra_zddPrimes */

DdNode* Extra_zddSelectOneSubset ( DdManager dd,
DdNode zS 
)

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

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

Description []

SideEffects [None]

SeeAlso []

Definition at line 543 of file extraBddSymm.c.

00546 {
00547     DdNode  *res;
00548     do {
00549         dd->reordered = 0;
00550         res = extraZddSelectOneSubset(dd, zS);
00551     } while (dd->reordered == 1);
00552     return(res);
00553 
00554 } /* end of Extra_zddSelectOneSubset */

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

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 102 of file extraBddSymm.c.

00106 {
00107     DdNode * res;
00108     do {
00109         dd->reordered = 0;
00110         res = extraZddSymmPairsCompute( dd, bF, bVars );
00111     } while (dd->reordered == 1);
00112     return(res);
00113 
00114 } /* end of Extra_zddSymmPairsCompute */

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

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 485 of file extraBddSymm.c.

00489 {
00490     DdNode  *zRes;
00491     int     autoDynZ;
00492 
00493     autoDynZ = dd->autoDynZ;
00494     dd->autoDynZ = 0;
00495 
00496     do {
00497         /* transform the numeric arguments (K) into a DdNode* argument;
00498          * this allows us to use the standard internal CUDD cache */
00499         DdNode *bVarSet = bVarsN, *bVarsK = bVarsN;
00500         int     nVars = 0, i;
00501 
00502         /* determine the number of variables in VarSet */
00503         while ( bVarSet != b1 )
00504         {
00505             nVars++;
00506             /* make sure that the VarSet is a cube */
00507             if ( cuddE( bVarSet ) != b0 )
00508                 return NULL;
00509             bVarSet = cuddT( bVarSet );
00510         }
00511         /* make sure that the number of variables in VarSet is less or equal 
00512            that the number of variables that should be present in the tuples
00513         */
00514         if ( K > nVars )
00515             return NULL;
00516 
00517         /* the second argument in the recursive call stannds for <n>;
00518         /* reate the first argument, which stands for <k> 
00519          * as when we are talking about the tuple of <k> out of <n> */
00520         for ( i = 0; i < nVars-K; i++ )
00521             bVarsK = cuddT( bVarsK );
00522 
00523         dd->reordered = 0;
00524         zRes = extraZddTuplesFromBdd(dd, bVarsK, bVarsN );
00525 
00526     } while (dd->reordered == 1);
00527     dd->autoDynZ = autoDynZ;
00528     return zRes;
00529 
00530 } /* end of Extra_zddTuplesFromBdd */

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

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 102 of file extraBddUnate.c.

00106 {
00107     DdNode * res;
00108     do {
00109         dd->reordered = 0;
00110         res = extraZddUnateInfoCompute( dd, bF, bVars );
00111     } while (dd->reordered == 1);
00112     return(res);
00113 
00114 } /* end of Extra_zddUnateInfoCompute */

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

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 1166 of file extraBddSymm.c.

01170 {
01171     DdNode * bRes;
01172 
01173     if ( bF == b0 )
01174         return b1;
01175 
01176     assert( bVars != b1 );
01177     
01178     if ( bRes = cuddCacheLookup2(dd, extraBddCheckVarsSymmetric, bF, bVars) )
01179         return bRes;
01180     else
01181     {
01182         DdNode * bRes0, * bRes1;
01183         DdNode * bF0, * bF1;             
01184         DdNode * bFR = Cudd_Regular(bF);
01185         int LevelF = cuddI(dd,bFR->index);
01186 
01187         DdNode * bVarsR = Cudd_Regular(bVars);
01188         int fVar1Pres;
01189         int iLev1;
01190         int iLev2;
01191 
01192         if ( bVarsR != bVars ) // cube's pointer is complemented
01193         {
01194             assert( cuddT(bVarsR) == b1 );
01195             fVar1Pres = 1;                    // the first var is present on the path
01196             iLev1 = -1;                       // we are already below the first var level
01197             iLev2 = dd->perm[bVarsR->index];  // the level of the second var
01198         }
01199         else  // cube's pointer is NOT complemented
01200         {
01201             fVar1Pres = 0;                    // the first var is absent on the path
01202             if ( cuddT(bVars) == b1 )
01203             {
01204                 iLev1 = -1;                             // we are already below the first var level 
01205                 iLev2 = dd->perm[bVars->index];         // the level of the second var
01206             }
01207             else
01208             {
01209                 assert( cuddT(cuddT(bVars)) == b1 );
01210                 iLev1 = dd->perm[bVars->index];         // the level of the first var 
01211                 iLev2 = dd->perm[cuddT(bVars)->index];  // the level of the second var
01212             }
01213         }
01214 
01215         // cofactor the function
01216         // the cofactors are needed only if we are above the second level
01217         if ( LevelF < iLev2 )
01218         {
01219             if ( bFR != bF ) // bFunc is complemented 
01220             {
01221                 bF0 = Cudd_Not( cuddE(bFR) );
01222                 bF1 = Cudd_Not( cuddT(bFR) );
01223             }
01224             else
01225             {
01226                 bF0 = cuddE(bFR);
01227                 bF1 = cuddT(bFR);
01228             }
01229         }
01230         else
01231             bF0 = bF1 = NULL;
01232 
01233         // consider five cases:
01234         // (1) F is above iLev1
01235         // (2) F is on the level iLev1
01236         // (3) F is between iLev1 and iLev2
01237         // (4) F is on the level iLev2
01238         // (5) F is below iLev2
01239 
01240         // (1) F is above iLev1
01241         if ( LevelF < iLev1 )
01242         {
01243             // the returned result cannot have the hash attribute
01244             // because we still did not reach the level of Var1;
01245             // the attribute never travels above the level of Var1
01246             bRes0 = extraBddCheckVarsSymmetric( dd, bF0, bVars );
01247 //          assert( !Hash_IsComplement( bRes0 ) );
01248             assert( bRes0 != z0 );
01249             if ( bRes0 == b0 )
01250                 bRes = b0;
01251             else
01252                 bRes = extraBddCheckVarsSymmetric( dd, bF1, bVars );
01253 //          assert( !Hash_IsComplement( bRes ) );
01254             assert( bRes != z0 );
01255         }
01256         // (2) F is on the level iLev1
01257         else if ( LevelF == iLev1 )
01258         {
01259             bRes0 = extraBddCheckVarsSymmetric( dd, bF0, Cudd_Not( cuddT(bVars) ) );
01260             if ( bRes0 == b0 )
01261                 bRes = b0;
01262             else
01263             {
01264                 bRes1 = extraBddCheckVarsSymmetric( dd, bF1, Cudd_Not( cuddT(bVars) ) );
01265                 if ( bRes1 == b0 )
01266                     bRes = b0;
01267                 else
01268                 {
01269 //                  if ( Hash_IsComplement( bRes0 ) || Hash_IsComplement( bRes1 ) )
01270                     if ( bRes0 == z0 || bRes1 == z0 )
01271                         bRes = b1;
01272                     else
01273                         bRes = b0;
01274                 }
01275             }
01276         }
01277         // (3) F is between iLev1 and iLev2
01278         else if ( LevelF < iLev2 )
01279         {
01280             bRes0 = extraBddCheckVarsSymmetric( dd, bF0, bVars );
01281             if ( bRes0 == b0 )
01282                 bRes = b0;
01283             else
01284             {
01285                 bRes1 = extraBddCheckVarsSymmetric( dd, bF1, bVars );
01286                 if ( bRes1 == b0 )
01287                     bRes = b0;
01288                 else
01289                 {
01290 //                  if ( Hash_IsComplement( bRes0 ) || Hash_IsComplement( bRes1 ) )
01291 //                      bRes = Hash_Not( b1 );
01292                     if ( bRes0 == z0 || bRes1 == z0 )
01293                         bRes = z0;
01294                     else
01295                         bRes = b1;
01296                 }
01297             }
01298         }
01299         // (4) F is on the level iLev2
01300         else if ( LevelF == iLev2 )
01301         {
01302             // this is the only place where the hash attribute (Hash_Not) can be added 
01303             // to the result; it can be added only if the path came through the node
01304             // lebeled with Var1; therefore, the hash attribute cannot be returned
01305             // to the caller function
01306             if ( fVar1Pres )
01307 //              bRes = Hash_Not( b1 );
01308                 bRes = z0;
01309             else 
01310                 bRes = b0;
01311         }
01312         // (5) F is below iLev2
01313         else // if ( LevelF > iLev2 )
01314         {
01315             // it is possible that the path goes through the node labeled by Var1
01316             // and still everything is okay; we do not label with Hash_Not here
01317             // because the path does not go through node labeled by Var2
01318             bRes = b1;
01319         }
01320 
01321         cuddCacheInsert2(dd, extraBddCheckVarsSymmetric, bF, bVars, bRes);
01322         return bRes;
01323     }
01324 } /* end of extraBddCheckVarsSymmetric */

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

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 979 of file extraBddMisc.c.

00983 {
00984     DdNode * bRes;
00985 
00986     if ( Cudd_IsConstant(bF) )
00987         return bF;
00988 
00989     if ( bRes = cuddCacheLookup2(dd, extraBddMove, bF, bDist) )
00990         return bRes;
00991     else
00992     {
00993         DdNode * bRes0, * bRes1;             
00994         DdNode * bF0, * bF1;             
00995         DdNode * bFR = Cudd_Regular(bF); 
00996         int VarNew;
00997         
00998         if ( Cudd_IsComplement(bDist) )
00999             VarNew = bFR->index - Cudd_Not(bDist)->index;
01000         else
01001             VarNew = bFR->index + bDist->index;
01002         assert( VarNew < dd->size );
01003 
01004         // cofactor the functions
01005         if ( bFR != bF ) // bFunc is complemented 
01006         {
01007             bF0 = Cudd_Not( cuddE(bFR) );
01008             bF1 = Cudd_Not( cuddT(bFR) );
01009         }
01010         else
01011         {
01012             bF0 = cuddE(bFR);
01013             bF1 = cuddT(bFR);
01014         }
01015 
01016         bRes0 = extraBddMove( dd, bF0, bDist );
01017         if ( bRes0 == NULL ) 
01018             return NULL;
01019         cuddRef( bRes0 );
01020 
01021         bRes1 = extraBddMove( dd, bF1, bDist );
01022         if ( bRes1 == NULL ) 
01023         {
01024             Cudd_RecursiveDeref( dd, bRes0 );
01025             return NULL;
01026         }
01027         cuddRef( bRes1 );
01028 
01029         /* only bRes0 and bRes1 are referenced at this point */
01030         bRes = cuddBddIteRecur( dd, dd->vars[VarNew], bRes1, bRes0 );
01031         if ( bRes == NULL ) 
01032         {
01033             Cudd_RecursiveDeref( dd, bRes0 );
01034             Cudd_RecursiveDeref( dd, bRes1 );
01035             return NULL;
01036         }
01037         cuddRef( bRes );
01038         Cudd_RecursiveDeref( dd, bRes0 );
01039         Cudd_RecursiveDeref( dd, bRes1 );
01040 
01041         /* insert the result into cache */
01042         cuddCacheInsert2( dd, extraBddMove, bF, bDist, bRes );
01043         cuddDeref( bRes );
01044         return bRes;
01045     }
01046 } /* end of extraBddMove */

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

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 1059 of file extraBddSymm.c.

01063 {
01064     DdNode * bRes;
01065     DdNode * bFR = Cudd_Regular(bF);
01066 
01067     if ( cuddIsConstant(bFR) || bVars == b1 )
01068         return bVars;
01069 
01070     if ( bRes = cuddCacheLookup2(dd, extraBddReduceVarSet, bVars, bF) )
01071         return bRes;
01072     else
01073     {
01074         DdNode * bF0, * bF1;             
01075         DdNode * bVarsThis, * bVarsLower, * bTemp;
01076         int LevelF;
01077 
01078         // if LevelF is below LevelV, scroll through the vars in bVars 
01079         LevelF = dd->perm[bFR->index];
01080         for ( bVarsThis = bVars; LevelF > cuddI(dd,bVarsThis->index); bVarsThis = cuddT(bVarsThis) );
01081         // scroll also through the current var, because it should be not be added
01082         if ( LevelF == cuddI(dd,bVarsThis->index) )
01083             bVarsLower = cuddT(bVarsThis);
01084         else
01085             bVarsLower = bVarsThis;
01086 
01087         // cofactor the function
01088         if ( bFR != bF ) // bFunc is complemented 
01089         {
01090             bF0 = Cudd_Not( cuddE(bFR) );
01091             bF1 = Cudd_Not( cuddT(bFR) );
01092         }
01093         else
01094         {
01095             bF0 = cuddE(bFR);
01096             bF1 = cuddT(bFR);
01097         }
01098 
01099         // solve subproblems
01100         bRes = extraBddReduceVarSet( dd, bVarsLower, bF0 );
01101         if ( bRes == NULL ) 
01102             return NULL;
01103         cuddRef( bRes );
01104 
01105         bRes = extraBddReduceVarSet( dd, bTemp = bRes, bF1 );
01106         if ( bRes == NULL ) 
01107         {
01108             Cudd_RecursiveDeref( dd, bTemp );
01109             return NULL;
01110         }
01111         cuddRef( bRes );
01112         Cudd_RecursiveDeref( dd, bTemp );
01113 
01114         // the current var should not be added
01115         // add the skipped vars
01116         if ( bVarsThis != bVars )
01117         {
01118             DdNode * bVarsExtra;
01119 
01120             // extract the skipped variables
01121             bVarsExtra = cuddBddExistAbstractRecur( dd, bVars, bVarsThis );
01122             if ( bVarsExtra == NULL )
01123             {
01124                 Cudd_RecursiveDeref( dd, bRes );
01125                 return NULL;
01126             }
01127             cuddRef( bVarsExtra );
01128 
01129             // add these variables
01130             bRes = cuddBddAndRecur( dd, bTemp = bRes, bVarsExtra );
01131             if ( bRes == NULL ) 
01132             {
01133                 Cudd_RecursiveDeref( dd, bTemp );
01134                 Cudd_RecursiveDeref( dd, bVarsExtra );
01135                 return NULL;
01136             }
01137             cuddRef( bRes );
01138             Cudd_RecursiveDeref( dd, bTemp );
01139             Cudd_RecursiveDeref( dd, bVarsExtra );
01140         }
01141         cuddDeref( bRes );
01142 
01143         cuddCacheInsert2( dd, extraBddReduceVarSet, bVars, bF, bRes );
01144         return bRes;
01145     }
01146 }   /* end of extraBddReduceVarSet */

DdNode* extraBddSpaceCanonVars ( DdManager dd,
DdNode bF 
)

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 997 of file extraBddAuto.c.

00998 {
00999         DdNode * bRes, * bFR;
01000         statLine( dd );
01001 
01002         bFR = Cudd_Regular(bF);
01003         if ( cuddIsConstant(bFR) )
01004                 return bF;
01005 
01006     if ( bRes = cuddCacheLookup1(dd, extraBddSpaceCanonVars, bF) )
01007         return bRes;
01008         else
01009         {
01010                 DdNode * bF0,  * bF1;
01011                 DdNode * bRes, * bRes0; 
01012 
01013                 if ( bFR != bF ) // bF is complemented 
01014                 {
01015                         bF0 = Cudd_Not( cuddE(bFR) );
01016                         bF1 = Cudd_Not( cuddT(bFR) );
01017                 }
01018                 else
01019                 {
01020                         bF0 = cuddE(bFR);
01021                         bF1 = cuddT(bFR);
01022                 }
01023 
01024                 if ( bF0 == b0 )
01025                 {
01026                         bRes = extraBddSpaceCanonVars( dd, bF1 );
01027                         if ( bRes == NULL )
01028                                 return NULL;
01029                 }
01030                 else if ( bF1 == b0 )
01031                 {
01032                         bRes = extraBddSpaceCanonVars( dd, bF0 );
01033                         if ( bRes == NULL )
01034                                 return NULL;
01035                 }
01036                 else
01037                 {
01038                         bRes0 = extraBddSpaceCanonVars( dd, bF0 );
01039                         if ( bRes0 == NULL )
01040                                 return NULL;
01041                         cuddRef( bRes0 );
01042 
01043                         bRes = cuddUniqueInter( dd, bFR->index, bRes0, b0 );
01044                         if ( bRes == NULL ) 
01045                         {
01046                                 Cudd_RecursiveDeref( dd,bRes0 );
01047                                 return NULL;
01048                         }
01049                         cuddDeref( bRes0 );
01050                 }
01051 
01052                 cuddCacheInsert1( dd, extraBddSpaceCanonVars, bF, bRes );
01053                 return bRes;
01054         }
01055 }

DdNode* extraBddSpaceEquationsNeg ( DdManager dd,
DdNode bF 
)

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 1198 of file extraBddAuto.c.

01199 {
01200         DdNode * zRes;
01201         statLine( dd );
01202 
01203         if ( bF == b0 )
01204                 return z1;
01205         if ( bF == b1 )
01206                 return z0;
01207         
01208     if ( zRes = cuddCacheLookup1Zdd(dd, extraBddSpaceEquationsNeg, bF) )
01209         return zRes;
01210         else
01211         {
01212                 DdNode * bFR, * bF0,  * bF1;
01213                 DdNode * zPos0, * zPos1, * zNeg1; 
01214                 DdNode * zRes, * zRes0, * zRes1;
01215 
01216                 bFR = Cudd_Regular(bF);
01217                 if ( bFR != bF ) // bF is complemented 
01218                 {
01219                         bF0 = Cudd_Not( cuddE(bFR) );
01220                         bF1 = Cudd_Not( cuddT(bFR) );
01221                 }
01222                 else
01223                 {
01224                         bF0 = cuddE(bFR);
01225                         bF1 = cuddT(bFR);
01226                 }
01227 
01228                 if ( bF0 == b0 )
01229                 {
01230                         zRes = extraBddSpaceEquationsNeg( dd, bF1 );
01231                         if ( zRes == NULL )
01232                                 return NULL;
01233                 }
01234                 else if ( bF1 == b0 )
01235                 {
01236                         zRes0 = extraBddSpaceEquationsNeg( dd, bF0 );
01237                         if ( zRes0 == NULL )
01238                                 return NULL;
01239                         cuddRef( zRes0 );
01240 
01241                         // add the current element to the set
01242                         zRes = cuddZddGetNode( dd, 2*bFR->index, z1, zRes0 );
01243                         if ( zRes == NULL ) 
01244                         {
01245                                 Cudd_RecursiveDerefZdd(dd, zRes0);
01246                                 return NULL;
01247                         }
01248                         cuddDeref( zRes0 );
01249                 }
01250                 else
01251                 {
01252                         zPos0 = extraBddSpaceEquationsNeg( dd, bF0 );
01253                         if ( zPos0 == NULL )
01254                                 return NULL;
01255                         cuddRef( zPos0 );
01256 
01257                         zPos1 = extraBddSpaceEquationsNeg( dd, bF1 );
01258                         if ( zPos1 == NULL )
01259                         {
01260                                 Cudd_RecursiveDerefZdd(dd, zPos0);
01261                                 return NULL;
01262                         }
01263                         cuddRef( zPos1 );
01264 
01265                         zNeg1 = extraBddSpaceEquationsPos( dd, bF1 );
01266                         if ( zNeg1 == NULL )
01267                         {
01268                                 Cudd_RecursiveDerefZdd(dd, zPos0);
01269                                 Cudd_RecursiveDerefZdd(dd, zPos1);
01270                                 return NULL;
01271                         }
01272                         cuddRef( zNeg1 );
01273 
01274 
01275                         zRes0 = cuddZddIntersect( dd, zPos0, zPos1 );
01276                         if ( zRes0 == NULL )
01277                         {
01278                                 Cudd_RecursiveDerefZdd(dd, zNeg1);
01279                                 Cudd_RecursiveDerefZdd(dd, zPos0);
01280                                 Cudd_RecursiveDerefZdd(dd, zPos1);
01281                                 return NULL;
01282                         }
01283                         cuddRef( zRes0 );
01284 
01285                         zRes1 = cuddZddIntersect( dd, zPos0, zNeg1 );
01286                         if ( zRes1 == NULL )
01287                         {
01288                                 Cudd_RecursiveDerefZdd(dd, zRes0);
01289                                 Cudd_RecursiveDerefZdd(dd, zNeg1);
01290                                 Cudd_RecursiveDerefZdd(dd, zPos0);
01291                                 Cudd_RecursiveDerefZdd(dd, zPos1);
01292                                 return NULL;
01293                         }
01294                         cuddRef( zRes1 );
01295                         Cudd_RecursiveDerefZdd(dd, zNeg1);
01296                         Cudd_RecursiveDerefZdd(dd, zPos0);
01297                         Cudd_RecursiveDerefZdd(dd, zPos1);
01298                         // only zRes0 and zRes1 are refed at this point
01299 
01300                         zRes = cuddZddGetNode( dd, 2*bFR->index, zRes1, zRes0 );
01301                         if ( zRes == NULL ) 
01302                         {
01303                                 Cudd_RecursiveDerefZdd(dd, zRes0);
01304                                 Cudd_RecursiveDerefZdd(dd, zRes1);
01305                                 return NULL;
01306                         }
01307                         cuddDeref( zRes0 );
01308                         cuddDeref( zRes1 );
01309                 }
01310 
01311                 cuddCacheInsert1( dd, extraBddSpaceEquationsNeg, bF, zRes );
01312                 return zRes;
01313         }
01314 }

DdNode* extraBddSpaceEquationsPos ( DdManager dd,
DdNode bF 
)

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 1068 of file extraBddAuto.c.

01069 {
01070         DdNode * zRes;
01071         statLine( dd );
01072 
01073         if ( bF == b0 )
01074                 return z1;
01075         if ( bF == b1 )
01076                 return z0;
01077         
01078     if ( zRes = cuddCacheLookup1Zdd(dd, extraBddSpaceEquationsPos, bF) )
01079         return zRes;
01080         else
01081         {
01082                 DdNode * bFR, * bF0,  * bF1;
01083                 DdNode * zPos0, * zPos1, * zNeg1; 
01084                 DdNode * zRes, * zRes0, * zRes1;
01085 
01086                 bFR = Cudd_Regular(bF);
01087                 if ( bFR != bF ) // bF is complemented 
01088                 {
01089                         bF0 = Cudd_Not( cuddE(bFR) );
01090                         bF1 = Cudd_Not( cuddT(bFR) );
01091                 }
01092                 else
01093                 {
01094                         bF0 = cuddE(bFR);
01095                         bF1 = cuddT(bFR);
01096                 }
01097 
01098                 if ( bF0 == b0 )
01099                 {
01100                         zRes1 = extraBddSpaceEquationsPos( dd, bF1 );
01101                         if ( zRes1 == NULL )
01102                                 return NULL;
01103                         cuddRef( zRes1 );
01104 
01105                         // add the current element to the set
01106                         zRes = cuddZddGetNode( dd, 2*bFR->index, z1, zRes1 );
01107                         if ( zRes == NULL ) 
01108                         {
01109                                 Cudd_RecursiveDerefZdd(dd, zRes1);
01110                                 return NULL;
01111                         }
01112                         cuddDeref( zRes1 );
01113                 }
01114                 else if ( bF1 == b0 )
01115                 {
01116                         zRes = extraBddSpaceEquationsPos( dd, bF0 );
01117                         if ( zRes == NULL )
01118                                 return NULL;
01119                 }
01120                 else
01121                 {
01122                         zPos0 = extraBddSpaceEquationsPos( dd, bF0 );
01123                         if ( zPos0 == NULL )
01124                                 return NULL;
01125                         cuddRef( zPos0 );
01126 
01127                         zPos1 = extraBddSpaceEquationsPos( dd, bF1 );
01128                         if ( zPos1 == NULL )
01129                         {
01130                                 Cudd_RecursiveDerefZdd(dd, zPos0);
01131                                 return NULL;
01132                         }
01133                         cuddRef( zPos1 );
01134 
01135                         zNeg1 = extraBddSpaceEquationsNeg( dd, bF1 );
01136                         if ( zNeg1 == NULL )
01137                         {
01138                                 Cudd_RecursiveDerefZdd(dd, zPos0);
01139                                 Cudd_RecursiveDerefZdd(dd, zPos1);
01140                                 return NULL;
01141                         }
01142                         cuddRef( zNeg1 );
01143 
01144 
01145                         zRes0 = cuddZddIntersect( dd, zPos0, zPos1 );
01146                         if ( zRes0 == NULL )
01147                         {
01148                                 Cudd_RecursiveDerefZdd(dd, zNeg1);
01149                                 Cudd_RecursiveDerefZdd(dd, zPos0);
01150                                 Cudd_RecursiveDerefZdd(dd, zPos1);
01151                                 return NULL;
01152                         }
01153                         cuddRef( zRes0 );
01154 
01155                         zRes1 = cuddZddIntersect( dd, zPos0, zNeg1 );
01156                         if ( zRes1 == NULL )
01157                         {
01158                                 Cudd_RecursiveDerefZdd(dd, zRes0);
01159                                 Cudd_RecursiveDerefZdd(dd, zNeg1);
01160                                 Cudd_RecursiveDerefZdd(dd, zPos0);
01161                                 Cudd_RecursiveDerefZdd(dd, zPos1);
01162                                 return NULL;
01163                         }
01164                         cuddRef( zRes1 );
01165                         Cudd_RecursiveDerefZdd(dd, zNeg1);
01166                         Cudd_RecursiveDerefZdd(dd, zPos0);
01167                         Cudd_RecursiveDerefZdd(dd, zPos1);
01168                         // only zRes0 and zRes1 are refed at this point
01169 
01170                         zRes = cuddZddGetNode( dd, 2*bFR->index, zRes1, zRes0 );
01171                         if ( zRes == NULL ) 
01172                         {
01173                                 Cudd_RecursiveDerefZdd(dd, zRes0);
01174                                 Cudd_RecursiveDerefZdd(dd, zRes1);
01175                                 return NULL;
01176                         }
01177                         cuddDeref( zRes0 );
01178                         cuddDeref( zRes1 );
01179                 }
01180 
01181                 cuddCacheInsert1( dd, extraBddSpaceEquationsPos, bF, zRes );
01182                 return zRes;
01183         }
01184 }

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

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

Synopsis [Performs the recursive steps of Extra_bddSpaceFromFunction.]

Description []

SideEffects []

SeeAlso []

Definition at line 559 of file extraBddAuto.c.

00560 {
00561         DdNode * bRes;
00562         DdNode * bFR, * bGR;
00563 
00564         bFR = Cudd_Regular( bF ); 
00565         bGR = Cudd_Regular( bG ); 
00566         if ( cuddIsConstant(bFR) )
00567         {
00568                 if ( bF == bG )
00569                         return b1;
00570                 else 
00571                         return b0;
00572         }
00573         if ( cuddIsConstant(bGR) )
00574                 return b0;
00575         // both bFunc and bCore are not constants
00576 
00577         // the operation is commutative - normalize the problem
00578         if ( (unsigned)bF > (unsigned)bG )
00579                 return extraBddSpaceFromFunction(dd, bG, bF);
00580 
00581 
00582     if ( bRes = cuddCacheLookup2(dd, extraBddSpaceFromFunction, bF, bG) )
00583         return bRes;
00584         else
00585         {
00586                 DdNode * bF0, * bF1;
00587                 DdNode * bG0, * bG1;
00588                 DdNode * bTemp1, * bTemp2;
00589                 DdNode * bRes0, * bRes1;
00590                 int LevelF, LevelG;
00591                 int index;
00592 
00593                 LevelF = dd->perm[bFR->index];
00594                 LevelG = dd->perm[bGR->index];
00595                 if ( LevelF <= LevelG )
00596                 {
00597                         index = dd->invperm[LevelF];
00598                         if ( bFR != bF )
00599                         {
00600                                 bF0 = Cudd_Not( cuddE(bFR) );
00601                                 bF1 = Cudd_Not( cuddT(bFR) );
00602                         }
00603                         else
00604                         {
00605                                 bF0 = cuddE(bFR);
00606                                 bF1 = cuddT(bFR);
00607                         }
00608                 }
00609                 else
00610                 {
00611                         index = dd->invperm[LevelG];
00612                         bF0 = bF1 = bF;
00613                 }
00614 
00615                 if ( LevelG <= LevelF )
00616                 {
00617                         if ( bGR != bG )
00618                         {
00619                                 bG0 = Cudd_Not( cuddE(bGR) );
00620                                 bG1 = Cudd_Not( cuddT(bGR) );
00621                         }
00622                         else
00623                         {
00624                                 bG0 = cuddE(bGR);
00625                                 bG1 = cuddT(bGR);
00626                         }
00627                 }
00628                 else
00629                         bG0 = bG1 = bG;
00630 
00631                 bTemp1 = extraBddSpaceFromFunction( dd, bF0, bG0 );
00632                 if ( bTemp1 == NULL ) 
00633                         return NULL;
00634                 cuddRef( bTemp1 );
00635 
00636                 bTemp2 = extraBddSpaceFromFunction( dd, bF1, bG1 );
00637                 if ( bTemp2 == NULL ) 
00638                 {
00639                         Cudd_RecursiveDeref( dd, bTemp1 );
00640                         return NULL;
00641                 }
00642                 cuddRef( bTemp2 );
00643 
00644 
00645                 bRes0  = cuddBddAndRecur( dd, bTemp1, bTemp2 );
00646                 if ( bRes0 == NULL )
00647                 {
00648                         Cudd_RecursiveDeref( dd, bTemp1 );
00649                         Cudd_RecursiveDeref( dd, bTemp2 );
00650                         return NULL;
00651                 }
00652                 cuddRef( bRes0 );
00653                 Cudd_RecursiveDeref( dd, bTemp1 );
00654                 Cudd_RecursiveDeref( dd, bTemp2 );
00655 
00656 
00657                 bTemp1  = extraBddSpaceFromFunction( dd, bF0, bG1 );
00658                 if ( bTemp1 == NULL )
00659                 {
00660                         Cudd_RecursiveDeref( dd, bRes0 );
00661                         return NULL;
00662                 }
00663                 cuddRef( bTemp1 );
00664 
00665                 bTemp2  = extraBddSpaceFromFunction( dd, bF1, bG0 );
00666                 if ( bTemp2 == NULL )
00667                 {
00668                         Cudd_RecursiveDeref( dd, bRes0 );
00669                         Cudd_RecursiveDeref( dd, bTemp1 );
00670                         return NULL;
00671                 }
00672                 cuddRef( bTemp2 );
00673 
00674                 bRes1  = cuddBddAndRecur( dd, bTemp1, bTemp2 );
00675                 if ( bRes1 == NULL )
00676                 {
00677                         Cudd_RecursiveDeref( dd, bRes0 );
00678                         Cudd_RecursiveDeref( dd, bTemp1 );
00679                         Cudd_RecursiveDeref( dd, bTemp2 );
00680                         return NULL;
00681                 }
00682                 cuddRef( bRes1 );
00683                 Cudd_RecursiveDeref( dd, bTemp1 );
00684                 Cudd_RecursiveDeref( dd, bTemp2 );
00685 
00686 
00687 
00688                 // consider the case when Res0 and Res1 are the same node 
00689                 if ( bRes0 == bRes1 )
00690                         bRes = bRes1;
00691                 // consider the case when Res1 is complemented 
00692                 else if ( Cudd_IsComplement(bRes1) ) 
00693                 {
00694                         bRes = cuddUniqueInter(dd, index, Cudd_Not(bRes1), Cudd_Not(bRes0));
00695                         if ( bRes == NULL ) 
00696                         {
00697                                 Cudd_RecursiveDeref(dd,bRes0);
00698                                 Cudd_RecursiveDeref(dd,bRes1);
00699                                 return NULL;
00700                         }
00701                         bRes = Cudd_Not(bRes);
00702                 } 
00703                 else 
00704                 {
00705                         bRes = cuddUniqueInter( dd, index, bRes1, bRes0 );
00706                         if ( bRes == NULL ) 
00707                         {
00708                                 Cudd_RecursiveDeref(dd,bRes0);
00709                                 Cudd_RecursiveDeref(dd,bRes1);
00710                                 return NULL;
00711                         }
00712                 }
00713                 cuddDeref( bRes0 );
00714                 cuddDeref( bRes1 );
00715                         
00716                 // insert the result into cache 
00717                 cuddCacheInsert2(dd, extraBddSpaceFromFunction, bF, bG, bRes);
00718                 return bRes;
00719         }
00720 }  /* end of extraBddSpaceFromFunction */

DdNode* extraBddSpaceFromFunctionNeg ( DdManager dd,
DdNode bF 
)

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 866 of file extraBddAuto.c.

00867 {
00868         DdNode * bRes, * bFR;
00869         statLine( dd );
00870 
00871         bFR = Cudd_Regular(bF);
00872         if ( cuddIsConstant(bFR) )
00873                 return b0;
00874 
00875     if ( bRes = cuddCacheLookup1(dd, extraBddSpaceFromFunctionNeg, bF) )
00876         return bRes;
00877         else
00878         {
00879                 DdNode * bF0,   * bF1;
00880                 DdNode * bPos0, * bPos1;
00881                 DdNode * bNeg0, * bNeg1;
00882                 DdNode * bRes0, * bRes1; 
00883 
00884                 if ( bFR != bF ) // bF is complemented 
00885                 {
00886                         bF0 = Cudd_Not( cuddE(bFR) );
00887                         bF1 = Cudd_Not( cuddT(bFR) );
00888                 }
00889                 else
00890                 {
00891                         bF0 = cuddE(bFR);
00892                         bF1 = cuddT(bFR);
00893                 }
00894 
00895 
00896                 bPos0  = extraBddSpaceFromFunctionNeg( dd, bF0 );
00897                 if ( bPos0 == NULL )
00898                         return NULL;
00899                 cuddRef( bPos0 );
00900 
00901                 bPos1  = extraBddSpaceFromFunctionNeg( dd, bF1 );
00902                 if ( bPos1 == NULL )
00903                 {
00904                         Cudd_RecursiveDeref( dd, bPos0 );
00905                         return NULL;
00906                 }
00907                 cuddRef( bPos1 );
00908 
00909                 bRes0  = cuddBddAndRecur( dd, bPos0, bPos1 );
00910                 if ( bRes0 == NULL )
00911                 {
00912                         Cudd_RecursiveDeref( dd, bPos0 );
00913                         Cudd_RecursiveDeref( dd, bPos1 );
00914                         return NULL;
00915                 }
00916                 cuddRef( bRes0 );
00917                 Cudd_RecursiveDeref( dd, bPos0 );
00918                 Cudd_RecursiveDeref( dd, bPos1 );
00919 
00920 
00921                 bNeg0  = extraBddSpaceFromFunctionPos( dd, bF0 );
00922                 if ( bNeg0 == NULL )
00923                 {
00924                         Cudd_RecursiveDeref( dd, bRes0 );
00925                         return NULL;
00926                 }
00927                 cuddRef( bNeg0 );
00928 
00929                 bNeg1  = extraBddSpaceFromFunctionPos( dd, bF1 );
00930                 if ( bNeg1 == NULL )
00931                 {
00932                         Cudd_RecursiveDeref( dd, bRes0 );
00933                         Cudd_RecursiveDeref( dd, bNeg0 );
00934                         return NULL;
00935                 }
00936                 cuddRef( bNeg1 );
00937 
00938                 bRes1  = cuddBddAndRecur( dd, bNeg0, bNeg1 );
00939                 if ( bRes1 == NULL )
00940                 {
00941                         Cudd_RecursiveDeref( dd, bRes0 );
00942                         Cudd_RecursiveDeref( dd, bNeg0 );
00943                         Cudd_RecursiveDeref( dd, bNeg1 );
00944                         return NULL;
00945                 }
00946                 cuddRef( bRes1 );
00947                 Cudd_RecursiveDeref( dd, bNeg0 );
00948                 Cudd_RecursiveDeref( dd, bNeg1 );
00949 
00950 
00951                 // consider the case when Res0 and Res1 are the same node 
00952                 if ( bRes0 == bRes1 )
00953                         bRes = bRes1;
00954                 // consider the case when Res1 is complemented 
00955                 else if ( Cudd_IsComplement(bRes1) ) 
00956                 {
00957                         bRes = cuddUniqueInter( dd, bFR->index, Cudd_Not(bRes1), Cudd_Not(bRes0) );
00958                         if ( bRes == NULL ) 
00959                         {
00960                                 Cudd_RecursiveDeref(dd,bRes0);
00961                                 Cudd_RecursiveDeref(dd,bRes1);
00962                                 return NULL;
00963                         }
00964                         bRes = Cudd_Not(bRes);
00965                 } 
00966                 else 
00967                 {
00968                         bRes = cuddUniqueInter( dd, bFR->index, bRes1, bRes0 );
00969                         if ( bRes == NULL ) 
00970                         {
00971                                 Cudd_RecursiveDeref(dd,bRes0);
00972                                 Cudd_RecursiveDeref(dd,bRes1);
00973                                 return NULL;
00974                         }
00975                 }
00976                 cuddDeref( bRes0 );
00977                 cuddDeref( bRes1 );
00978 
00979                 cuddCacheInsert1( dd, extraBddSpaceFromFunctionNeg, bF, bRes );
00980                 return bRes;
00981         }
00982 }

DdNode* extraBddSpaceFromFunctionPos ( DdManager dd,
DdNode bF 
)

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 735 of file extraBddAuto.c.

00736 {
00737         DdNode * bRes, * bFR;
00738         statLine( dd );
00739 
00740         bFR = Cudd_Regular(bF);
00741         if ( cuddIsConstant(bFR) )
00742                 return b1;
00743 
00744     if ( bRes = cuddCacheLookup1(dd, extraBddSpaceFromFunctionPos, bF) )
00745         return bRes;
00746         else
00747         {
00748                 DdNode * bF0,   * bF1;
00749                 DdNode * bPos0, * bPos1;
00750                 DdNode * bNeg0, * bNeg1;
00751                 DdNode * bRes0, * bRes1; 
00752 
00753                 if ( bFR != bF ) // bF is complemented 
00754                 {
00755                         bF0 = Cudd_Not( cuddE(bFR) );
00756                         bF1 = Cudd_Not( cuddT(bFR) );
00757                 }
00758                 else
00759                 {
00760                         bF0 = cuddE(bFR);
00761                         bF1 = cuddT(bFR);
00762                 }
00763 
00764 
00765                 bPos0  = extraBddSpaceFromFunctionPos( dd, bF0 );
00766                 if ( bPos0 == NULL )
00767                         return NULL;
00768                 cuddRef( bPos0 );
00769 
00770                 bPos1  = extraBddSpaceFromFunctionPos( dd, bF1 );
00771                 if ( bPos1 == NULL )
00772                 {
00773                         Cudd_RecursiveDeref( dd, bPos0 );
00774                         return NULL;
00775                 }
00776                 cuddRef( bPos1 );
00777 
00778                 bRes0  = cuddBddAndRecur( dd, bPos0, bPos1 );
00779                 if ( bRes0 == NULL )
00780                 {
00781                         Cudd_RecursiveDeref( dd, bPos0 );
00782                         Cudd_RecursiveDeref( dd, bPos1 );
00783                         return NULL;
00784                 }
00785                 cuddRef( bRes0 );
00786                 Cudd_RecursiveDeref( dd, bPos0 );
00787                 Cudd_RecursiveDeref( dd, bPos1 );
00788 
00789 
00790                 bNeg0  = extraBddSpaceFromFunctionNeg( dd, bF0 );
00791                 if ( bNeg0 == NULL )
00792                 {
00793                         Cudd_RecursiveDeref( dd, bRes0 );
00794                         return NULL;
00795                 }
00796                 cuddRef( bNeg0 );
00797 
00798                 bNeg1  = extraBddSpaceFromFunctionNeg( dd, bF1 );
00799                 if ( bNeg1 == NULL )
00800                 {
00801                         Cudd_RecursiveDeref( dd, bRes0 );
00802                         Cudd_RecursiveDeref( dd, bNeg0 );
00803                         return NULL;
00804                 }
00805                 cuddRef( bNeg1 );
00806 
00807                 bRes1  = cuddBddAndRecur( dd, bNeg0, bNeg1 );
00808                 if ( bRes1 == NULL )
00809                 {
00810                         Cudd_RecursiveDeref( dd, bRes0 );
00811                         Cudd_RecursiveDeref( dd, bNeg0 );
00812                         Cudd_RecursiveDeref( dd, bNeg1 );
00813                         return NULL;
00814                 }
00815                 cuddRef( bRes1 );
00816                 Cudd_RecursiveDeref( dd, bNeg0 );
00817                 Cudd_RecursiveDeref( dd, bNeg1 );
00818 
00819 
00820                 // consider the case when Res0 and Res1 are the same node 
00821                 if ( bRes0 == bRes1 )
00822                         bRes = bRes1;
00823                 // consider the case when Res1 is complemented 
00824                 else if ( Cudd_IsComplement(bRes1) ) 
00825                 {
00826                         bRes = cuddUniqueInter( dd, bFR->index, Cudd_Not(bRes1), Cudd_Not(bRes0) );
00827                         if ( bRes == NULL ) 
00828                         {
00829                                 Cudd_RecursiveDeref(dd,bRes0);
00830                                 Cudd_RecursiveDeref(dd,bRes1);
00831                                 return NULL;
00832                         }
00833                         bRes = Cudd_Not(bRes);
00834                 } 
00835                 else 
00836                 {
00837                         bRes = cuddUniqueInter( dd, bFR->index, bRes1, bRes0 );
00838                         if ( bRes == NULL ) 
00839                         {
00840                                 Cudd_RecursiveDeref(dd,bRes0);
00841                                 Cudd_RecursiveDeref(dd,bRes1);
00842                                 return NULL;
00843                         }
00844                 }
00845                 cuddDeref( bRes0 );
00846                 cuddDeref( bRes1 );
00847 
00848                 cuddCacheInsert1( dd, extraBddSpaceFromFunctionPos, bF, bRes );
00849                 return bRes;
00850         }
00851 }

DdNode* extraBddSpaceFromMatrixNeg ( DdManager dd,
DdNode zA 
)

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 1448 of file extraBddAuto.c.

01449 {
01450         DdNode * bRes;
01451         statLine( dd );
01452 
01453         if ( zA == z0 )
01454                 return b1;
01455         if ( zA == z1 )
01456                 return b0;
01457 
01458     if ( bRes = cuddCacheLookup1(dd, extraBddSpaceFromMatrixNeg, zA) )
01459         return bRes;
01460         else
01461         {
01462                 DdNode * bP0, * bP1;
01463                 DdNode * bN0, * bN1;
01464                 DdNode * bRes0, * bRes1; 
01465 
01466                 bP0  = extraBddSpaceFromMatrixNeg( dd, cuddE(zA) );
01467                 if ( bP0 == NULL )
01468                         return NULL;
01469                 cuddRef( bP0 );
01470 
01471                 bP1  = extraBddSpaceFromMatrixNeg( dd, cuddT(zA) );
01472                 if ( bP1 == NULL )
01473                 {
01474                         Cudd_RecursiveDeref( dd, bP0 );
01475                         return NULL;
01476                 }
01477                 cuddRef( bP1 );
01478 
01479                 bRes0  = cuddBddAndRecur( dd, bP0, bP1 );
01480                 if ( bRes0 == NULL )
01481                 {
01482                         Cudd_RecursiveDeref( dd, bP0 );
01483                         Cudd_RecursiveDeref( dd, bP1 );
01484                         return NULL;
01485                 }
01486                 cuddRef( bRes0 );
01487                 Cudd_RecursiveDeref( dd, bP0 );
01488                 Cudd_RecursiveDeref( dd, bP1 );
01489 
01490 
01491                 bN0  = extraBddSpaceFromMatrixNeg( dd, cuddE(zA) );
01492                 if ( bN0 == NULL )
01493                 {
01494                         Cudd_RecursiveDeref( dd, bRes0 );
01495                         return NULL;
01496                 }
01497                 cuddRef( bN0 );
01498 
01499                 bN1  = extraBddSpaceFromMatrixPos( dd, cuddT(zA) );
01500                 if ( bN1 == NULL )
01501                 {
01502                         Cudd_RecursiveDeref( dd, bRes0 );
01503                         Cudd_RecursiveDeref( dd, bN0 );
01504                         return NULL;
01505                 }
01506                 cuddRef( bN1 );
01507 
01508                 bRes1  = cuddBddAndRecur( dd, bN0, bN1 );
01509                 if ( bRes1 == NULL )
01510                 {
01511                         Cudd_RecursiveDeref( dd, bRes0 );
01512                         Cudd_RecursiveDeref( dd, bN0 );
01513                         Cudd_RecursiveDeref( dd, bN1 );
01514                         return NULL;
01515                 }
01516                 cuddRef( bRes1 );
01517                 Cudd_RecursiveDeref( dd, bN0 );
01518                 Cudd_RecursiveDeref( dd, bN1 );
01519 
01520 
01521                 // consider the case when Res0 and Res1 are the same node 
01522                 if ( bRes0 == bRes1 )
01523                         bRes = bRes1;
01524                 // consider the case when Res1 is complemented 
01525                 else if ( Cudd_IsComplement(bRes1) ) 
01526                 {
01527                         bRes = cuddUniqueInter( dd, zA->index/2, Cudd_Not(bRes1), Cudd_Not(bRes0) );
01528                         if ( bRes == NULL ) 
01529                         {
01530                                 Cudd_RecursiveDeref(dd,bRes0);
01531                                 Cudd_RecursiveDeref(dd,bRes1);
01532                                 return NULL;
01533                         }
01534                         bRes = Cudd_Not(bRes);
01535                 } 
01536                 else 
01537                 {
01538                         bRes = cuddUniqueInter( dd, zA->index/2, bRes1, bRes0 );
01539                         if ( bRes == NULL ) 
01540                         {
01541                                 Cudd_RecursiveDeref(dd,bRes0);
01542                                 Cudd_RecursiveDeref(dd,bRes1);
01543                                 return NULL;
01544                         }
01545                 }
01546                 cuddDeref( bRes0 );
01547                 cuddDeref( bRes1 );
01548 
01549                 cuddCacheInsert1( dd, extraBddSpaceFromMatrixNeg, zA, bRes );
01550                 return bRes;
01551         }
01552 }

DdNode* extraBddSpaceFromMatrixPos ( DdManager dd,
DdNode zA 
)

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 1330 of file extraBddAuto.c.

01331 {
01332         DdNode * bRes;
01333         statLine( dd );
01334 
01335         if ( zA == z0 )
01336                 return b1;
01337         if ( zA == z1 )
01338                 return b1;
01339 
01340     if ( bRes = cuddCacheLookup1(dd, extraBddSpaceFromMatrixPos, zA) )
01341         return bRes;
01342         else
01343         {
01344                 DdNode * bP0, * bP1;
01345                 DdNode * bN0, * bN1;
01346                 DdNode * bRes0, * bRes1; 
01347 
01348                 bP0  = extraBddSpaceFromMatrixPos( dd, cuddE(zA) );
01349                 if ( bP0 == NULL )
01350                         return NULL;
01351                 cuddRef( bP0 );
01352 
01353                 bP1  = extraBddSpaceFromMatrixPos( dd, cuddT(zA) );
01354                 if ( bP1 == NULL )
01355                 {
01356                         Cudd_RecursiveDeref( dd, bP0 );
01357                         return NULL;
01358                 }
01359                 cuddRef( bP1 );
01360 
01361                 bRes0  = cuddBddAndRecur( dd, bP0, bP1 );
01362                 if ( bRes0 == NULL )
01363                 {
01364                         Cudd_RecursiveDeref( dd, bP0 );
01365                         Cudd_RecursiveDeref( dd, bP1 );
01366                         return NULL;
01367                 }
01368                 cuddRef( bRes0 );
01369                 Cudd_RecursiveDeref( dd, bP0 );
01370                 Cudd_RecursiveDeref( dd, bP1 );
01371 
01372 
01373                 bN0  = extraBddSpaceFromMatrixPos( dd, cuddE(zA) );
01374                 if ( bN0 == NULL )
01375                 {
01376                         Cudd_RecursiveDeref( dd, bRes0 );
01377                         return NULL;
01378                 }
01379                 cuddRef( bN0 );
01380 
01381                 bN1  = extraBddSpaceFromMatrixNeg( dd, cuddT(zA) );
01382                 if ( bN1 == NULL )
01383                 {
01384                         Cudd_RecursiveDeref( dd, bRes0 );
01385                         Cudd_RecursiveDeref( dd, bN0 );
01386                         return NULL;
01387                 }
01388                 cuddRef( bN1 );
01389 
01390                 bRes1  = cuddBddAndRecur( dd, bN0, bN1 );
01391                 if ( bRes1 == NULL )
01392                 {
01393                         Cudd_RecursiveDeref( dd, bRes0 );
01394                         Cudd_RecursiveDeref( dd, bN0 );
01395                         Cudd_RecursiveDeref( dd, bN1 );
01396                         return NULL;
01397                 }
01398                 cuddRef( bRes1 );
01399                 Cudd_RecursiveDeref( dd, bN0 );
01400                 Cudd_RecursiveDeref( dd, bN1 );
01401 
01402 
01403                 // consider the case when Res0 and Res1 are the same node 
01404                 if ( bRes0 == bRes1 )
01405                         bRes = bRes1;
01406                 // consider the case when Res1 is complemented 
01407                 else if ( Cudd_IsComplement(bRes1) ) 
01408                 {
01409                         bRes = cuddUniqueInter( dd, zA->index/2, Cudd_Not(bRes1), Cudd_Not(bRes0) );
01410                         if ( bRes == NULL ) 
01411                         {
01412                                 Cudd_RecursiveDeref(dd,bRes0);
01413                                 Cudd_RecursiveDeref(dd,bRes1);
01414                                 return NULL;
01415                         }
01416                         bRes = Cudd_Not(bRes);
01417                 } 
01418                 else 
01419                 {
01420                         bRes = cuddUniqueInter( dd, zA->index/2, bRes1, bRes0 );
01421                         if ( bRes == NULL ) 
01422                         {
01423                                 Cudd_RecursiveDeref(dd,bRes0);
01424                                 Cudd_RecursiveDeref(dd,bRes1);
01425                                 return NULL;
01426                         }
01427                 }
01428                 cuddDeref( bRes0 );
01429                 cuddDeref( bRes1 );
01430 
01431                 cuddCacheInsert1( dd, extraBddSpaceFromMatrixPos, zA, bRes );
01432                 return bRes;
01433         }
01434 }

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

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 1068 of file extraBddMisc.c.

01074 {
01075     if ( (zC->index & 1) == 0 ) 
01076     { /* the top variable is present in positive polarity and maybe in negative */
01077 
01078         DdNode *Temp = cuddE( zC );
01079         *zC1  = cuddT( zC );
01080         if ( cuddIZ(dd,Temp->index) == cuddIZ(dd,zC->index) + 1 )
01081         {   /* Temp is not a terminal node 
01082              * top var is present in negative polarity */
01083             *zC2 = cuddE( Temp );
01084             *zC0 = cuddT( Temp );
01085         }
01086         else
01087         {   /* top var is not present in negative polarity */
01088             *zC2 = Temp;
01089             *zC0 = dd->zero;
01090         }
01091     }
01092     else 
01093     { /* the top variable is present only in negative */
01094         *zC1 = dd->zero;
01095         *zC2 = cuddE( zC );
01096         *zC0 = cuddT( zC );
01097     }
01098 } /* extraDecomposeCover */

DdNode* extraZddGetSingletons ( DdManager dd,
DdNode bVars 
)

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 998 of file extraBddSymm.c.

01001 {
01002     DdNode * zRes;
01003 
01004     if ( bVars == b1 )
01005 //    if ( bVars == b0 )  // bug fixed by Jin Zhang, Jan 23, 2004
01006         return z1;
01007 
01008     if ( zRes = cuddCacheLookup1Zdd(dd, extraZddGetSingletons, bVars) )
01009         return zRes;
01010     else
01011     {
01012         DdNode * zTemp, * zPlus;          
01013 
01014         // solve subproblem
01015         zRes = extraZddGetSingletons( dd, cuddT(bVars) );
01016         if ( zRes == NULL ) 
01017             return NULL;
01018         cuddRef( zRes );
01019         
01020         zPlus = cuddZddGetNode( dd, 2*bVars->index, z1, z0 );
01021         if ( zPlus == NULL ) 
01022         {
01023             Cudd_RecursiveDerefZdd( dd, zRes );
01024             return NULL;
01025         }
01026         cuddRef( zPlus );
01027 
01028         // add these to the result
01029         zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
01030         if ( zRes == NULL )
01031         {
01032             Cudd_RecursiveDerefZdd( dd, zTemp );
01033             Cudd_RecursiveDerefZdd( dd, zPlus );
01034             return NULL;
01035         }
01036         cuddRef( zRes );
01037         Cudd_RecursiveDerefZdd( dd, zTemp );
01038         Cudd_RecursiveDerefZdd( dd, zPlus );
01039         cuddDeref( zRes );
01040 
01041         cuddCacheInsert1( dd, extraZddGetSingletons, bVars, zRes );
01042         return zRes;
01043     }
01044 }   /* end of extraZddGetSingletons */

DdNode* extraZddGetSingletonsBoth ( DdManager dd,
DdNode bVars 
)

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 567 of file extraBddUnate.c.

00570 {
00571     DdNode * zRes;
00572 
00573     if ( bVars == b1 )
00574         return z1;
00575 
00576     if ( zRes = cuddCacheLookup1Zdd(dd, extraZddGetSingletonsBoth, bVars) )
00577         return zRes;
00578     else
00579     {
00580         DdNode * zTemp, * zPlus;          
00581 
00582         // solve subproblem
00583         zRes = extraZddGetSingletonsBoth( dd, cuddT(bVars) );
00584         if ( zRes == NULL ) 
00585             return NULL;
00586         cuddRef( zRes );
00587 
00588         
00589         // create the negative singleton
00590         zPlus = cuddZddGetNode( dd, 2*bVars->index+1, z1, z0 );
00591         if ( zPlus == NULL ) 
00592         {
00593             Cudd_RecursiveDerefZdd( dd, zRes );
00594             return NULL;
00595         }
00596         cuddRef( zPlus );
00597 
00598         // add these to the result
00599         zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
00600         if ( zRes == NULL )
00601         {
00602             Cudd_RecursiveDerefZdd( dd, zTemp );
00603             Cudd_RecursiveDerefZdd( dd, zPlus );
00604             return NULL;
00605         }
00606         cuddRef( zRes );
00607         Cudd_RecursiveDerefZdd( dd, zTemp );
00608         Cudd_RecursiveDerefZdd( dd, zPlus );
00609         
00610 
00611         // create the positive singleton
00612         zPlus = cuddZddGetNode( dd, 2*bVars->index, z1, z0 );
00613         if ( zPlus == NULL ) 
00614         {
00615             Cudd_RecursiveDerefZdd( dd, zRes );
00616             return NULL;
00617         }
00618         cuddRef( zPlus );
00619 
00620         // add these to the result
00621         zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
00622         if ( zRes == NULL )
00623         {
00624             Cudd_RecursiveDerefZdd( dd, zTemp );
00625             Cudd_RecursiveDerefZdd( dd, zPlus );
00626             return NULL;
00627         }
00628         cuddRef( zRes );
00629         Cudd_RecursiveDerefZdd( dd, zTemp );
00630         Cudd_RecursiveDerefZdd( dd, zPlus );
00631 
00632         cuddDeref( zRes );
00633         cuddCacheInsert1( dd, extraZddGetSingletonsBoth, bVars, zRes );
00634         return zRes;
00635     }
00636 }   /* end of extraZddGetSingletonsBoth */

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

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 801 of file extraBddSymm.c.

00806 {
00807     DdNode * zRes;
00808     DdNode * bFR = Cudd_Regular(bF); 
00809     DdNode * bGR = Cudd_Regular(bG); 
00810 
00811     if ( cuddIsConstant(bFR) && cuddIsConstant(bGR) )
00812     {
00813         if ( bF == bG )
00814             return extraZddGetSingletons( dd, bVars );
00815         else 
00816             return z0;
00817     }
00818     assert( bVars != b1 );
00819 
00820     if ( zRes = cuddCacheLookupZdd(dd, DD_GET_SYMM_VARS_TAG, bF, bG, bVars) )
00821         return zRes;
00822     else
00823     {
00824         DdNode * zRes0, * zRes1;             
00825         DdNode * zPlus, * zTemp;
00826         DdNode * bF0, * bF1;             
00827         DdNode * bG0, * bG1;             
00828         DdNode * bVarsNew;
00829     
00830         int LevelF = cuddI(dd,bFR->index);
00831         int LevelG = cuddI(dd,bGR->index);
00832         int LevelFG;
00833 
00834         if ( LevelF < LevelG )
00835             LevelFG = LevelF;
00836         else
00837             LevelFG = LevelG;
00838 
00839         // at least one of the arguments is not a constant
00840         assert( LevelFG < dd->size );
00841 
00842         // every variable in bF and bG should be also in bVars, therefore LevelFG cannot be above LevelV
00843         // if LevelFG is below LevelV, scroll through the vars in bVars to the same level as LevelFG
00844         for ( bVarsNew = bVars; LevelFG > dd->perm[bVarsNew->index]; bVarsNew = cuddT(bVarsNew) );
00845         assert( LevelFG == dd->perm[bVarsNew->index] );
00846 
00847         // cofactor the functions
00848         if ( LevelF == LevelFG )
00849         {
00850             if ( bFR != bF ) // bF is complemented 
00851             {
00852                 bF0 = Cudd_Not( cuddE(bFR) );
00853                 bF1 = Cudd_Not( cuddT(bFR) );
00854             }
00855             else
00856             {
00857                 bF0 = cuddE(bFR);
00858                 bF1 = cuddT(bFR);
00859             }
00860         }
00861         else 
00862             bF0 = bF1 = bF;
00863 
00864         if ( LevelG == LevelFG )
00865         {
00866             if ( bGR != bG ) // bG is complemented 
00867             {
00868                 bG0 = Cudd_Not( cuddE(bGR) );
00869                 bG1 = Cudd_Not( cuddT(bGR) );
00870             }
00871             else
00872             {
00873                 bG0 = cuddE(bGR);
00874                 bG1 = cuddT(bGR);
00875             }
00876         }
00877         else 
00878             bG0 = bG1 = bG;
00879 
00880         // solve subproblems
00881         zRes0 = extraZddGetSymmetricVars( dd, bF0, bG0, cuddT(bVarsNew) );
00882         if ( zRes0 == NULL ) 
00883             return NULL;
00884         cuddRef( zRes0 );
00885 
00886         // if there is not symmetries in the negative cofactor
00887         // there is no need to test the positive cofactor
00888         if ( zRes0 == z0 )
00889             zRes = zRes0;  // zRes takes reference
00890         else
00891         {
00892             zRes1 = extraZddGetSymmetricVars( dd, bF1, bG1, cuddT(bVarsNew) );
00893             if ( zRes1 == NULL ) 
00894             {
00895                 Cudd_RecursiveDerefZdd( dd, zRes0 );
00896                 return NULL;
00897             }
00898             cuddRef( zRes1 );
00899 
00900             // only those variables should belong to the resulting set 
00901             // for which the property is true for both cofactors
00902             zRes = cuddZddIntersect( dd, zRes0, zRes1 );
00903             if ( zRes == NULL )
00904             {
00905                 Cudd_RecursiveDerefZdd( dd, zRes0 );
00906                 Cudd_RecursiveDerefZdd( dd, zRes1 );
00907                 return NULL;
00908             }
00909             cuddRef( zRes );
00910             Cudd_RecursiveDerefZdd( dd, zRes0 );
00911             Cudd_RecursiveDerefZdd( dd, zRes1 );
00912         }
00913 
00914         // add one more singleton if the property is true for this variable
00915         if ( bF0 == bG1 )
00916         {
00917             zPlus = cuddZddGetNode( dd, 2*bVarsNew->index, z1, z0 );
00918             if ( zPlus == NULL ) 
00919             {
00920                 Cudd_RecursiveDerefZdd( dd, zRes );
00921                 return NULL;
00922             }
00923             cuddRef( zPlus );
00924 
00925             // add these variable pairs to the result
00926             zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
00927             if ( zRes == NULL )
00928             {
00929                 Cudd_RecursiveDerefZdd( dd, zTemp );
00930                 Cudd_RecursiveDerefZdd( dd, zPlus );
00931                 return NULL;
00932             }
00933             cuddRef( zRes );
00934             Cudd_RecursiveDerefZdd( dd, zTemp );
00935             Cudd_RecursiveDerefZdd( dd, zPlus );
00936         }
00937 
00938         if ( bF == bG && bVars != bVarsNew )
00939         { 
00940             // if the functions are equal, so are their cofactors
00941             // add those variables from V that are above F and G 
00942 
00943             DdNode * bVarsExtra;
00944 
00945             assert( LevelFG > dd->perm[bVars->index] );
00946 
00947             // create the BDD of the extra variables
00948             bVarsExtra = cuddBddExistAbstractRecur( dd, bVars, bVarsNew );
00949             if ( bVarsExtra == NULL )
00950             {
00951                 Cudd_RecursiveDerefZdd( dd, zRes );
00952                 return NULL;
00953             }
00954             cuddRef( bVarsExtra );
00955 
00956             zPlus = extraZddGetSingletons( dd, bVarsExtra );
00957             if ( zPlus == NULL )
00958             {
00959                 Cudd_RecursiveDeref( dd, bVarsExtra );
00960                 Cudd_RecursiveDerefZdd( dd, zRes );
00961                 return NULL;
00962             }
00963             cuddRef( zPlus );
00964             Cudd_RecursiveDeref( dd, bVarsExtra );
00965 
00966             // add these to the result
00967             zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
00968             if ( zRes == NULL )
00969             {
00970                 Cudd_RecursiveDerefZdd( dd, zTemp );
00971                 Cudd_RecursiveDerefZdd( dd, zPlus );
00972                 return NULL;
00973             }
00974             cuddRef( zRes );
00975             Cudd_RecursiveDerefZdd( dd, zTemp );
00976             Cudd_RecursiveDerefZdd( dd, zPlus );
00977         }
00978         cuddDeref( zRes );
00979 
00980         cuddCacheInsert( dd, DD_GET_SYMM_VARS_TAG, bF, bG, bVars, zRes );
00981         return zRes;
00982     }
00983 }   /* end of extraZddGetSymmetricVars */

DdNode* extraZddSelectOneSubset ( DdManager dd,
DdNode zS 
)

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

Synopsis [Performs the recursive step of Extra_zddSelectOneSubset.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 1416 of file extraBddSymm.c.

01421 {
01422     DdNode * zRes;
01423 
01424     if ( zS == z0 )    return z0;
01425     if ( zS == z1 )    return z1;
01426     
01427     // check cache
01428     if ( zRes = cuddCacheLookup1Zdd( dd, extraZddSelectOneSubset, zS ) )
01429         return zRes;
01430     else
01431     {
01432         DdNode * zS0, * zS1, * zTemp; 
01433 
01434         zS0 = cuddE(zS);
01435         zS1 = cuddT(zS);
01436 
01437         if ( zS0 != z0 )
01438         {
01439             zRes = extraZddSelectOneSubset( dd, zS0 );
01440             if ( zRes == NULL )
01441                 return NULL;
01442         }
01443         else // if ( zS0 == z0 )
01444         {
01445             assert( zS1 != z0 );
01446             zRes = extraZddSelectOneSubset( dd, zS1 );
01447             if ( zRes == NULL )
01448                 return NULL;
01449             cuddRef( zRes );
01450 
01451             zRes = cuddZddGetNode( dd, zS->index, zTemp = zRes, z0 );
01452             if ( zRes == NULL ) 
01453             {
01454                 Cudd_RecursiveDerefZdd( dd, zTemp );
01455                 return NULL;
01456             }
01457             cuddDeref( zTemp );
01458         }
01459 
01460         // insert the result into cache
01461         cuddCacheInsert1( dd, extraZddSelectOneSubset, zS, zRes );
01462         return zRes;
01463     }       
01464 } /* end of extraZddSelectOneSubset */

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

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 577 of file extraBddSymm.c.

00581 {
00582     DdNode * zRes;
00583     DdNode * bFR = Cudd_Regular(bFunc); 
00584 
00585     if ( cuddIsConstant(bFR) )
00586     {
00587         int nVars, i;
00588 
00589         // determine how many vars are in the bVars
00590         nVars = Extra_bddSuppSize( dd, bVars );
00591         if ( nVars < 2 )
00592             return z0;
00593         else
00594         {
00595             DdNode * bVarsK;
00596 
00597             // create the BDD bVarsK corresponding to K = 2;
00598             bVarsK = bVars;
00599             for ( i = 0; i < nVars-2; i++ )
00600                 bVarsK = cuddT( bVarsK );
00601             return extraZddTuplesFromBdd( dd, bVarsK, bVars );
00602         }
00603     }
00604     assert( bVars != b1 );
00605 
00606     if ( zRes = cuddCacheLookup2Zdd(dd, extraZddSymmPairsCompute, bFunc, bVars) )
00607         return zRes;
00608     else
00609     {
00610         DdNode * zRes0, * zRes1;
00611         DdNode * zTemp, * zPlus, * zSymmVars;             
00612         DdNode * bF0, * bF1;             
00613         DdNode * bVarsNew;
00614         int nVarsExtra;
00615         int LevelF;
00616 
00617         // every variable in bF should be also in bVars, therefore LevelF cannot be above LevelV
00618         // if LevelF is below LevelV, scroll through the vars in bVars to the same level as F
00619         // count how many extra vars are there in bVars
00620         nVarsExtra = 0;
00621         LevelF = dd->perm[bFR->index];
00622         for ( bVarsNew = bVars; LevelF > dd->perm[bVarsNew->index]; bVarsNew = cuddT(bVarsNew) )
00623             nVarsExtra++; 
00624         // the indexes (level) of variables should be synchronized now
00625         assert( bFR->index == bVarsNew->index );
00626 
00627         // cofactor the function
00628         if ( bFR != bFunc ) // bFunc is complemented 
00629         {
00630             bF0 = Cudd_Not( cuddE(bFR) );
00631             bF1 = Cudd_Not( cuddT(bFR) );
00632         }
00633         else
00634         {
00635             bF0 = cuddE(bFR);
00636             bF1 = cuddT(bFR);
00637         }
00638 
00639         // solve subproblems
00640         zRes0 = extraZddSymmPairsCompute( dd, bF0, cuddT(bVarsNew) );
00641         if ( zRes0 == NULL )
00642             return NULL;
00643         cuddRef( zRes0 );
00644 
00645         // if there is no symmetries in the negative cofactor
00646         // there is no need to test the positive cofactor
00647         if ( zRes0 == z0 )
00648             zRes = zRes0;  // zRes takes reference
00649         else
00650         {
00651             zRes1 = extraZddSymmPairsCompute( dd, bF1, cuddT(bVarsNew) );
00652             if ( zRes1 == NULL )
00653             {
00654                 Cudd_RecursiveDerefZdd( dd, zRes0 );
00655                 return NULL;
00656             }
00657             cuddRef( zRes1 );
00658 
00659             // only those variables are pair-wise symmetric 
00660             // that are pair-wise symmetric in both cofactors
00661             // therefore, intersect the solutions
00662             zRes = cuddZddIntersect( dd, zRes0, zRes1 );
00663             if ( zRes == NULL )
00664             {
00665                 Cudd_RecursiveDerefZdd( dd, zRes0 );
00666                 Cudd_RecursiveDerefZdd( dd, zRes1 );
00667                 return NULL;
00668             }
00669             cuddRef( zRes );
00670             Cudd_RecursiveDerefZdd( dd, zRes0 );
00671             Cudd_RecursiveDerefZdd( dd, zRes1 );
00672         }
00673 
00674         // consider the current top-most variable and find all the vars
00675         // that are pairwise symmetric with it
00676         // these variables are returned as a set of ZDD singletons
00677         zSymmVars = extraZddGetSymmetricVars( dd, bF1, bF0, cuddT(bVarsNew) );
00678         if ( zSymmVars == NULL )
00679         {
00680             Cudd_RecursiveDerefZdd( dd, zRes );
00681             return NULL;
00682         }
00683         cuddRef( zSymmVars );
00684 
00685         // attach the topmost variable to the set, to get the variable pairs
00686         // use the positive polarity ZDD variable for the purpose
00687 
00688         // there is no need to do so, if zSymmVars is empty
00689         if ( zSymmVars == z0 )
00690             Cudd_RecursiveDerefZdd( dd, zSymmVars );
00691         else
00692         {
00693             zPlus = cuddZddGetNode( dd, 2*bFR->index, zSymmVars, z0 );
00694             if ( zPlus == NULL ) 
00695             {
00696                 Cudd_RecursiveDerefZdd( dd, zRes );
00697                 Cudd_RecursiveDerefZdd( dd, zSymmVars );
00698                 return NULL;
00699             }
00700             cuddRef( zPlus );
00701             cuddDeref( zSymmVars );
00702 
00703             // add these variable pairs to the result
00704             zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
00705             if ( zRes == NULL )
00706             {
00707                 Cudd_RecursiveDerefZdd( dd, zTemp );
00708                 Cudd_RecursiveDerefZdd( dd, zPlus );
00709                 return NULL;
00710             }
00711             cuddRef( zRes );
00712             Cudd_RecursiveDerefZdd( dd, zTemp );
00713             Cudd_RecursiveDerefZdd( dd, zPlus );
00714         }
00715 
00716         // only zRes is referenced at this point
00717 
00718         // if we skipped some variables, these variables cannot be symmetric with
00719         // any variables that are currently in the support of bF, but they can be 
00720         // symmetric with the variables that are in bVars but not in the support of bF
00721         if ( nVarsExtra )
00722         {
00723             // it is possible to improve this step:
00724             // (1) there is no need to enter here, if nVarsExtra < 2
00725 
00726             // create the set of topmost nVarsExtra in bVars
00727             DdNode * bVarsExtra;
00728             int nVars;
00729 
00730             // remove from bVars all the variable that are in the support of bFunc
00731             bVarsExtra = extraBddReduceVarSet( dd, bVars, bFunc );  
00732             if ( bVarsExtra == NULL )
00733             {
00734                 Cudd_RecursiveDerefZdd( dd, zRes );
00735                 return NULL;
00736             }
00737             cuddRef( bVarsExtra );
00738 
00739             // determine how many vars are in the bVarsExtra
00740             nVars = Extra_bddSuppSize( dd, bVarsExtra );
00741             if ( nVars < 2 )
00742             {
00743                 Cudd_RecursiveDeref( dd, bVarsExtra );
00744             }
00745             else
00746             {
00747                 int i;
00748                 DdNode * bVarsK;
00749 
00750                 // create the BDD bVarsK corresponding to K = 2;
00751                 bVarsK = bVarsExtra;
00752                 for ( i = 0; i < nVars-2; i++ )
00753                     bVarsK = cuddT( bVarsK );
00754 
00755                 // create the 2 variable tuples
00756                 zPlus = extraZddTuplesFromBdd( dd, bVarsK, bVarsExtra );
00757                 if ( zPlus == NULL )
00758                 {
00759                     Cudd_RecursiveDeref( dd, bVarsExtra );
00760                     Cudd_RecursiveDerefZdd( dd, zRes );
00761                     return NULL;
00762                 }
00763                 cuddRef( zPlus );
00764                 Cudd_RecursiveDeref( dd, bVarsExtra );
00765 
00766                 // add these to the result
00767                 zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
00768                 if ( zRes == NULL )
00769                 {
00770                     Cudd_RecursiveDerefZdd( dd, zTemp );
00771                     Cudd_RecursiveDerefZdd( dd, zPlus );
00772                     return NULL;
00773                 }
00774                 cuddRef( zRes );
00775                 Cudd_RecursiveDerefZdd( dd, zTemp );
00776                 Cudd_RecursiveDerefZdd( dd, zPlus );
00777             }
00778         }
00779         cuddDeref( zRes );
00780 
00781 
00782         /* insert the result into cache */
00783         cuddCacheInsert2(dd, extraZddSymmPairsCompute, bFunc, bVars, zRes);
00784         return zRes;
00785     }
00786 } /* end of extraZddSymmPairsCompute */

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

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 1338 of file extraBddSymm.c.

01342 {
01343     DdNode *zRes, *zRes0, *zRes1;
01344     statLine(dd); 
01345 
01346     /* terminal cases */
01347 /*  if ( k < 0 || k > n )
01348  *      return dd->zero;
01349  *  if ( n == 0 )
01350  *      return dd->one; 
01351  */
01352     if ( cuddI( dd, bVarsK->index ) < cuddI( dd, bVarsN->index ) )
01353         return z0;
01354     if ( bVarsN == b1 )
01355         return z1;
01356 
01357     /* check cache */
01358     zRes = cuddCacheLookup2Zdd(dd, extraZddTuplesFromBdd, bVarsK, bVarsN);
01359     if (zRes)
01360         return(zRes);
01361 
01362     /* ZDD in which this variable is 0 */
01363 /*  zRes0 = extraZddTuplesFromBdd( dd, k,     n-1 ); */
01364     zRes0 = extraZddTuplesFromBdd( dd, bVarsK, cuddT(bVarsN) );
01365     if ( zRes0 == NULL ) 
01366         return NULL;
01367     cuddRef( zRes0 );
01368 
01369     /* ZDD in which this variable is 1 */
01370 /*  zRes1 = extraZddTuplesFromBdd( dd, k-1,          n-1 ); */
01371     if ( bVarsK == b1 )
01372     {
01373         zRes1 = z0;
01374         cuddRef( zRes1 );
01375     }
01376     else
01377     {
01378         zRes1 = extraZddTuplesFromBdd( dd, cuddT(bVarsK), cuddT(bVarsN) );
01379         if ( zRes1 == NULL ) 
01380         {
01381             Cudd_RecursiveDerefZdd( dd, zRes0 );
01382             return NULL;
01383         }
01384         cuddRef( zRes1 );
01385     }
01386 
01387     /* compose Res0 and Res1 with the given ZDD variable */
01388     zRes = cuddZddGetNode( dd, 2*bVarsN->index, zRes1, zRes0 );
01389     if ( zRes == NULL ) 
01390     {
01391         Cudd_RecursiveDerefZdd( dd, zRes0 );
01392         Cudd_RecursiveDerefZdd( dd, zRes1 );
01393         return NULL;
01394     }
01395     cuddDeref( zRes0 );
01396     cuddDeref( zRes1 );
01397 
01398     /* insert the result into cache */
01399     cuddCacheInsert2(dd, extraZddTuplesFromBdd, bVarsK, bVarsN, zRes);
01400     return zRes;
01401 
01402 } /* end of extraZddTuplesFromBdd */

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

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 382 of file extraBddUnate.c.

00386 {
00387     DdNode * zRes;
00388     DdNode * bFR = Cudd_Regular(bFunc); 
00389 
00390     if ( cuddIsConstant(bFR) )
00391     {
00392         if ( cuddIsConstant(bVars) )
00393             return z0;
00394         return extraZddGetSingletonsBoth( dd, bVars );
00395     }
00396     assert( bVars != b1 );
00397 
00398     if ( zRes = cuddCacheLookup2Zdd(dd, extraZddUnateInfoCompute, bFunc, bVars) )
00399         return zRes;
00400     else
00401     {
00402         DdNode * zRes0, * zRes1;
00403         DdNode * zTemp, * zPlus;             
00404         DdNode * bF0, * bF1;             
00405         DdNode * bVarsNew;
00406         int nVarsExtra;
00407         int LevelF;
00408         int AddVar;
00409 
00410         // every variable in bF should be also in bVars, therefore LevelF cannot be above LevelV
00411         // if LevelF is below LevelV, scroll through the vars in bVars to the same level as F
00412         // count how many extra vars are there in bVars
00413         nVarsExtra = 0;
00414         LevelF = dd->perm[bFR->index];
00415         for ( bVarsNew = bVars; LevelF > dd->perm[bVarsNew->index]; bVarsNew = cuddT(bVarsNew) )
00416             nVarsExtra++; 
00417         // the indexes (level) of variables should be synchronized now
00418         assert( bFR->index == bVarsNew->index );
00419 
00420         // cofactor the function
00421         if ( bFR != bFunc ) // bFunc is complemented 
00422         {
00423             bF0 = Cudd_Not( cuddE(bFR) );
00424             bF1 = Cudd_Not( cuddT(bFR) );
00425         }
00426         else
00427         {
00428             bF0 = cuddE(bFR);
00429             bF1 = cuddT(bFR);
00430         }
00431 
00432         // solve subproblems
00433         zRes0 = extraZddUnateInfoCompute( dd, bF0, cuddT(bVarsNew) );
00434         if ( zRes0 == NULL )
00435             return NULL;
00436         cuddRef( zRes0 );
00437 
00438         // if there is no symmetries in the negative cofactor
00439         // there is no need to test the positive cofactor
00440         if ( zRes0 == z0 )
00441             zRes = zRes0;  // zRes takes reference
00442         else
00443         {
00444             zRes1 = extraZddUnateInfoCompute( dd, bF1, cuddT(bVarsNew) );
00445             if ( zRes1 == NULL )
00446             {
00447                 Cudd_RecursiveDerefZdd( dd, zRes0 );
00448                 return NULL;
00449             }
00450             cuddRef( zRes1 );
00451 
00452             // only those variables are pair-wise symmetric 
00453             // that are pair-wise symmetric in both cofactors
00454             // therefore, intersect the solutions
00455             zRes = cuddZddIntersect( dd, zRes0, zRes1 );
00456             if ( zRes == NULL )
00457             {
00458                 Cudd_RecursiveDerefZdd( dd, zRes0 );
00459                 Cudd_RecursiveDerefZdd( dd, zRes1 );
00460                 return NULL;
00461             }
00462             cuddRef( zRes );
00463             Cudd_RecursiveDerefZdd( dd, zRes0 );
00464             Cudd_RecursiveDerefZdd( dd, zRes1 );
00465         }
00466 
00467         // consider the current top-most variable
00468         AddVar = -1;
00469         if ( Cudd_bddLeq( dd, bF0, bF1 ) ) // pos
00470             AddVar = 0;
00471         else if ( Cudd_bddLeq( dd, bF1, bF0 ) ) // neg
00472             AddVar = 1;
00473         if ( AddVar >= 0 )
00474         {
00475             // create the singleton
00476             zPlus = cuddZddGetNode( dd, 2*bFR->index + AddVar, z1, z0 );
00477             if ( zPlus == NULL ) 
00478             {
00479                 Cudd_RecursiveDerefZdd( dd, zRes );
00480                 return NULL;
00481             }
00482             cuddRef( zPlus );
00483 
00484             // add these to the result
00485             zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
00486             if ( zRes == NULL )
00487             {
00488                 Cudd_RecursiveDerefZdd( dd, zTemp );
00489                 Cudd_RecursiveDerefZdd( dd, zPlus );
00490                 return NULL;
00491             }
00492             cuddRef( zRes );
00493             Cudd_RecursiveDerefZdd( dd, zTemp );
00494             Cudd_RecursiveDerefZdd( dd, zPlus );
00495         }
00496         // only zRes is referenced at this point
00497 
00498         // if we skipped some variables, these variables cannot be symmetric with
00499         // any variables that are currently in the support of bF, but they can be 
00500         // symmetric with the variables that are in bVars but not in the support of bF
00501         for ( bVarsNew = bVars; LevelF > dd->perm[bVarsNew->index]; bVarsNew = cuddT(bVarsNew) )
00502         {
00503             // create the negative singleton
00504             zPlus = cuddZddGetNode( dd, 2*bVarsNew->index+1, z1, z0 );
00505             if ( zPlus == NULL ) 
00506             {
00507                 Cudd_RecursiveDerefZdd( dd, zRes );
00508                 return NULL;
00509             }
00510             cuddRef( zPlus );
00511 
00512             // add these to the result
00513             zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
00514             if ( zRes == NULL )
00515             {
00516                 Cudd_RecursiveDerefZdd( dd, zTemp );
00517                 Cudd_RecursiveDerefZdd( dd, zPlus );
00518                 return NULL;
00519             }
00520             cuddRef( zRes );
00521             Cudd_RecursiveDerefZdd( dd, zTemp );
00522             Cudd_RecursiveDerefZdd( dd, zPlus );
00523         
00524 
00525             // create the positive singleton
00526             zPlus = cuddZddGetNode( dd, 2*bVarsNew->index, z1, z0 );
00527             if ( zPlus == NULL ) 
00528             {
00529                 Cudd_RecursiveDerefZdd( dd, zRes );
00530                 return NULL;
00531             }
00532             cuddRef( zPlus );
00533 
00534             // add these to the result
00535             zRes = cuddZddUnion( dd, zTemp = zRes, zPlus );
00536             if ( zRes == NULL )
00537             {
00538                 Cudd_RecursiveDerefZdd( dd, zTemp );
00539                 Cudd_RecursiveDerefZdd( dd, zPlus );
00540                 return NULL;
00541             }
00542             cuddRef( zRes );
00543             Cudd_RecursiveDerefZdd( dd, zTemp );
00544             Cudd_RecursiveDerefZdd( dd, zPlus );
00545         }
00546         cuddDeref( zRes );
00547 
00548         /* insert the result into cache */
00549         cuddCacheInsert2(dd, extraZddUnateInfoCompute, bFunc, bVars, zRes);
00550         return zRes;
00551     }
00552 } /* end of extraZddUnateInfoCompute */


Variable Documentation

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

Synopsis [MMoutOfMemory()]

Description []

SideEffects []

SeeAlso []

Definition at line 41 of file extraUtilUtil.c.

Definition at line 42 of file extraUtilUtil.c.


Generated on Tue Jan 5 12:19:14 2010 for abc70930 by  doxygen 1.6.1