Commit 4f093483 by Alan Mishchenko

Experiments with permutations.

parent d80efa1b
...@@ -10449,7 +10449,11 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -10449,7 +10449,11 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
} }
{ {
extern void Abc_EnumerateCubeStates(); extern void Abc_EnumerateCubeStates();
Abc_EnumerateCubeStates(); extern void Abc_EnumerateCubeStatesZdd();
if ( fNewAlgo )
Abc_EnumerateCubeStatesZdd();
else
Abc_EnumerateCubeStates();
return 0; return 0;
} }
if ( pNtk ) if ( pNtk )
...@@ -128,6 +128,7 @@ static inline int Abc_ZddCacheInsert( Abc_ZddMan * p, int Arg0, int Arg1, int Ar ...@@ -128,6 +128,7 @@ static inline int Abc_ZddCacheInsert( Abc_ZddMan * p, int Arg0, int Arg1, int Ar
Abc_ZddEnt * pEnt = p->pCache + (Abc_ZddHash(Arg0, Arg1, Arg2) & p->nCacheMask); Abc_ZddEnt * pEnt = p->pCache + (Abc_ZddHash(Arg0, Arg1, Arg2) & p->nCacheMask);
pEnt->Arg0 = Arg0; pEnt->Arg1 = Arg1; pEnt->Arg2 = Arg2; pEnt->Res = Res; pEnt->Arg0 = Arg0; pEnt->Arg1 = Arg1; pEnt->Arg2 = Arg2; pEnt->Res = Res;
p->nCacheMisses++; p->nCacheMisses++;
assert( Res >= 0 );
return Res; return Res;
} }
static inline int Abc_ZddUniqueLookup( Abc_ZddMan * p, int Var, int True, int False ) static inline int Abc_ZddUniqueLookup( Abc_ZddMan * p, int Var, int True, int False )
...@@ -394,12 +395,11 @@ int Abc_ZddMultiply( Abc_ZddMan * p, int a, int Var ) ...@@ -394,12 +395,11 @@ int Abc_ZddMultiply( Abc_ZddMan * p, int a, int Var )
if ( (int)A->Var > Var ) if ( (int)A->Var > Var )
r = Abc_ZddUniqueCreate( p, Var, a, 0 ); r = Abc_ZddUniqueCreate( p, Var, a, 0 );
else if ( (int)A->Var < Var ) else if ( (int)A->Var < Var )
{
r0 = Abc_ZddMultiply( p, A->False, Var ), r0 = Abc_ZddMultiply( p, A->False, Var ),
r1 = Abc_ZddMultiply( p, A->True, Var ); r1 = Abc_ZddMultiply( p, A->True, Var ),
r = Abc_ZddUniqueCreate( p, A->Var, r1, r0 ); r = Abc_ZddUniqueCreate( p, A->Var, r1, r0 );
} else
else assert( 0 ); r = Abc_ZddUniqueCreate( p, A->Var, A->False, A->True );
return Abc_ZddCacheInsert( p, a, Var, ABC_ZDD_OPER_MULTIPLY, r ); return Abc_ZddCacheInsert( p, a, Var, ABC_ZDD_OPER_MULTIPLY, r );
} }
int Abc_ZddCountPaths( Abc_ZddMan * p, int a ) int Abc_ZddCountPaths( Abc_ZddMan * p, int a )
...@@ -555,55 +555,54 @@ int Abc_ZddDotMinProduct6( Abc_ZddMan * p, int a, int b ) ...@@ -555,55 +555,54 @@ int Abc_ZddDotMinProduct6( Abc_ZddMan * p, int a, int b )
int Abc_ZddPerm( Abc_ZddMan * p, int a, int Var ) int Abc_ZddPerm( Abc_ZddMan * p, int a, int Var )
{ {
Abc_ZddObj * A; Abc_ZddObj * A;
int r; int r0, r1, r;
assert( Var < p->nVars ); assert( Var < p->nVars );
if ( a == 0 ) return 0; if ( a == 0 ) return 0;
if ( a == 1 ) return Abc_ZddIthVar(Var); if ( a == 1 ) return Abc_ZddIthVar(Var);
if ( (r = Abc_ZddCacheLookup(p, a, Var, ABC_ZDD_OPER_PERM)) >= 0 ) if ( (r = Abc_ZddCacheLookup(p, a, Var, ABC_ZDD_OPER_PERM)) >= 0 )
return r; return r;
A = Abc_ZddNode( p, a ); A = Abc_ZddNode( p, a );
if ( (int)A->Var == Var ) if ( p->pV2TI[A->Var] > p->pV2TI[Var] ) // Ai > Bi
r = Abc_ZddUniqueCreate( p, A->Var, A->False, A->True );
else if ( p->pV2TI[A->Var] > p->pV2TJ[Var] )
r = Abc_ZddUniqueCreate( p, Var, a, 0 ); r = Abc_ZddUniqueCreate( p, Var, a, 0 );
else if ( (int)A->Var == Var ) // Ai == Bi && Aj == Bj
r0 = Abc_ZddPerm( p, A->False, Var ),
r = Abc_ZddUnion( p, r0, A->True );
else else
{ {
int r0, r1, VarTop, VarPerm; int VarPerm, VarTop;
int Ai = p->pV2TI[A->Var]; int Ai = p->pV2TI[A->Var];
int Aj = p->pV2TJ[A->Var]; int Aj = p->pV2TJ[A->Var];
int Bi = p->pV2TI[Var]; int Bi = p->pV2TI[Var];
int Bj = p->pV2TJ[Var]; int Bj = p->pV2TJ[Var];
assert( Ai < Aj && Bi < Bj ); assert( Ai < Aj && Bi < Bj && Ai <= Bi );
if ( Ai == Bj || (Ai == Bi && Aj > Bj) || (Aj == Bj && Ai > Bi) ) if ( Aj == Bi )
VarTop = Var, VarPerm = Var,
VarPerm = A->Var; VarTop = Abc_ZddVarIJ(p, Ai, Bj);
else if ( Ai == Bi )
VarTop = A->Var,
VarPerm = Abc_ZddVarIJ(p, Aj, Bj);
else if ( Aj == Bj ) else if ( Aj == Bj )
VarTop = Abc_ZddVarIJ(p, Ai, Bi), VarPerm = Var,
VarPerm = Abc_ZddVarIJ(p, Bi, Bj); VarTop = Abc_ZddVarIJ(p, Ai, Bi);
else if ( Aj == Bi ) else if ( Ai == Bi )
VarTop = A->Var, VarPerm = Abc_ZddVarIJ(p, Abc_MinInt(Aj, Bj), Abc_MaxInt(Aj, Bj)),
VarPerm = Abc_ZddVarIJ(p, Ai, Bj); VarTop = A->Var;
else // no clash else // no clash
VarTop = A->Var, VarPerm = Var,
VarPerm = Var; VarTop = A->Var;
assert( p->pV2TI[VarPerm] > p->pV2TI[VarTop] );
r0 = Abc_ZddPerm( p, A->False, Var ); r0 = Abc_ZddPerm( p, A->False, Var );
r1 = Abc_ZddPerm( p, A->True, VarPerm ); r1 = Abc_ZddPerm( p, A->True, VarPerm );
if ( VarTop < Abc_ZddObjVar(p, r0) && VarTop < Abc_ZddObjVar(p, r1) ) assert( Abc_ZddObjVar(p, r1) > VarTop );
if ( Abc_ZddObjVar(p, r0) > VarTop )
r = Abc_ZddUniqueCreate( p, VarTop, r1, r0 ); r = Abc_ZddUniqueCreate( p, VarTop, r1, r0 );
else else
{ r1 = Abc_ZddUniqueCreate( p, VarTop, r1, 0 ),
r1 = Abc_ZddMultiply( p, r1, VarTop );
r = Abc_ZddUnion( p, r0, r1 ); r = Abc_ZddUnion( p, r0, r1 );
}
} }
return Abc_ZddCacheInsert( p, a, Var, ABC_ZDD_OPER_PERM, r ); return Abc_ZddCacheInsert( p, a, Var, ABC_ZDD_OPER_PERM, r );
} }
int Abc_ZddPermProduct( Abc_ZddMan * p, int a, int b ) int Abc_ZddPermProduct( Abc_ZddMan * p, int a, int b )
{ {
Abc_ZddObj * A, * B; Abc_ZddObj * B;
int r0, r1, r; int r0, r1, r;
if ( a == 0 ) return 0; if ( a == 0 ) return 0;
if ( a == 1 ) return b; if ( a == 1 ) return b;
...@@ -611,27 +610,11 @@ int Abc_ZddPermProduct( Abc_ZddMan * p, int a, int b ) ...@@ -611,27 +610,11 @@ int Abc_ZddPermProduct( Abc_ZddMan * p, int a, int b )
if ( b == 1 ) return a; if ( b == 1 ) return a;
if ( (r = Abc_ZddCacheLookup(p, a, b, ABC_ZDD_OPER_PERM_PROD)) >= 0 ) if ( (r = Abc_ZddCacheLookup(p, a, b, ABC_ZDD_OPER_PERM_PROD)) >= 0 )
return r; return r;
A = Abc_ZddNode( p, a ); B = Abc_ZddNode( p, b );
B = Abc_ZddNode( p, b ); r0 = Abc_ZddPermProduct( p, a, B->False );
if ( Abc_ZddVarsClash(p, A->Var, B->Var) ) r1 = Abc_ZddPermProduct( p, a, B->True );
{ r1 = Abc_ZddPerm( p, r1, B->Var );
r0 = Abc_ZddPermProduct( p, a, B->False ); r = Abc_ZddUnion( p, r0, r1 );
r1 = Abc_ZddPermProduct( p, a, B->True );
r1 = Abc_ZddPerm( p, r1, B->Var );
r = Abc_ZddUnion( p, r1, r0 );
assert( Abc_MinInt(A->Var, B->Var) <= (int)Abc_ZddObjVar(p, r) );
}
else
{
if ( A->Var < B->Var )
r0 = Abc_ZddPermProduct( p, A->False, b ),
r1 = Abc_ZddPermProduct( p, A->True, b );
else if ( A->Var > B->Var )
r0 = Abc_ZddPermProduct( p, a, B->False ),
r1 = Abc_ZddPermProduct( p, a, B->True );
else assert( 0 );
r = Abc_ZddUniqueCreate( p, Abc_MinInt(A->Var, B->Var), r1, r0 );
}
return Abc_ZddCacheInsert( p, a, b, ABC_ZDD_OPER_PERM_PROD, r ); return Abc_ZddCacheInsert( p, a, b, ABC_ZDD_OPER_PERM_PROD, r );
} }
...@@ -651,12 +634,14 @@ void Abc_ZddPermPrint( int * pPerm, int Size ) ...@@ -651,12 +634,14 @@ void Abc_ZddPermPrint( int * pPerm, int Size )
int i; int i;
printf( "{" ); printf( "{" );
for ( i = 0; i < Size; i++ ) for ( i = 0; i < Size; i++ )
printf( " %d", pPerm[i] ); printf( " %2d", pPerm[i] );
printf( " }\n" ); printf( " }\n" );
} }
void Abc_ZddCombPrint( int * pComb, int nTrans ) void Abc_ZddCombPrint( int * pComb, int nTrans )
{ {
int i; int i;
if ( nTrans == 0 )
printf( "Empty set" );
for ( i = 0; i < nTrans; i++ ) for ( i = 0; i < nTrans; i++ )
printf( "(%d %d)", pComb[i] >> 16, pComb[i] & 0xffff ); printf( "(%d %d)", pComb[i] >> 16, pComb[i] & 0xffff );
printf( "\n" ); printf( "\n" );
...@@ -715,11 +700,11 @@ void Abc_ZddPrint_rec( Abc_ZddMan * p, int a, int * pPath, int Size ) ...@@ -715,11 +700,11 @@ void Abc_ZddPrint_rec( Abc_ZddMan * p, int a, int * pPath, int Size )
// if ( a == 1 ) { Abc_ZddPermPrint( pPath, Size ); return; } // if ( a == 1 ) { Abc_ZddPermPrint( pPath, Size ); return; }
if ( a == 1 ) if ( a == 1 )
{ {
int pPerm[10], pComb[10], i; int pPerm[24], pComb[24], i;
assert( p->nPermSize <= 10 ); assert( p->nPermSize <= 24 );
for ( i = 0; i < Size; i++ ) for ( i = 0; i < Size; i++ )
pComb[i] = (p->pV2TI[pPath[i]] << 16) | p->pV2TJ[pPath[i]]; pComb[i] = (p->pV2TI[pPath[i]] << 16) | p->pV2TJ[pPath[i]];
// Abc_ZddCombPrint( pComb, Size ); Abc_ZddCombPrint( pComb, Size );
Abc_ZddComb2Perm( pComb, Size, pPerm, p->nPermSize ); Abc_ZddComb2Perm( pComb, Size, pPerm, p->nPermSize );
Abc_ZddPermPrint( pPerm, p->nPermSize ); Abc_ZddPermPrint( pPerm, p->nPermSize );
return; return;
...@@ -858,6 +843,78 @@ void Abc_ZddPermTest() ...@@ -858,6 +843,78 @@ void Abc_ZddPermTest()
Abc_ZddManFree( p ); Abc_ZddManFree( p );
} }
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_EnumerateCubeStatesZdd()
{
int pXYZ[3][9][2] = {
{ {3, 5}, {3,17}, {3,15}, {1, 6}, {1,16}, {1,14}, {2, 4}, {2,18}, {2,13} },
{ {2,14}, {2,24}, {2,12}, {3,13}, {3,23}, {3,10}, {1,15}, {1,22}, {1,11} },
{ {1,10}, {1, 7}, {1, 4}, {3,12}, {3, 9}, {3, 6}, {2,11}, {2, 8}, {2, 5} } };
Abc_ZddMan * p;
int i, k, pComb[9], pPerm[24], nSize;
int ZddTurn1, ZddTurn2, ZddTurn3, ZddTurns9, ZddAll, ZddReached, ZddNew;
abctime clk = Abc_Clock();
printf( "Enumerating states of 2x2x2 cube.\n" );
p = Abc_ZddManAlloc( 24 * 23 / 2, 1 << 28 );
Abc_ZddManCreatePerms( p, 24 );
// init state
printf( "Iter %2d -> %8d ", 0, 1 );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
// first 9 states
ZddTurns9 = 0;
for ( i = 0; i < 3; i++ )
{
for ( k = 0; k < 24; k++ )
pPerm[k] = k;
for ( k = 0; k < 9; k++ )
ABC_SWAP( int, pPerm[pXYZ[i][k][0]-1], pPerm[pXYZ[i][k][1]-1] );
nSize = Abc_ZddPerm2Comb( pPerm, 24, pComb );
assert( nSize == 9 );
for ( k = 0; k < 9; k++ )
pComb[k] = Abc_ZddVarIJ( p, pComb[k] >> 16, pComb[k] & 0xffff );
// add first turn
ZddTurn1 = Abc_ZddBuildSet( p, pComb, 9 );
ZddTurns9 = Abc_ZddUnion( p, ZddTurns9, ZddTurn1 );
//Abc_ZddPrint( p, ZddTurn1 );
// add second turn
ZddTurn2 = Abc_ZddPermProduct( p, ZddTurn1, ZddTurn1 );
ZddTurns9 = Abc_ZddUnion( p, ZddTurns9, ZddTurn2 );
//Abc_ZddPrint( p, ZddTurn2 );
// add third turn
ZddTurn3 = Abc_ZddPermProduct( p, ZddTurn2, ZddTurn1 );
ZddTurns9 = Abc_ZddUnion( p, ZddTurns9, ZddTurn3 );
//Abc_ZddPrint( p, ZddTurn3 );
//printf( "\n" );
}
//Abc_ZddPrint( p, ZddTurns9 );
printf( "Iter %2d -> %8d ", 1, Abc_ZddCountPaths(p, ZddTurns9) );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
// other states
ZddNew = ZddTurns9;
ZddAll = Abc_ZddUnion( p, 1, ZddTurns9 );
for ( i = 2; i <= 100; i++ )
{
ZddReached = Abc_ZddPermProduct( p, ZddNew, ZddTurns9 );
ZddNew = Abc_ZddDiff( p, ZddReached, ZddAll );
ZddAll = Abc_ZddUnion( p, ZddAll, ZddNew );
printf( "Iter %2d -> %8d ", i, Abc_ZddCountPaths(p, ZddNew) );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
if ( ZddNew == 0 )
break;
}
Abc_ZddManFree( p );
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
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