blob: 534a0237a4be3a2aaf8c42048718c347b8367a67 [file] [log] [blame]
/**CFile****************************************************************
FileName [dauMerge.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware unmapping.]
Synopsis [Enumeration of decompositions.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: dauMerge.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "dauInt.h"
#include "misc/util/utilTruth.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Substitution storage.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
typedef struct Dau_Sto_t_ Dau_Sto_t;
struct Dau_Sto_t_
{
int iVarUsed; // counter of used variables
char pOutput[DAU_MAX_STR]; // storage for reduced function
char * pPosOutput; // place in the output
char pStore[DAU_MAX_VAR][DAU_MAX_STR]; // storage for definitions
char * pPosStore[DAU_MAX_VAR]; // place in the store
};
static inline void Dau_DsdMergeStoreClean( Dau_Sto_t * pS, int nShared )
{
int i;
pS->iVarUsed = nShared;
for ( i = 0; i < DAU_MAX_VAR; i++ )
pS->pStore[i][0] = 0;
}
static inline void Dau_DsdMergeStoreCleanOutput( Dau_Sto_t * pS )
{
pS->pPosOutput = pS->pOutput;
}
static inline void Dau_DsdMergeStoreAddToOutput( Dau_Sto_t * pS, char * pBeg, char * pEnd )
{
while ( pBeg < pEnd )
*pS->pPosOutput++ = *pBeg++;
}
static inline void Dau_DsdMergeStoreAddToOutputChar( Dau_Sto_t * pS, char c )
{
*pS->pPosOutput++ = c;
}
static inline int Dau_DsdMergeStoreStartDef( Dau_Sto_t * pS, char c )
{
pS->pPosStore[pS->iVarUsed] = pS->pStore[pS->iVarUsed];
if (c) *pS->pPosStore[pS->iVarUsed]++ = c;
return pS->iVarUsed++;
}
static inline void Dau_DsdMergeStoreAddToDef( Dau_Sto_t * pS, int New, char * pBeg, char * pEnd )
{
while ( pBeg < pEnd )
*pS->pPosStore[New]++ = *pBeg++;
}
static inline void Dau_DsdMergeStoreAddToDefChar( Dau_Sto_t * pS, int New, char c )
{
*pS->pPosStore[New]++ = c;
}
static inline void Dau_DsdMergeStoreStopDef( Dau_Sto_t * pS, int New, char c )
{
if (c) *pS->pPosStore[New]++ = c;
*pS->pPosStore[New]++ = 0;
}
static inline char Dau_DsdMergeStoreCreateDef( Dau_Sto_t * pS, char * pBeg, char * pEnd )
{
int New = Dau_DsdMergeStoreStartDef( pS, 0 );
Dau_DsdMergeStoreAddToDef( pS, New, pBeg, pEnd );
Dau_DsdMergeStoreStopDef( pS, New, 0 );
return New;
}
static inline void Dau_DsdMergeStorePrintDefs( Dau_Sto_t * pS )
{
int i;
for ( i = 0; i < DAU_MAX_VAR; i++ )
if ( pS->pStore[i][0] )
printf( "%c = %s\n", 'a' + i, pS->pStore[i] );
}
/**Function*************************************************************
Synopsis [Creates local copy.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Dau_DsdMergeCopy( char * pDsd, int fCompl, char * pRes )
{
if ( fCompl && pDsd[0] == '!' )
fCompl = 0, pDsd++;
if ( Dau_DsdIsConst(pDsd) ) // constant
pRes[0] = (fCompl ? (char)((int)pDsd[0] ^ 1) : pDsd[0]), pRes[1] = 0;
else
sprintf( pRes, "%s%s", fCompl ? "!" : "", pDsd );
}
/**Function*************************************************************
Synopsis [Replaces variables according to the mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Dau_DsdMergeReplace( char * pDsd, int * pMatches, int * pMap )
{
int i;
for ( i = 0; pDsd[i]; i++ )
{
// skip non-DSD block
if ( pDsd[i] == '<' && pDsd[pMatches[i]+1] == '{' )
i = pMatches[i] + 1;
if ( (pDsd[i] >= 'A' && pDsd[i] <= 'F') || (pDsd[i] >= '0' && pDsd[i] <= '9') )
while ( (pDsd[i] >= 'A' && pDsd[i] <= 'F') || (pDsd[i] >= '0' && pDsd[i] <= '9') )
i++;
// detect variables
if ( pDsd[i] >= 'a' && pDsd[i] <= 'z' )
pDsd[i] = 'a' + pMap[ pDsd[i] - 'a' ];
}
}
static inline void Dau_DsdMergeMatches( char * pDsd, int * pMatches )
{
int pNested[DAU_MAX_VAR];
int i, nNested = 0;
for ( i = 0; pDsd[i]; i++ )
{
pMatches[i] = 0;
if ( pDsd[i] == '(' || pDsd[i] == '[' || pDsd[i] == '<' || pDsd[i] == '{' )
pNested[nNested++] = i;
else if ( pDsd[i] == ')' || pDsd[i] == ']' || pDsd[i] == '>' || pDsd[i] == '}' )
pMatches[pNested[--nNested]] = i;
assert( nNested < DAU_MAX_VAR );
}
assert( nNested == 0 );
}
static inline void Dau_DsdMergeVarPres( char * pDsd, int * pMatches, int * pPres, int Mask )
{
int i;
for ( i = 0; pDsd[i]; i++ )
{
// skip non-DSD block
if ( pDsd[i] == '<' && pDsd[pMatches[i]+1] == '{' )
i = pMatches[i] + 1;
if ( (pDsd[i] >= 'A' && pDsd[i] <= 'F') || (pDsd[i] >= '0' && pDsd[i] <= '9') )
while ( (pDsd[i] >= 'A' && pDsd[i] <= 'F') || (pDsd[i] >= '0' && pDsd[i] <= '9') )
i++;
// skip non-variables
if ( !(pDsd[i] >= 'a' && pDsd[i] <= 'z') )
continue;
// record the mask
assert( pDsd[i]-'a' < DAU_MAX_VAR );
pPres[pDsd[i]-'a'] |= Mask;
}
}
static inline int Dau_DsdMergeCountShared( int * pPres, int Mask )
{
int i, Counter = 0;
for ( i = 0; i < DAU_MAX_VAR; i++ )
Counter += (pPres[i] == Mask);
return Counter;
}
static inline int Dau_DsdMergeFindShared( char * pDsd0, char * pDsd1, int * pMatches0, int * pMatches1, int * pVarPres )
{
memset( pVarPres, 0, sizeof(int)*DAU_MAX_VAR );
Dau_DsdMergeVarPres( pDsd0, pMatches0, pVarPres, 1 );
Dau_DsdMergeVarPres( pDsd1, pMatches1, pVarPres, 2 );
return Dau_DsdMergeCountShared( pVarPres, 3 );
}
static inline int Dau_DsdMergeCreateMaps( int * pVarPres, int nShared, int * pOld2New, int * pNew2Old )
{
int i, Counter = 0, Counter2 = nShared;
for ( i = 0; i < DAU_MAX_VAR; i++ )
{
if ( pVarPres[i] == 0 )
continue;
if ( pVarPres[i] == 3 )
{
pOld2New[i] = Counter;
pNew2Old[Counter] = i;
Counter++;
continue;
}
assert( pVarPres[i] == 1 || pVarPres[i] == 2 );
pOld2New[i] = Counter2;
pNew2Old[Counter2] = i;
Counter2++;
}
return Counter2;
}
static inline void Dau_DsdMergeInlineDefinitions( char * pDsd, int * pMatches, Dau_Sto_t * pS, char * pRes, int nShared )
{
int i;
char * pDef;
char * pBegin = pRes;
for ( i = 0; pDsd[i]; i++ )
{
// skip non-DSD block
if ( pDsd[i] == '<' && pDsd[pMatches[i]+1] == '{' )
{
assert( pDsd[pMatches[i]] == '>' );
for ( ; i <= pMatches[i]; i++ )
*pRes++ = pDsd[i];
}
if ( (pDsd[i] >= 'A' && pDsd[i] <= 'F') || (pDsd[i] >= '0' && pDsd[i] <= '9') )
while ( (pDsd[i] >= 'A' && pDsd[i] <= 'F') || (pDsd[i] >= '0' && pDsd[i] <= '9') )
*pRes++ = pDsd[i++];
// detect variables
if ( !(pDsd[i] >= 'a' && pDsd[i] <= 'z') || (pDsd[i] - 'a' < nShared) )
{
*pRes++ = pDsd[i];
continue;
}
// inline definition
assert( pDsd[i]-'a' < DAU_MAX_STR );
for ( pDef = pS->pStore[pDsd[i]-'a']; *pDef; pDef++ )
*pRes++ = *pDef;
}
*pRes++ = 0;
assert( pRes - pBegin < DAU_MAX_STR );
}
/**Function*************************************************************
Synopsis [Computes independence status for each opening parenthesis.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Dau_DsdMergePrintWithStatus( char * p, int * pStatus )
{
int i;
printf( "%s\n", p );
for ( i = 0; p[i]; i++ )
if ( !(p[i] == '(' || p[i] == '[' || p[i] == '<' || p[i] == '{' || (p[i] >= 'a' && p[i] <= 'z')) )
printf( " " );
else if ( pStatus[i] >= 0 )
printf( "%d", pStatus[i] );
else
printf( "-" );
printf( "\n" );
}
int Dau_DsdMergeStatus_rec( char * pStr, char ** p, int * pMatches, int nShared, int * pStatus )
{
// none pure
// 1 one pure
// 2 two or more pure
// 3 all pure
if ( **p == '!' )
{
pStatus[*p - pStr] = -1;
(*p)++;
}
while ( (**p >= 'A' && **p <= 'F') || (**p >= '0' && **p <= '9') )
{
pStatus[*p - pStr] = -1;
(*p)++;
}
if ( **p == '<' )
{
char * q = pStr + pMatches[ *p - pStr ];
if ( *(q+1) == '{' )
{
char * pTemp = *p;
*p = q+1;
for ( ; pTemp < q+1; pTemp++ )
pStatus[pTemp - pStr] = -1;
}
}
if ( **p >= 'a' && **p <= 'z' ) // var
return pStatus[*p - pStr] = (**p - 'a' < nShared) ? 0 : 3;
if ( **p == '(' || **p == '[' || **p == '<' || **p == '{' ) // and/or/xor
{
int Status, nPure = 0, nTotal = 0;
char * pOld = *p;
char * q = pStr + pMatches[ *p - pStr ];
assert( *q == **p + 1 + (**p != '(') );
for ( (*p)++; *p < q; (*p)++ )
{
Status = Dau_DsdMergeStatus_rec( pStr, p, pMatches, nShared, pStatus );
nPure += (Status == 3);
nTotal++;
}
assert( *p == q );
assert( nTotal > 1 );
if ( nPure == 0 )
Status = 0;
else if ( nPure == 1 )
Status = 1;
else if ( nPure < nTotal )
Status = 2;
else if ( nPure == nTotal )
Status = 3;
else assert( 0 );
return (pStatus[pOld - pStr] = Status);
}
assert( 0 );
return 0;
}
static inline int Dau_DsdMergeStatus( char * pDsd, int * pMatches, int nShared, int * pStatus )
{
return Dau_DsdMergeStatus_rec( pDsd, &pDsd, pMatches, nShared, pStatus );
}
/**Function*************************************************************
Synopsis [Extracts the formula.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Dau_DsdMergeGetStatus( char * pBeg, char * pStr, int * pMatches, int * pStatus )
{
if ( *pBeg == '!' )
pBeg++;
while ( (*pBeg >= 'A' && *pBeg <= 'F') || (*pBeg >= '0' && *pBeg <= '9') )
pBeg++;
if ( *pBeg == '<' )
{
char * q = pStr + pMatches[pBeg - pStr];
if ( *(q+1) == '{' )
pBeg = q+1;
}
return pStatus[pBeg - pStr];
}
void Dau_DsdMergeSubstitute_rec( Dau_Sto_t * pS, char * pStr, char ** p, int * pMatches, int * pStatus, int fWrite )
{
// assert( **p != '!' );
if ( **p == '!' )
{
if ( fWrite )
Dau_DsdMergeStoreAddToOutputChar( pS, **p );
(*p)++;
}
while ( (**p >= 'A' && **p <= 'F') || (**p >= '0' && **p <= '9') )
{
if ( fWrite )
Dau_DsdMergeStoreAddToOutputChar( pS, **p );
(*p)++;
}
if ( **p == '<' )
{
char * q = pStr + pMatches[ *p - pStr ];
if ( *(q+1) == '{' )
{
char * pTemp = *p;
*p = q+1;
if ( fWrite )
for ( ; pTemp < q+1; pTemp++ )
Dau_DsdMergeStoreAddToOutputChar( pS, *pTemp );
}
}
if ( **p >= 'a' && **p <= 'z' ) // var
{
if ( fWrite )
Dau_DsdMergeStoreAddToOutputChar( pS, **p );
return;
}
if ( **p == '(' || **p == '[' || **p == '<' || **p == '{' ) // and/or/xor
{
int New, StatusFan, Status = pStatus[*p - pStr];
char * pBeg, * q = pStr + pMatches[ *p - pStr ];
assert( *q == **p + 1 + (**p != '(') );
if ( !fWrite )
{
assert( Status == 3 );
*p = q;
return;
}
assert( Status != 3 );
if ( Status == 0 ) // none pure
{
Dau_DsdMergeStoreAddToOutputChar( pS, **p );
for ( (*p)++; *p < q; (*p)++ )
{
if ( **p == '!' )
{
Dau_DsdMergeStoreAddToOutputChar( pS, '!' );
(*p)++;
}
Dau_DsdMergeSubstitute_rec( pS, pStr, p, pMatches, pStatus, 1 );
}
Dau_DsdMergeStoreAddToOutputChar( pS, **p );
assert( *p == q );
return;
}
if ( Status == 1 || **p == '<' || **p == '{' ) // 1 pure
{
Dau_DsdMergeStoreAddToOutputChar( pS, **p );
for ( (*p)++; *p < q; (*p)++ )
{
if ( **p == '!' )
{
Dau_DsdMergeStoreAddToOutputChar( pS, '!' );
(*p)++;
}
pBeg = *p;
StatusFan = Dau_DsdMergeGetStatus( pBeg, pStr, pMatches, pStatus );
Dau_DsdMergeSubstitute_rec( pS, pStr, p, pMatches, pStatus, StatusFan != 3 );
if ( StatusFan == 3 )
{
int New = Dau_DsdMergeStoreCreateDef( pS, pBeg, *p+1 );
Dau_DsdMergeStoreAddToOutputChar( pS, (char)('a' + New) );
}
}
Dau_DsdMergeStoreAddToOutputChar( pS, **p );
assert( *p == q );
return;
}
if ( Status == 2 )
{
// add more than one defs
Dau_DsdMergeStoreAddToOutputChar( pS, **p );
New = Dau_DsdMergeStoreStartDef( pS, **p );
for ( (*p)++; *p < q; (*p)++ )
{
pBeg = *p;
StatusFan = Dau_DsdMergeGetStatus( pBeg, pStr, pMatches, pStatus );
if ( **p == '!' )
{
if ( StatusFan != 3 )
Dau_DsdMergeStoreAddToOutputChar( pS, '!' );
else
Dau_DsdMergeStoreAddToDefChar( pS, New, '!' );
(*p)++;
pBeg++;
}
Dau_DsdMergeSubstitute_rec( pS, pStr, p, pMatches, pStatus, StatusFan != 3 );
if ( StatusFan == 3 )
Dau_DsdMergeStoreAddToDef( pS, New, pBeg, *p+1 );
}
Dau_DsdMergeStoreStopDef( pS, New, *q );
Dau_DsdMergeStoreAddToOutputChar( pS, (char)('a' + New) );
Dau_DsdMergeStoreAddToOutputChar( pS, **p );
return;
}
assert( 0 );
return;
}
assert( 0 );
}
static inline void Dau_DsdMergeSubstitute( Dau_Sto_t * pS, char * pDsd, int * pMatches, int * pStatus )
{
/*
int fCompl = 0;
if ( pDsd[0] == '!' )
{
Dau_DsdMergeStoreAddToOutputChar( pS, '!' );
pDsd++;
fCompl = 1;
}
*/
Dau_DsdMergeSubstitute_rec( pS, pDsd, &pDsd, pMatches, pStatus, 1 );
Dau_DsdMergeStoreAddToOutputChar( pS, 0 );
}
/**Function*************************************************************
Synopsis [Removes braces.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dau_DsdRemoveBraces_rec( char * pStr, char ** p, int * pMatches )
{
if ( **p == '!' )
(*p)++;
while ( (**p >= 'A' && **p <= 'F') || (**p >= '0' && **p <= '9') )
(*p)++;
if ( **p == '<' )
{
char * q = pStr + pMatches[*p - pStr];
if ( *(q+1) == '{' )
*p = q+1;
}
if ( **p >= 'a' && **p <= 'z' ) // var
return;
if ( **p == '(' || **p == '[' || **p == '<' || **p == '{' )
{
char * q = pStr + pMatches[ *p - pStr ];
assert( *q == **p + 1 + (**p != '(') );
for ( (*p)++; *p < q; (*p)++ )
{
int fCompl = (**p == '!');
char * pBeg = fCompl ? *p + 1 : *p;
Dau_DsdRemoveBraces_rec( pStr, p, pMatches );
if ( (!fCompl && *pBeg == '(' && *q == ')') || (*pBeg == '[' && *q == ']') )
{
assert( **p == ')' || **p == ']' );
*pBeg = **p = ' ';
}
}
assert( *p == q );
return;
}
assert( 0 );
}
void Dau_DsdRemoveBraces( char * pDsd, int * pMatches )
{
char * q, * p = pDsd;
if ( pDsd[1] == 0 )
return;
Dau_DsdRemoveBraces_rec( pDsd, &pDsd, pMatches );
for ( q = p; *p; p++ )
if ( *p != ' ' )
{
if ( *p == '!' && *(q-1) == '!' && p != q )
{
q--;
continue;
}
*q++ = *p;
}
*q = 0;
}
abctime s_TimeComp[4] = {0};
/**Function*************************************************************
Synopsis [Performs merging of two DSD formulas.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Dau_DsdMerge( char * pDsd0i, int * pPerm0, char * pDsd1i, int * pPerm1, int fCompl0, int fCompl1, int nVars )
{
int fVerbose = 0;
int fCheck = 0;
static int Counter = 0;
static char pRes[DAU_MAX_STR];
char pDsd0[DAU_MAX_STR];
char pDsd1[DAU_MAX_STR];
int pMatches0[DAU_MAX_STR];
int pMatches1[DAU_MAX_STR];
int pVarPres[DAU_MAX_VAR];
int pOld2New[DAU_MAX_VAR];
int pNew2Old[DAU_MAX_VAR];
int pStatus0[DAU_MAX_STR];
int pStatus1[DAU_MAX_STR];
int pMatches[DAU_MAX_STR];
int nVarsShared, nVarsTotal;
Dau_Sto_t S, * pS = &S;
word * pTruth, * pt = NULL, * pt0 = NULL, * pt1 = NULL;
word pParts[3][DAU_MAX_WORD];
int Status;
abctime clk = Abc_Clock();
Counter++;
// create local copies
Dau_DsdMergeCopy( pDsd0i, fCompl0, pDsd0 );
Dau_DsdMergeCopy( pDsd1i, fCompl1, pDsd1 );
if ( fVerbose )
printf( "\nAfter copying:\n" );
if ( fVerbose )
printf( "%s\n", pDsd0 );
if ( fVerbose )
printf( "%s\n", pDsd1 );
// handle constants
if ( Dau_DsdIsConst(pDsd0) || Dau_DsdIsConst(pDsd1) )
{
if ( Dau_DsdIsConst0(pDsd0) )
strcpy( pRes, pDsd0 );
else if ( Dau_DsdIsConst1(pDsd0) )
strcpy( pRes, pDsd1 );
else if ( Dau_DsdIsConst0(pDsd1) )
strcpy( pRes, pDsd1 );
else if ( Dau_DsdIsConst1(pDsd1) )
strcpy( pRes, pDsd0 );
else assert( 0 );
return pRes;
}
// compute matches
Dau_DsdMergeMatches( pDsd0, pMatches0 );
Dau_DsdMergeMatches( pDsd1, pMatches1 );
// implement permutation
Dau_DsdMergeReplace( pDsd0, pMatches0, pPerm0 );
Dau_DsdMergeReplace( pDsd1, pMatches1, pPerm1 );
if ( fVerbose )
printf( "After replacement:\n" );
if ( fVerbose )
printf( "%s\n", pDsd0 );
if ( fVerbose )
printf( "%s\n", pDsd1 );
if ( fCheck )
{
pt0 = Dau_DsdToTruth( pDsd0, nVars );
Abc_TtCopy( pParts[0], pt0, Abc_TtWordNum(nVars), 0 );
}
if ( fCheck )
{
pt1 = Dau_DsdToTruth( pDsd1, nVars );
Abc_TtCopy( pParts[1], pt1, Abc_TtWordNum(nVars), 0 );
Abc_TtAnd( pParts[2], pParts[0], pParts[1], Abc_TtWordNum(nVars), 0 );
}
// find shared varaiables
nVarsShared = Dau_DsdMergeFindShared(pDsd0, pDsd1, pMatches0, pMatches1, pVarPres);
if ( nVarsShared == 0 )
{
sprintf( pRes, "(%s%s)", pDsd0, pDsd1 );
if ( fVerbose )
printf( "Disjoint:\n" );
if ( fVerbose )
printf( "%s\n", pRes );
Dau_DsdMergeMatches( pRes, pMatches );
Dau_DsdRemoveBraces( pRes, pMatches );
Dau_DsdNormalize( pRes );
if ( fVerbose )
printf( "Normalized:\n" );
if ( fVerbose )
printf( "%s\n", pRes );
s_TimeComp[0] += Abc_Clock() - clk;
return pRes;
}
s_TimeComp[3] += Abc_Clock() - clk;
// create variable mapping
nVarsTotal = Dau_DsdMergeCreateMaps( pVarPres, nVarsShared, pOld2New, pNew2Old );
// perform variable replacement
Dau_DsdMergeReplace( pDsd0, pMatches0, pOld2New );
Dau_DsdMergeReplace( pDsd1, pMatches1, pOld2New );
// find uniqueness status
Dau_DsdMergeStatus( pDsd0, pMatches0, nVarsShared, pStatus0 );
Dau_DsdMergeStatus( pDsd1, pMatches1, nVarsShared, pStatus1 );
if ( fVerbose )
printf( "Individual status:\n" );
if ( fVerbose )
Dau_DsdMergePrintWithStatus( pDsd0, pStatus0 );
if ( fVerbose )
Dau_DsdMergePrintWithStatus( pDsd1, pStatus1 );
// prepare storage
Dau_DsdMergeStoreClean( pS, nVarsShared );
// perform substitutions
Dau_DsdMergeStoreCleanOutput( pS );
Dau_DsdMergeSubstitute( pS, pDsd0, pMatches0, pStatus0 );
strcpy( pDsd0, pS->pOutput );
if ( fVerbose )
printf( "Substitutions:\n" );
if ( fVerbose )
printf( "%s\n", pDsd0 );
// perform substitutions
Dau_DsdMergeStoreCleanOutput( pS );
Dau_DsdMergeSubstitute( pS, pDsd1, pMatches1, pStatus1 );
strcpy( pDsd1, pS->pOutput );
if ( fVerbose )
printf( "%s\n", pDsd1 );
if ( fVerbose )
Dau_DsdMergeStorePrintDefs( pS );
// create new function
// assert( nVarsTotal <= 6 );
sprintf( pS->pOutput, "(%s%s)", pDsd0, pDsd1 );
pTruth = Dau_DsdToTruth( pS->pOutput, nVarsTotal );
Status = Dau_DsdDecompose( pTruth, nVarsTotal, 0, 1, pS->pOutput );
//printf( "%d ", Status );
if ( Status == -1 ) // did not find 1-step DSD
return NULL;
// if ( Status > 6 ) // non-DSD part is too large
// return NULL;
if ( Dau_DsdIsConst(pS->pOutput) )
{
strcpy( pRes, pS->pOutput );
return pRes;
}
if ( fVerbose )
printf( "Decomposition:\n" );
if ( fVerbose )
printf( "%s\n", pS->pOutput );
// substitute definitions
Dau_DsdMergeMatches( pS->pOutput, pMatches );
Dau_DsdMergeInlineDefinitions( pS->pOutput, pMatches, pS, pRes, nVarsShared );
if ( fVerbose )
printf( "Inlining:\n" );
if ( fVerbose )
printf( "%s\n", pRes );
// perform variable replacement
Dau_DsdMergeMatches( pRes, pMatches );
Dau_DsdMergeReplace( pRes, pMatches, pNew2Old );
Dau_DsdRemoveBraces( pRes, pMatches );
if ( fVerbose )
printf( "Replaced:\n" );
if ( fVerbose )
printf( "%s\n", pRes );
Dau_DsdNormalize( pRes );
if ( fVerbose )
printf( "Normalized:\n" );
if ( fVerbose )
printf( "%s\n", pRes );
if ( fCheck )
{
pt = Dau_DsdToTruth( pRes, nVars );
if ( !Abc_TtEqual( pParts[2], pt, Abc_TtWordNum(nVars) ) )
printf( "Dau_DsdMerge(): Verification failed!\n" );
}
if ( Status == 0 )
s_TimeComp[1] += Abc_Clock() - clk;
else
s_TimeComp[2] += Abc_Clock() - clk;
return pRes;
}
void Dau_DsdTest66()
{
int Perm0[DAU_MAX_VAR] = { 0, 1, 2, 3, 4, 5 };
// int pMatches[DAU_MAX_STR];
// int pStatus[DAU_MAX_STR];
// char * pStr = "(!(!a<bcd>)!(!fe))";
// char * pStr = "([acb]<!edf>)";
// char * pStr = "!(f!(b!c!(d[ea])))";
char * pStr = "[!(a[be])!(c!df)]";
// char * pStr = "<(e<bca>)fd>";
// char * pStr = "[d8001{abef}c]";
// char * pStr1 = "(abc)";
// char * pStr2 = "[adf]";
// char * pStr1 = "(!abce)";
// char * pStr2 = "[adf!b]";
// char * pStr1 = "(!abc)";
// char * pStr2 = "[ab]";
// char * pStr1 = "[d81{abe}c]";
// char * pStr1 = "[d<a(bc)(!b!c)>{abe}c]";
// char * pStr1 = "[d81{abe}c]";
// char * pStr1 = "[d(a[be])c]";
// char * pStr2 = "(df)";
// char * pStr1 = "(abf)";
// char * pStr2 = "(a[(bc)(fde)])";
// char * pStr1 = "8001{abc[ef]}";
// char * pStr2 = "(abe)";
char * pStr1 = "(!(ab)de)";
char * pStr2 = "(!(ac)f)";
char * pRes;
word t = Dau_Dsd6ToTruth( pStr );
return;
// pStr2 = Dau_DsdDecompose( &t, 6, 0, NULL );
// Dau_DsdNormalize( pStr2 );
// Dau_DsdMergeMatches( pStr, pMatches );
// Dau_DsdMergeStatus( pStr, pMatches, 2, pStatus );
// Dau_DsdMergePrintWithStatus( pStr, pStatus );
pRes = Dau_DsdMerge( pStr1, Perm0, pStr2, Perm0, 0, 0, 6 );
t = 0;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END