00001
00019 #include "mvc.h"
00020
00024
00025 static void Mvc_CoverVerifyDivision( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t * pQuo, Mvc_Cover_t * pRem );
00026
00027 int s_fVerbose = 0;
00028
00032
00044 void Mvc_CoverDivide( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t ** ppQuo, Mvc_Cover_t ** ppRem )
00045 {
00046
00047 if ( Mvc_CoverReadCubeNum( pCover ) < Mvc_CoverReadCubeNum( pDiv ) )
00048 {
00049 *ppQuo = NULL;
00050 *ppRem = NULL;
00051 return;
00052 }
00053
00054
00055 if ( !Mvc_CoverCheckSuppContainment( pCover, pDiv ) )
00056 {
00057 *ppQuo = NULL;
00058 *ppRem = NULL;
00059 return;
00060 }
00061
00062
00063 Mvc_CoverDivideInternal( pCover, pDiv, ppQuo, ppRem );
00064 }
00065
00066
00078 void Mvc_CoverDivideInternal( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t ** ppQuo, Mvc_Cover_t ** ppRem )
00079 {
00080 Mvc_Cover_t * pQuo, * pRem;
00081 Mvc_Cube_t * pCubeC, * pCubeD, * pCubeCopy;
00082 Mvc_Cube_t * pCube1, * pCube2;
00083 int * pGroups, nGroups;
00084 int nCubesC, nCubesD, nMerges, iCubeC, iCubeD, iMerge;
00085 int fSkipG, GroupSize, g, c, RetValue;
00086 int nCubes;
00087
00088
00089 nCubesD = Mvc_CoverReadCubeNum( pDiv );
00090 nCubesC = Mvc_CoverReadCubeNum( pCover );
00091
00092
00093 if ( nCubesD == 1 )
00094 {
00095 if ( Mvc_CoverIsOneLiteral( pDiv ) )
00096 Mvc_CoverDivideByLiteral( pCover, pDiv, ppQuo, ppRem );
00097 else
00098 Mvc_CoverDivideByCube( pCover, pDiv, ppQuo, ppRem );
00099 return;
00100 }
00101
00102
00103 pQuo = Mvc_CoverAlloc( pCover->pMem, pCover->nBits );
00104 pRem = Mvc_CoverAlloc( pCover->pMem, pCover->nBits );
00105
00106
00107 Mvc_CoverAllocateMask( pDiv );
00108 Mvc_CoverSupport( pDiv, pDiv->pMask );
00109
00110
00111 Mvc_CoverSort( pDiv, NULL, Mvc_CubeCompareInt );
00112
00113 Mvc_CoverSort( pCover, pDiv->pMask, Mvc_CubeCompareIntOutsideAndUnderMask );
00114
00115
00116 pGroups = MEM_ALLOC( pCover->pMem, int, nCubesC + 1 );
00117
00118
00119
00120 Mvc_CoverList2Array( pCover );
00121 Mvc_CoverList2Array( pDiv );
00122 pGroups[0] = 0;
00123 nGroups = 1;
00124 for ( c = 1; c < nCubesC; c++ )
00125 {
00126
00127 pCube1 = pCover->pCubes[c-1];
00128 pCube2 = pCover->pCubes[c ];
00129
00130 Mvc_CubeBitEqualOutsideMask( RetValue, pCube1, pCube2, pDiv->pMask );
00131 if ( !RetValue )
00132 pGroups[nGroups++] = c;
00133 }
00134
00135 pGroups[nGroups] = nCubesC;
00136
00137
00138
00139 nCubes = 0;
00140 for ( g = 0; g < nGroups; g++ )
00141 {
00142
00143
00144
00145 GroupSize = pGroups[g+1] - pGroups[g];
00146 if ( GroupSize < nCubesD )
00147 {
00148 for ( c = pGroups[g]; c < pGroups[g+1]; c++ )
00149 {
00150 pCubeCopy = Mvc_CubeDup( pRem, pCover->pCubes[c] );
00151 Mvc_CoverAddCubeTail( pRem, pCubeCopy );
00152 nCubes++;
00153 }
00154 continue;
00155 }
00156
00157
00158 for ( c = pGroups[g]; c < pGroups[g+1]; c++ )
00159 Mvc_CubeSetSize( pCover->pCubes[c], 1 );
00160
00161
00162
00163 iCubeD = 0;
00164 iCubeC = 0;
00165 pCubeD = pDiv->pCubes[iCubeD++];
00166 pCubeC = pCover->pCubes[pGroups[g]+iCubeC++];
00167 fSkipG = 0;
00168 nMerges = 0;
00169
00170 while ( 1 )
00171 {
00172
00173 RetValue = Mvc_CubeCompareIntUnderMask( pCubeC, pCubeD, pDiv->pMask );
00174
00175 if ( RetValue == -1 )
00176 {
00177
00178 if ( GroupSize - iCubeC < nCubesD - nMerges )
00179 {
00180 fSkipG = 1;
00181 break;
00182 }
00183
00184 pCubeC = pCover->pCubes[pGroups[g]+iCubeC++];
00185 continue;
00186 }
00187 if ( RetValue == 1 )
00188 {
00189 fSkipG = 1;
00190 break;
00191 }
00192
00193 Mvc_CubeSetSize( pCubeC, 0 );
00194
00195 iMerge = iCubeC-1;
00196 nMerges++;
00197
00198
00199 if ( iCubeD == nCubesD )
00200 break;
00201
00202
00203 assert( iCubeD < nCubesD );
00204 pCubeD = pDiv->pCubes[iCubeD++];
00205
00206
00207 assert( pGroups[g]+iCubeC < nCubesC );
00208 pCubeC = pCover->pCubes[pGroups[g]+iCubeC++];
00209 }
00210
00211 if ( fSkipG )
00212 {
00213
00214 for ( c = pGroups[g]; c < pGroups[g+1]; c++ )
00215 {
00216 pCubeCopy = Mvc_CubeDup( pRem, pCover->pCubes[c] );
00217 Mvc_CoverAddCubeTail( pRem, pCubeCopy );
00218 nCubes++;
00219 }
00220 continue;
00221 }
00222
00223
00224 for ( c = pGroups[g]; c < pGroups[g+1]; c++ )
00225 {
00226 pCubeC = pCover->pCubes[c];
00227 if ( Mvc_CubeReadSize(pCubeC) )
00228 {
00229 pCubeCopy = Mvc_CubeDup( pRem, pCubeC );
00230 Mvc_CoverAddCubeTail( pRem, pCubeCopy );
00231 nCubes++;
00232 }
00233 }
00234
00235
00236 pCube1 = Mvc_CubeAlloc( pQuo );
00237 Mvc_CubeBitSharp( pCube1, pCover->pCubes[pGroups[g]+iMerge], pDiv->pMask );
00238
00239 Mvc_CoverAddCubeTail( pQuo, pCube1 );
00240 nCubes += nCubesD;
00241 }
00242 assert( nCubes == nCubesC );
00243
00244
00245 MEM_FREE( pCover->pMem, int, nCubesC + 1, pGroups );
00246
00247
00248 *ppRem = pRem;
00249 *ppQuo = pQuo;
00250
00251 }
00252
00253
00265 void Mvc_CoverDivideByCube( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t ** ppQuo, Mvc_Cover_t ** ppRem )
00266 {
00267 Mvc_Cover_t * pQuo, * pRem;
00268 Mvc_Cube_t * pCubeC, * pCubeD, * pCubeCopy;
00269 int CompResult;
00270
00271
00272 assert( Mvc_CoverReadCubeNum(pDiv) == 1 );
00273
00274
00275 pQuo = Mvc_CoverAlloc( pCover->pMem, pCover->nBits );
00276 pRem = Mvc_CoverAlloc( pCover->pMem, pCover->nBits );
00277
00278
00279 pCubeD = Mvc_CoverReadCubeHead( pDiv );
00280
00281
00282 Mvc_CoverForEachCube( pCover, pCubeC )
00283 {
00284
00285 Mvc_Cube2BitNotImpl( CompResult, pCubeD, pCubeC );
00286 if ( !CompResult )
00287 {
00288
00289 pCubeCopy = Mvc_CubeAlloc( pQuo );
00290
00291 Mvc_CubeBitSharp( pCubeCopy, pCubeC, pCubeD );
00292
00293 Mvc_CoverAddCubeTail( pQuo, pCubeCopy );
00294 }
00295 else
00296 {
00297
00298 pCubeCopy = Mvc_CubeDup( pRem, pCubeC );
00299
00300 Mvc_CoverAddCubeTail( pRem, pCubeCopy );
00301 }
00302 }
00303
00304 *ppRem = pRem;
00305 *ppQuo = pQuo;
00306 }
00307
00319 void Mvc_CoverDivideByLiteral( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t ** ppQuo, Mvc_Cover_t ** ppRem )
00320 {
00321 Mvc_Cover_t * pQuo, * pRem;
00322 Mvc_Cube_t * pCubeC, * pCubeCopy;
00323 int iLit;
00324
00325
00326 assert( Mvc_CoverReadCubeNum(pDiv) == 1 );
00327
00328
00329 pQuo = Mvc_CoverAlloc( pCover->pMem, pCover->nBits );
00330 pRem = Mvc_CoverAlloc( pCover->pMem, pCover->nBits );
00331
00332
00333 iLit = Mvc_CoverFirstCubeFirstLit( pDiv );
00334
00335
00336 Mvc_CoverForEachCube( pCover, pCubeC )
00337 {
00338
00339 pCubeCopy = Mvc_CubeDup( pCover, pCubeC );
00340
00341 if ( Mvc_CubeBitValue( pCubeCopy, iLit ) )
00342 {
00343 Mvc_CubeBitRemove( pCubeCopy, iLit );
00344
00345 Mvc_CoverAddCubeTail( pQuo, pCubeCopy );
00346 }
00347 else
00348 {
00349 Mvc_CoverAddCubeTail( pRem, pCubeCopy );
00350 }
00351 }
00352
00353 *ppRem = pRem;
00354 *ppQuo = pQuo;
00355 }
00356
00357
00370 void Mvc_CoverDivideByLiteralQuo( Mvc_Cover_t * pCover, int iLit )
00371 {
00372 Mvc_Cube_t * pCube, * pCube2, * pPrev;
00373
00374
00375 pPrev = NULL;
00376 Mvc_CoverForEachCubeSafe( pCover, pCube, pCube2 )
00377 {
00378 if ( Mvc_CubeBitValue( pCube, iLit ) == 0 )
00379 {
00380 Mvc_CoverDeleteCube( pCover, pPrev, pCube );
00381 Mvc_CubeFree( pCover, pCube );
00382
00383 }
00384 else
00385 {
00386 Mvc_CubeBitRemove( pCube, iLit );
00387
00388 pPrev = pCube;
00389 }
00390 }
00391 }
00392
00393
00405 void Mvc_CoverVerifyDivision( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t * pQuo, Mvc_Cover_t * pRem )
00406 {
00407 Mvc_Cover_t * pProd;
00408 Mvc_Cover_t * pDiff;
00409
00410 pProd = Mvc_CoverAlgebraicMultiply( pDiv, pQuo );
00411 pDiff = Mvc_CoverAlgebraicSubtract( pCover, pProd );
00412
00413 if ( Mvc_CoverAlgebraicEqual( pDiff, pRem ) )
00414 printf( "Verification OKAY!\n" );
00415 else
00416 {
00417 printf( "Verification FAILED!\n" );
00418 printf( "pCover:\n" );
00419 Mvc_CoverPrint( pCover );
00420 printf( "pDiv:\n" );
00421 Mvc_CoverPrint( pDiv );
00422 printf( "pRem:\n" );
00423 Mvc_CoverPrint( pRem );
00424 printf( "pQuo:\n" );
00425 Mvc_CoverPrint( pQuo );
00426 }
00427
00428 Mvc_CoverFree( pProd );
00429 Mvc_CoverFree( pDiff );
00430 }
00431
00435
00436