00001
00019 #include "abc.h"
00020 #include "fxuInt.h"
00021 #include "fxu.h"
00022
00026
00027 static int Fxu_CountPairDiffs( char * pCover, unsigned char pDiffs[] );
00028
00032
00050 int Fxu_PreprocessCubePairs( Fxu_Matrix * p, Vec_Ptr_t * vCovers, int nPairsTotal, int nPairsMax )
00051 {
00052 unsigned char * pnLitsDiff;
00053 int * pnPairCounters;
00054 Fxu_Cube * pCubeFirst, * pCubeLast;
00055 Fxu_Cube * pCube1, * pCube2;
00056 Fxu_Var * pVar;
00057 int nCubes, nBitsMax, nSum;
00058 int CutOffNum, CutOffQuant;
00059 int iPair, iQuant, k, c;
00060 int clk = clock();
00061 char * pSopCover;
00062 int nFanins;
00063
00064 assert( nPairsMax < nPairsTotal );
00065
00066
00067 pnLitsDiff = ALLOC( unsigned char, nPairsTotal );
00068
00069 iPair = 0;
00070 nBitsMax = -1;
00071 for ( c = 0; c < vCovers->nSize; c++ )
00072 if ( pSopCover = vCovers->pArray[c] )
00073 {
00074 nFanins = Abc_SopGetVarNum(pSopCover);
00075
00076 Fxu_CountPairDiffs( pSopCover, pnLitsDiff + iPair );
00077
00078 nCubes = Abc_SopGetCubeNum( pSopCover );
00079 iPair += nCubes * (nCubes - 1) / 2;
00080 if ( nBitsMax < nFanins )
00081 nBitsMax = nFanins;
00082 }
00083 assert( iPair == nPairsTotal );
00084
00085
00086 pnPairCounters = ALLOC( int, 2 * nBitsMax );
00087 memset( pnPairCounters, 0, sizeof(int) * 2 * nBitsMax );
00088
00089 for ( k = 0; k < nPairsTotal; k++ )
00090 pnPairCounters[ pnLitsDiff[k] ]++;
00091
00092
00093 if ( pnPairCounters[0] != 0 )
00094 {
00095 printf( "The SOPs of the nodes are not cube-free. Run \"bdd; sop\" before \"fx\".\n" );
00096 return 0;
00097 }
00098 if ( pnPairCounters[1] != 0 )
00099 {
00100 printf( "The SOPs of the nodes are not SCC-free. Run \"bdd; sop\" before \"fx\".\n" );
00101 return 0;
00102 }
00103 assert( pnPairCounters[0] == 0 );
00104 assert( pnPairCounters[1] == 0 );
00105 nSum = 0;
00106 for ( k = 0; k < 2 * nBitsMax; k++ )
00107 {
00108 nSum += pnPairCounters[k];
00109 if ( nSum >= nPairsMax )
00110 {
00111 CutOffNum = k;
00112 CutOffQuant = pnPairCounters[k] - (nSum - nPairsMax);
00113 break;
00114 }
00115 }
00116 FREE( pnPairCounters );
00117
00118
00119 iQuant = 0;
00120 iPair = 0;
00121 for ( k = 0; k < nPairsTotal; k++ )
00122 if ( pnLitsDiff[k] > CutOffNum )
00123 pnLitsDiff[k] = 0;
00124 else if ( pnLitsDiff[k] == CutOffNum )
00125 {
00126 if ( iQuant++ >= CutOffQuant )
00127 pnLitsDiff[k] = 0;
00128 else
00129 iPair++;
00130 }
00131 else
00132 iPair++;
00133 assert( iPair == nPairsMax );
00134
00135
00136 iPair = 0;
00137 for ( c = 0; c < vCovers->nSize; c++ )
00138 if ( pSopCover = vCovers->pArray[c] )
00139 {
00140
00141 pVar = p->ppVars[2*c+1];
00142
00143 pCubeFirst = pVar->pFirst;
00144
00145 pCubeLast = pCubeFirst;
00146 for ( k = 0; k < pVar->nCubes; k++ )
00147 pCubeLast = pCubeLast->pNext;
00148 assert( pCubeLast == NULL || pCubeLast->pVar != pVar );
00149
00150
00151 for ( pCube1 = pCubeFirst; pCube1 != pCubeLast; pCube1 = pCube1->pNext )
00152 for ( pCube2 = pCube1->pNext; pCube2 != pCubeLast; pCube2 = pCube2->pNext )
00153 if ( pnLitsDiff[iPair++] )
00154 {
00155 Fxu_MatrixAddDivisor( p, pCube1, pCube2 );
00156 }
00157 }
00158 assert( iPair == nPairsTotal );
00159 FREE( pnLitsDiff );
00160
00161 return 1;
00162 }
00163
00164
00181 int Fxu_CountPairDiffs( char * pCover, unsigned char pDiffs[] )
00182 {
00183 char * pCube1, * pCube2;
00184 int nOnes, nCubePairs, nFanins, v;
00185 nCubePairs = 0;
00186 nFanins = Abc_SopGetVarNum(pCover);
00187 Abc_SopForEachCube( pCover, nFanins, pCube1 )
00188 Abc_SopForEachCube( pCube1, nFanins, pCube2 )
00189 {
00190 if ( pCube1 == pCube2 )
00191 continue;
00192 nOnes = 0;
00193 for ( v = 0; v < nFanins; v++ )
00194 nOnes += (pCube1[v] != pCube2[v]);
00195 pDiffs[nCubePairs++] = nOnes;
00196 }
00197 return 1;
00198 }
00199
00203
00204