Commit 3f7f4973 by Alan Mishchenko

Improved DSD.

parent cb5e2308
...@@ -80,8 +80,30 @@ static word s_PMasks[5][3] = { ...@@ -80,8 +80,30 @@ static word s_PMasks[5][3] = {
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
// read/write/flip i-th bit of a bit string table:
static inline int Abc_TtGetBit( word * p, int i ) { return (int)(p[i>>6] >> (i & 63)) & 1; }
static inline void Abc_TtSetBit( word * p, int i ) { p[i>>6] |= (((word)1)<<(i & 63)); }
static inline void Abc_TtXorBit( word * p, int i ) { p[i>>6] ^= (((word)1)<<(i & 63)); }
// read/write k-th digit d of a hexadecimal number:
static inline int Abc_TtGetHex( word * p, int k ) { return (int)(p[k>>4] >> ((k<<2) & 63)) & 15; }
static inline void Abc_TtSetHex( word * p, int k, int d ) { p[k>>4] |= (((word)d)<<((k<<2) & 63)); }
static inline void Abc_TtXorHex( word * p, int k, int d ) { p[k>>4] ^= (((word)d)<<((k<<2) & 63)); }
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Abc_TtWordNum( int nVars ) { return nVars <= 6 ? 1 : 1 << (nVars-6); } static inline int Abc_TtWordNum( int nVars ) { return nVars <= 6 ? 1 : 1 << (nVars-6); }
static inline int Abc_TtByteNum( int nVars ) { return nVars <= 3 ? 1 : 1 << (nVars-3); } static inline int Abc_TtByteNum( int nVars ) { return nVars <= 3 ? 1 : 1 << (nVars-3); }
static inline int Abc_TtHexDigitNum( int nVars ) { return nVars <= 2 ? 1 : 1 << (nVars-2); }
/**Function************************************************************* /**Function*************************************************************
...@@ -427,6 +449,66 @@ static inline int Abc_TtCofsOpposite( word * t, int nWords, int iVar ) ...@@ -427,6 +449,66 @@ static inline int Abc_TtCofsOpposite( word * t, int nWords, int iVar )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Stretch truthtable to have more input variables.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Abc_TtStretch5( unsigned * pInOut, int nVarS, int nVarB )
{
int w, i, step, nWords;
if ( nVarS == nVarB )
return;
assert( nVarS < nVarB );
step = Abc_TruthWordNum(nVarS);
nWords = Abc_TruthWordNum(nVarB);
if ( step == nWords )
return;
assert( step < nWords );
for ( w = 0; w < nWords; w += step )
for ( i = 0; i < step; i++ )
pInOut[w + i] = pInOut[i];
}
static inline void Abc_TtStretch6( word * pInOut, int nVarS, int nVarB )
{
int w, i, step, nWords;
if ( nVarS == nVarB )
return;
assert( nVarS < nVarB );
step = Abc_Truth6WordNum(nVarS);
nWords = Abc_Truth6WordNum(nVarB);
if ( step == nWords )
return;
assert( step < nWords );
for ( w = 0; w < nWords; w += step )
for ( i = 0; i < step; i++ )
pInOut[w + i] = pInOut[i];
}
static inline word Abc_Tt6Stretch( word t, int nVars )
{
assert( nVars >= 0 );
if ( nVars == 0 )
nVars++, t = (t & 0x1) | ((t & 0x1) << 1);
if ( nVars == 1 )
nVars++, t = (t & 0x3) | ((t & 0x3) << 2);
if ( nVars == 2 )
nVars++, t = (t & 0xF) | ((t & 0xF) << 4);
if ( nVars == 3 )
nVars++, t = (t & 0xFF) | ((t & 0xFF) << 8);
if ( nVars == 4 )
nVars++, t = (t & 0xFFFF) | ((t & 0xFFFF) << 16);
if ( nVars == 5 )
nVars++, t = (t & 0xFFFFFFFF) | ((t & 0xFFFFFFFF) << 32);
assert( nVars == 6 );
return t;
}
/**Function*************************************************************
Synopsis [] Synopsis []
Description [] Description []
...@@ -436,13 +518,40 @@ static inline int Abc_TtCofsOpposite( word * t, int nWords, int iVar ) ...@@ -436,13 +518,40 @@ static inline int Abc_TtCofsOpposite( word * t, int nWords, int iVar )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
static inline int Abc_TtIsHexDigit( char HexChar )
{
return (HexChar >= '0' && HexChar <= '9') || (HexChar >= 'A' && HexChar <= 'F') || (HexChar >= 'a' && HexChar <= 'f');
}
static inline char Abc_TtPrintDigit( int Digit ) static inline char Abc_TtPrintDigit( int Digit )
{ {
assert( Digit >= 0 && Digit < 16 ); assert( Digit >= 0 && Digit < 16 );
if ( Digit < 10 ) if ( Digit < 10 )
return '0' + Digit;; return '0' + Digit;
return 'A' + Digit-10; return 'A' + Digit-10;
} }
static inline int Abc_TtReadHexDigit( char HexChar )
{
if ( HexChar >= '0' && HexChar <= '9' )
return HexChar - '0';
if ( HexChar >= 'A' && HexChar <= 'F' )
return HexChar - 'A' + 10;
if ( HexChar >= 'a' && HexChar <= 'f' )
return HexChar - 'a' + 10;
assert( 0 ); // not a hexadecimal symbol
return -1; // return value which makes no sense
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Abc_TtPrintHex( word * pTruth, int nVars ) static inline void Abc_TtPrintHex( word * pTruth, int nVars )
{ {
word * pThis, * pLimit = pTruth + Abc_TtWordNum(nVars); word * pThis, * pLimit = pTruth + Abc_TtWordNum(nVars);
...@@ -485,6 +594,58 @@ static inline int Abc_TtWriteHexRev( char * pStr, word * pTruth, int nVars ) ...@@ -485,6 +594,58 @@ static inline int Abc_TtWriteHexRev( char * pStr, word * pTruth, int nVars )
return pStr - pStrInit; return pStr - pStrInit;
} }
/**Function*************************************************************
Synopsis [Reads hex truth table from a string.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Abc_TtReadHex( word * pTruth, char * pString )
{
int k, nVars, Digit, nDigits;
// skip the first 2 symbols if they are "0x"
if ( pString[0] == '0' && pString[1] == 'x' )
pString += 2;
// count the number of hex digits
nDigits = 0;
for ( k = 0; Abc_TtIsHexDigit(pString[k]); k++ )
nDigits++;
if ( nDigits == 1 )
{
if ( pString[0] == '0' || pString[0] == 'F' )
{
pTruth[0] = (pString[0] == '0') ? 0 : ~(word)0;
return 0;
}
if ( pString[0] == '5' || pString[0] == 'A' )
{
pTruth[0] = (pString[0] == '5') ? s_Truths6Neg[0] : s_Truths6[0];
return 1;
}
}
// determine the number of variables
nVars = 2 + Abc_Base2Log( nDigits );
// clean storage
for ( k = Abc_TtWordNum(nVars) - 1; k >= 0; k-- )
pTruth[k] = 0;
// read hexadecimal digits in the reverse order
// (the last symbol in the string is the least significant digit)
for ( k = 0; k < nDigits; k++ )
{
Digit = Abc_TtReadHexDigit( pString[nDigits - 1 - k] );
assert( Digit >= 0 && Digit < 16 );
Abc_TtSetHex( pTruth, k, Digit );
}
if ( nVars < 6 )
pTruth[0] = Abc_Tt6Stretch( pTruth[0], nVars );
return nVars;
}
/**Function************************************************************* /**Function*************************************************************
...@@ -890,48 +1051,6 @@ static inline void Abc_TtReverseBits( word * pTruth, int nVars ) ...@@ -890,48 +1051,6 @@ static inline void Abc_TtReverseBits( word * pTruth, int nVars )
} }
/**Function*************************************************************
Synopsis [Stretch truthtable to have more input variables.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Abc_TtStretch5( unsigned * pInOut, int nVarS, int nVarB )
{
int w, i, step, nWords;
if ( nVarS == nVarB )
return;
assert( nVarS < nVarB );
step = Abc_TruthWordNum(nVarS);
nWords = Abc_TruthWordNum(nVarB);
if ( step == nWords )
return;
assert( step < nWords );
for ( w = 0; w < nWords; w += step )
for ( i = 0; i < step; i++ )
pInOut[w + i] = pInOut[i];
}
static inline void Abc_TtStretch6( word * pInOut, int nVarS, int nVarB )
{
int w, i, step, nWords;
if ( nVarS == nVarB )
return;
assert( nVarS < nVarB );
step = Abc_Truth6WordNum(nVarS);
nWords = Abc_Truth6WordNum(nVarB);
if ( step == nWords )
return;
assert( step < nWords );
for ( w = 0; w < nWords; w += step )
for ( i = 0; i < step; i++ )
pInOut[w + i] = pInOut[i];
}
/*=== utilTruth.c ===========================================================*/ /*=== utilTruth.c ===========================================================*/
......
...@@ -27,7 +27,9 @@ ABC_NAMESPACE_IMPL_START ...@@ -27,7 +27,9 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS /// /// DECLARATIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
#define DAU_MAX_VAR 16 // should be 6 or more
#define DAU_MAX_STR 256 #define DAU_MAX_STR 256
#define DAU_MAX_WORD (1<<(DAU_MAX_VAR-6))
/* /*
This code performs truth-table-based decomposition for 6-variable functions. This code performs truth-table-based decomposition for 6-variable functions.
...@@ -54,15 +56,39 @@ ABC_NAMESPACE_IMPL_START ...@@ -54,15 +56,39 @@ ABC_NAMESPACE_IMPL_START
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int * Dau_DsdComputeMatches( char * p )
{
static int pMatches[DAU_MAX_STR];
int pNested[DAU_MAX_VAR];
int v, nNested = 0;
for ( v = 0; p[v]; v++ )
{
pMatches[v] = 0;
if ( p[v] == '(' || p[v] == '[' || p[v] == '<' || p[v] == '{' )
pNested[nNested++] = v;
else if ( p[v] == ')' || p[v] == ']' || p[v] == '>' || p[v] == '}' )
pMatches[pNested[--nNested]] = v;
}
assert( nNested == 0 );
/*
// verify
for ( v = 0; p[v]; v++ )
if ( p[v] == '(' || p[v] == '[' || p[v] == '<' || p[v] == '{' )
assert( pMatches[v] > 0 );
else
assert( pMatches[v] == 0 );
*/
return pMatches;
}
char * Dau_DsdFindMatch( char * p ) char * Dau_DsdFindMatch( char * p )
{ {
int Counter = 0; int Counter = 0;
assert( *p == '(' || *p == '[' || *p == '<' ); assert( *p == '(' || *p == '[' || *p == '<' || *p == '{' );
while ( *p ) while ( *p )
{ {
if ( *p == '(' || *p == '[' || *p == '<' ) if ( *p == '(' || *p == '[' || *p == '<' || *p == '{' )
Counter++; Counter++;
else if ( *p == ')' || *p == ']' || *p == '>' ) else if ( *p == ')' || *p == ']' || *p == '>' || *p == '}' )
Counter--; Counter--;
if ( Counter == 0 ) if ( Counter == 0 )
return p; return p;
...@@ -70,7 +96,23 @@ char * Dau_DsdFindMatch( char * p ) ...@@ -70,7 +96,23 @@ char * Dau_DsdFindMatch( char * p )
} }
return NULL; return NULL;
} }
word Dau_DsdToTruth_rec( char ** p ) word Dau_DsdTruthCompose_rec( word Func, word * pFanins, int nVars )
{
word t0, t1;
if ( Func == 0 )
return 0;
if ( Func == ~(word)0 )
return ~(word)0;
assert( nVars > 0 );
if ( --nVars == 0 )
return (Func == s_Truths6[0]) ? pFanins[0] : ~pFanins[0];
if ( !Abc_Tt6HasVar(Func, nVars) )
return Dau_DsdTruthCompose_rec( Func, pFanins, nVars );
t0 = Dau_DsdTruthCompose_rec( Abc_Tt6Cofactor0(Func, nVars), pFanins, nVars );
t1 = Dau_DsdTruthCompose_rec( Abc_Tt6Cofactor1(Func, nVars), pFanins, nVars );
return (~pFanins[nVars] & t0) | (pFanins[nVars] & t1);
}
word Dau_DsdToTruth_rec( char * pStr, char ** p, int * pMatches )
{ {
int fCompl = 0; int fCompl = 0;
if ( **p == '!' ) if ( **p == '!' )
...@@ -83,8 +125,8 @@ word Dau_DsdToTruth_rec( char ** p ) ...@@ -83,8 +125,8 @@ word Dau_DsdToTruth_rec( char ** p )
if ( **p == '(' || **p == '[' || **p == '<' ) if ( **p == '(' || **p == '[' || **p == '<' )
{ {
word Res = 0; word Res = 0;
char * q = Dau_DsdFindMatch( *p ); // char * q2 = Dau_DsdFindMatch( *p );
assert( q != NULL ); char * q = pStr + pMatches[ *p - pStr ];
assert( (**p == '(') == (*q == ')') ); assert( (**p == '(') == (*q == ')') );
assert( (**p == '[') == (*q == ']') ); assert( (**p == '[') == (*q == ']') );
assert( (**p == '<') == (*q == '>') ); assert( (**p == '<') == (*q == '>') );
...@@ -92,19 +134,19 @@ word Dau_DsdToTruth_rec( char ** p ) ...@@ -92,19 +134,19 @@ word Dau_DsdToTruth_rec( char ** p )
{ {
Res = ~(word)0; Res = ~(word)0;
for ( (*p)++; *p < q; (*p)++ ) for ( (*p)++; *p < q; (*p)++ )
Res &= Dau_DsdToTruth_rec( p ); Res &= Dau_DsdToTruth_rec( pStr, p, pMatches );
} }
else if ( **p == '[' ) // xor else if ( **p == '[' ) // xor
{ {
Res = 0; Res = 0;
for ( (*p)++; *p < q; (*p)++ ) for ( (*p)++; *p < q; (*p)++ )
Res ^= Dau_DsdToTruth_rec( p ); Res ^= Dau_DsdToTruth_rec( pStr, p, pMatches );
} }
else if ( **p == '<' ) // mux else if ( **p == '<' ) // mux
{ {
word Temp[3], * pTemp = Temp; word Temp[3], * pTemp = Temp;
for ( (*p)++; *p < q; (*p)++ ) for ( (*p)++; *p < q; (*p)++ )
*pTemp++ = Dau_DsdToTruth_rec( p ); *pTemp++ = Dau_DsdToTruth_rec( pStr, p, pMatches );
assert( pTemp == Temp + 3 ); assert( pTemp == Temp + 3 );
Res = (Temp[0] & Temp[1]) | (~Temp[0] & Temp[2]); Res = (Temp[0] & Temp[1]) | (~Temp[0] & Temp[2]);
} }
...@@ -112,18 +154,31 @@ word Dau_DsdToTruth_rec( char ** p ) ...@@ -112,18 +154,31 @@ word Dau_DsdToTruth_rec( char ** p )
assert( *p == q ); assert( *p == q );
return fCompl ? ~Res : Res; return fCompl ? ~Res : Res;
} }
if ( (**p >= 'A' && **p <= 'F') || (**p >= '0' && **p <= '9') )
{
word Func, Fanins[6];
char * q;
int i, nVars = Abc_TtReadHex( &Func, *p );
*p += Abc_TtHexDigitNum( nVars );
q = pStr + pMatches[ *p - pStr ];
assert( **p == '{' && *q == '}' );
for ( i = 0, (*p)++; *p < q; (*p)++, i++ )
Fanins[i] = Dau_DsdToTruth_rec( pStr, p, pMatches );
assert( i == nVars );
return Dau_DsdTruthCompose_rec( Func, Fanins, nVars );
}
assert( 0 ); assert( 0 );
return 0; return 0;
} }
word Dau_DsdToTruth( char * p ) word Dau_DsdToTruth( char * p )
{ {
word Res; word Res;
if ( *p == '0' ) if ( *p == '0' && *(p+1) == 0 )
Res = 0; Res = 0;
else if ( *p == '1' ) else if ( *p == '1' && *(p+1) == 0 )
Res = ~(word)0; Res = ~(word)0;
else else
Res = Dau_DsdToTruth_rec( &p ); Res = Dau_DsdToTruth_rec( p, &p, Dau_DsdComputeMatches(p) );
assert( *++p == 0 ); assert( *++p == 0 );
return Res; return Res;
} }
...@@ -779,7 +834,7 @@ static inline void Dau_DsdWriteVar( Dau_Dsd_t * p, int iVar, int fInv ) ...@@ -779,7 +834,7 @@ static inline void Dau_DsdWriteVar( Dau_Dsd_t * p, int iVar, int fInv )
static inline void Dau_DsdTranslate( Dau_Dsd_t * p, int * pVars, int nVars, char * pStr ) static inline void Dau_DsdTranslate( Dau_Dsd_t * p, int * pVars, int nVars, char * pStr )
{ {
for ( ; *pStr; pStr++ ) for ( ; *pStr; pStr++ )
if ( *pStr >= 'a' + nVars && *pStr < 'a' + nVars ) if ( *pStr >= 'a' && *pStr < 'a' + nVars )
Dau_DsdWriteVar( p, pVars[*pStr - 'a'], 0 ); Dau_DsdWriteVar( p, pVars[*pStr - 'a'], 0 );
else else
p->pOutput[ p->nPos++ ] = *pStr; p->pOutput[ p->nPos++ ] = *pStr;
...@@ -814,6 +869,15 @@ static inline int Dau_DsdAddVarDef( Dau_Dsd_t * p, char * pStr ) ...@@ -814,6 +869,15 @@ static inline int Dau_DsdAddVarDef( Dau_Dsd_t * p, char * pStr )
sprintf( p->pVarDefs[p->nVarsUsed++], "%s", pStr ); sprintf( p->pVarDefs[p->nVarsUsed++], "%s", pStr );
return p->nVarsUsed - 1; return p->nVarsUsed - 1;
} }
static inline int Dau_DsdFindVarDef( int * pVars, int nVars, int VarDef )
{
int v;
for ( v = 0; v < nVars; v++ )
if ( pVars[v] == VarDef )
break;
assert( v < nVars );
return v;
}
static inline void Dau_DsdInsertVarCache( Dau_Dsd_t * p, int v, int u, int Status ) static inline void Dau_DsdInsertVarCache( Dau_Dsd_t * p, int v, int u, int Status )
{ {
assert( v != u ); assert( v != u );
...@@ -828,6 +892,48 @@ static inline int Dau_DsdLookupVarCache( Dau_Dsd_t * p, int v, int u ) ...@@ -828,6 +892,48 @@ static inline int Dau_DsdLookupVarCache( Dau_Dsd_t * p, int v, int u )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Generate random permutation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dau_DsdFindVarNum( char * pDsd )
{
int vMax = 0;
pDsd--;
while ( *++pDsd )
if ( *pDsd >= 'a' && *pDsd <= 'z' )
vMax = Abc_MaxInt( vMax, *pDsd - 'a' );
return vMax + 1;
}
void Dau_DsdGenRandPerm( int * pPerm, int nVars )
{
int v, vNew;
for ( v = 0; v < nVars; v++ )
pPerm[v] = v;
for ( v = 0; v < nVars; v++ )
{
vNew = rand() % nVars;
ABC_SWAP( int, pPerm[v], pPerm[vNew] );
}
}
void Dau_DsdPermute( char * pDsd )
{
int pPerm[16];
int nVars = Dau_DsdFindVarNum( pDsd );
Dau_DsdGenRandPerm( pPerm, nVars );
pDsd--;
while ( *++pDsd )
if ( *pDsd >= 'a' && *pDsd < 'a' + nVars )
*pDsd = 'a' + pPerm[*pDsd - 'a'];
}
/**Function*************************************************************
Synopsis [] Synopsis []
Description [] Description []
...@@ -955,6 +1061,8 @@ static inline unsigned Dau_Dsd6FindSupports( Dau_Dsd_t * p, word * pTruth, int ...@@ -955,6 +1061,8 @@ static inline unsigned Dau_Dsd6FindSupports( Dau_Dsd_t * p, word * pTruth, int
unsigned uSupports = 0; unsigned uSupports = 0;
word tCof0 = Abc_Tt6Cofactor0( pTruth[0], v ); word tCof0 = Abc_Tt6Cofactor0( pTruth[0], v );
word tCof1 = Abc_Tt6Cofactor1( pTruth[0], v ); word tCof1 = Abc_Tt6Cofactor1( pTruth[0], v );
//Kit_DsdPrintFromTruth( (unsigned *)&tCof0, 6 );printf( "\n" );
//Kit_DsdPrintFromTruth( (unsigned *)&tCof1, 6 );printf( "\n" );
for ( u = 0; u < nVars; u++ ) for ( u = 0; u < nVars; u++ )
if ( u != v ) if ( u != v )
uSupports |= (Dau_Dsd6FindSupportOne( p, tCof0, tCof1, pVars, nVars, v, u ) << (2 * u)); uSupports |= (Dau_Dsd6FindSupportOne( p, tCof0, tCof1, pVars, nVars, v, u ) << (2 * u));
...@@ -1051,7 +1159,7 @@ int Dau_Dsd6DecomposeDoubleVars( Dau_Dsd_t * p, word * pTruth, int * pVars, int ...@@ -1051,7 +1159,7 @@ int Dau_Dsd6DecomposeDoubleVars( Dau_Dsd_t * p, word * pTruth, int * pVars, int
{ {
for ( u = v - 1; u >= 0; u-- ) for ( u = v - 1; u >= 0; u-- )
{ {
if ( Dau_DsdLookupVarCache( p, v, u ) ) if ( Dau_DsdLookupVarCache( p, pVars[v], pVars[u] ) )
continue; continue;
nVarsOld = nVars; nVarsOld = nVars;
nVars = Dau_Dsd6DecomposeDoubleVarsOne( p, pTruth, pVars, nVars, v, u ); nVars = Dau_Dsd6DecomposeDoubleVarsOne( p, pTruth, pVars, nVars, v, u );
...@@ -1074,24 +1182,25 @@ static inline int Dau_Dsd6DecomposeTripleVarsOuter( Dau_Dsd_t * p, word * pTrut ...@@ -1074,24 +1182,25 @@ static inline int Dau_Dsd6DecomposeTripleVarsOuter( Dau_Dsd_t * p, word * pTrut
{ {
extern void Dau_DsdDecomposeInt( Dau_Dsd_t * p, word * pTruth, int nVarsInit ); extern void Dau_DsdDecomposeInt( Dau_Dsd_t * p, word * pTruth, int nVarsInit );
Dau_Dsd_t P1, * p1 = &P1; Dau_Dsd_t P1, * p1 = &P1;
Dau_Dsd_t P2, * p2 = &P2;
word tCof0, tCof1; word tCof0, tCof1;
// move this variable to the top // move this variable to the top
pVars[v] = pVars[nVars-1]; ABC_SWAP( int, pVars[v], pVars[nVars-1] );
Abc_TtSwapVars( pTruth, 6, v, nVars-1 ); Abc_TtSwapVars( pTruth, 6, v, nVars-1 );
// cofactor w.r.t the last variable // cofactor w.r.t the last variable
tCof0 = Abc_Tt6Cofactor0( pTruth[0], nVars - 1 ); tCof0 = Abc_Tt6Cofactor0( pTruth[0], nVars - 1 );
tCof1 = Abc_Tt6Cofactor1( pTruth[0], nVars - 1 ); tCof1 = Abc_Tt6Cofactor1( pTruth[0], nVars - 1 );
// split decomposition
Dau_DsdDecomposeInt( p1, &tCof0, nVars - 1 );
Dau_DsdDecomposeInt( p2, &tCof1, nVars - 1 );
p->nSizeNonDec = Abc_MaxInt( p1->nSizeNonDec, p2->nSizeNonDec );
// compose the result // compose the result
Dau_DsdWriteString( p, "<" ); Dau_DsdWriteString( p, "<" );
Dau_DsdWriteVar( p, pVars[nVars - 1], 0 ); Dau_DsdWriteVar( p, pVars[nVars - 1], 0 );
// split decomposition
Dau_DsdDecomposeInt( p1, &tCof1, nVars - 1 );
Dau_DsdTranslate( p, pVars, nVars - 1, p1->pOutput );
p->nSizeNonDec = p1->nSizeNonDec;
// split decomposition
Dau_DsdDecomposeInt( p1, &tCof0, nVars - 1 );
Dau_DsdTranslate( p, pVars, nVars - 1, p1->pOutput ); Dau_DsdTranslate( p, pVars, nVars - 1, p1->pOutput );
Dau_DsdTranslate( p, pVars, nVars - 1, p2->pOutput );
Dau_DsdWriteString( p, ">" ); Dau_DsdWriteString( p, ">" );
p->nSizeNonDec = Abc_MaxInt( p->nSizeNonDec, p1->nSizeNonDec );
return 0; return 0;
} }
static inline int Dau_Dsd6DecomposeTripleVarsInner( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars, int v, unsigned uSupports ) static inline int Dau_Dsd6DecomposeTripleVarsInner( Dau_Dsd_t * p, word * pTruth, int * pVars, int nVars, int v, unsigned uSupports )
...@@ -1112,20 +1221,23 @@ static inline int Dau_Dsd6DecomposeTripleVarsInner( Dau_Dsd_t * p, word * pTrut ...@@ -1112,20 +1221,23 @@ static inline int Dau_Dsd6DecomposeTripleVarsInner( Dau_Dsd_t * p, word * pTrut
if ( fEqual0 || fEqual1 ) if ( fEqual0 || fEqual1 )
{ {
char pBuffer[10]; char pBuffer[10];
int iVarMin = Abc_MinInt( v, Abc_MinInt( iVar0, iVar1 ) ); int VarId = pVars[iVar0];
// assert( iVarMin < iVar0 && iVar0 < iVar1 ); pTruth[0] = (s_Truths6[v] & C11) | (~s_Truths6[v] & C10);
pTruth[0] = (s_Truths6[iVarMin] & Abc_Tt6Cofactor0(tCof1, iVar1)) | (~s_Truths6[iVarMin] & Abc_Tt6Cofactor1(tCof1, iVar1)); sprintf( pBuffer, "<%c%c%s%c>", 'a' + pVars[v], 'a' + pVars[iVar1], fEqual1 ? "!":"", 'a' + pVars[iVar0] );
if ( fEqual1 ) pVars[v] = Dau_DsdAddVarDef( p, pBuffer );
pTruth[0] = ~pTruth[0]; // remove iVar1
sprintf( pBuffer, "<%c%c%c>", 'a' + pVars[v], 'a' + pVars[iVar1], 'a' + pVars[iVar0] ); ABC_SWAP( int, pVars[iVar1], pVars[nVars-1] );
pVars[iVarMin] = Dau_DsdAddVarDef( p, pBuffer ); Abc_TtSwapVars( pTruth, 6, iVar1, --nVars );
// remove iVar0
pVars[iVar1] = pVars[nVars-1]; iVar0 = Dau_DsdFindVarDef( pVars, nVars, VarId );
Abc_TtSwapVars( pTruth, 6, iVar1, nVars-1 ); ABC_SWAP( int, pVars[iVar0], pVars[nVars-1] );
pVars[iVar0] = pVars[nVars-2]; Abc_TtSwapVars( pTruth, 6, iVar0, --nVars );
Abc_TtSwapVars( pTruth, 6, iVar0, nVars-2 ); // find the new var
nVars -= 2; v = Dau_DsdFindVarDef( pVars, nVars, p->nVarsUsed-1 );
return Dau_Dsd6DecomposeSingleVar( p, pTruth, pVars, nVars ); // remove single variables if possible
if ( Dau_Dsd6DecomposeSingleVarOne( p, pTruth, pVars, nVars, v ) )
nVars = Dau_Dsd6DecomposeSingleVar( p, pTruth, pVars, --nVars );
return nVars;
} }
return nVars; return nVars;
} }
...@@ -1134,13 +1246,14 @@ int Dau_Dsd6DecomposeTripleVars( Dau_Dsd_t * p, word * pTruth, int * pVars, int ...@@ -1134,13 +1246,14 @@ int Dau_Dsd6DecomposeTripleVars( Dau_Dsd_t * p, word * pTruth, int * pVars, int
while ( 1 ) while ( 1 )
{ {
int v; int v;
// Kit_DsdPrintFromTruth( (unsigned *)pTruth, 6 ); printf( "\n" );
for ( v = nVars - 1; v >= 0; v-- ) for ( v = nVars - 1; v >= 0; v-- )
{ {
unsigned uSupports = Dau_Dsd6FindSupports( p, pTruth, pVars, nVars, v ); unsigned uSupports = Dau_Dsd6FindSupports( p, pTruth, pVars, nVars, v );
Dau_DsdPrintSupports( uSupports, nVars ); // Dau_DsdPrintSupports( uSupports, nVars );
if ( (uSupports & (uSupports >> 1) & 0x55555555) == 0 ) // non-overlapping supports if ( (uSupports & (uSupports >> 1) & 0x55555555) == 0 ) // non-overlapping supports
return Dau_Dsd6DecomposeTripleVarsOuter( p, pTruth, pVars, nVars, v ); return Dau_Dsd6DecomposeTripleVarsOuter( p, pTruth, pVars, nVars, v );
if ( Abc_TtSuppOnlyOne( uSupports & (~uSupports >> 1) & 0x55555555) || if ( Abc_TtSuppOnlyOne( uSupports & (~uSupports >> 1) & 0x55555555) &&
Abc_TtSuppOnlyOne(~uSupports & ( uSupports >> 1) & 0x55555555) ) // one unique variable in each cofactor Abc_TtSuppOnlyOne(~uSupports & ( uSupports >> 1) & 0x55555555) ) // one unique variable in each cofactor
{ {
nVars = Dau_Dsd6DecomposeTripleVarsInner( p, pTruth, pVars, nVars, v, uSupports ); nVars = Dau_Dsd6DecomposeTripleVarsInner( p, pTruth, pVars, nVars, v, uSupports );
...@@ -1246,6 +1359,7 @@ char * Dau_DsdDecompose( word * pTruth, int nVarsInit, int * pnSizeNonDec ) ...@@ -1246,6 +1359,7 @@ char * Dau_DsdDecompose( word * pTruth, int nVarsInit, int * pnSizeNonDec )
{ {
static Dau_Dsd_t P; static Dau_Dsd_t P;
Dau_Dsd_t * p = &P; Dau_Dsd_t * p = &P;
p->nSizeNonDec = 0;
if ( (pTruth[0] & 1) == 0 && Abc_TtIsConst0(pTruth, Abc_TtWordNum(nVarsInit)) ) if ( (pTruth[0] & 1) == 0 && Abc_TtIsConst0(pTruth, Abc_TtWordNum(nVarsInit)) )
p->pOutput[0] = '0', p->pOutput[1] = 0; p->pOutput[0] = '0', p->pOutput[1] = 0;
else if ( (pTruth[0] & 1) && Abc_TtIsConst1(pTruth, Abc_TtWordNum(nVarsInit)) ) else if ( (pTruth[0] & 1) && Abc_TtIsConst1(pTruth, Abc_TtWordNum(nVarsInit)) )
...@@ -1254,24 +1368,68 @@ char * Dau_DsdDecompose( word * pTruth, int nVarsInit, int * pnSizeNonDec ) ...@@ -1254,24 +1368,68 @@ char * Dau_DsdDecompose( word * pTruth, int nVarsInit, int * pnSizeNonDec )
{ {
Dau_DsdDecomposeInt( p, pTruth, nVarsInit ); Dau_DsdDecomposeInt( p, pTruth, nVarsInit );
Dau_DsdCleanBraces( p->pOutput ); Dau_DsdCleanBraces( p->pOutput );
}
if ( pnSizeNonDec ) if ( pnSizeNonDec )
*pnSizeNonDec = p->nSizeNonDec; *pnSizeNonDec = p->nSizeNonDec;
}
return p->pOutput; return p->pOutput;
} }
void Dau_DsdTest() void Dau_DsdTest()
{ {
// char * pStr = "(!(!a<bcd>)!(!fe))"; // char * pStr = "(!(!a<bcd>)!(!fe))";
// char * pStr = "<cba>"; // char * pStr = "([acb]<!edf>)";
// char * pStr = "!(f!(b!c!(d[ea])))"; // char * pStr = "!(f!(b!c!(d[ea])))";
char * pStr = "[!(a[be])!(c!df)]"; // char * pStr = "[!(a[be])!(c!df)]";
// char * pStr = "<(a<bcd>)ef>";
char * pStr = "[d8001{a(!bc)ef}]";
char * pStr2; char * pStr2;
word t = Dau_DsdToTruth( pStr ); word t = Dau_DsdToTruth( pStr );
return; // return;
pStr2 = Dau_DsdDecompose( &t, 6, NULL ); pStr2 = Dau_DsdDecompose( &t, 6, NULL );
t = 0; t = 0;
} }
void Dau_DsdTest22()
{
char * pFileName = "_npn/npn/dsd06.txt";
FILE * pFile = fopen( pFileName, "rb" );
word t, t1, t2;
char pBuffer[100];
char * pStr2;
int nSizeNonDec;
int i, Counter = 0;
while ( fgets( pBuffer, 100, pFile ) != NULL )
{
pStr2 = pBuffer + strlen(pBuffer)-1;
if ( *pStr2 == '\n' )
*pStr2-- = 0;
if ( *pStr2 == '\r' )
*pStr2-- = 0;
if ( pBuffer[0] == 'V' || pBuffer[0] == 0 )
continue;
Counter++;
for ( i = 0; i < 10; i++ )
{
Dau_DsdPermute( pBuffer );
t = t1 = Dau_DsdToTruth( pBuffer[0] == '*' ? pBuffer + 1 : pBuffer );
pStr2 = Dau_DsdDecompose( &t, 6, &nSizeNonDec );
assert( nSizeNonDec == 0 );
t2 = Dau_DsdToTruth( pStr2 );
if ( t1 != t2 )
{
// Kit_DsdPrintFromTruth( (unsigned *)&t, 6 );
// printf( " " );
// Kit_DsdPrintFromTruth( (unsigned *)&t2, 6 );
printf( "%s -> %s \n", pBuffer, pStr2 );
printf( "Verification failed.\n" );
}
}
}
printf( "Finished trying %d decompositions.\n", Counter );
fclose( pFile );
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment