| /**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 | |