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