00001
00021 #include "kit.h"
00022
00026
00030
00042 void Kit_SopCreate( Kit_Sop_t * cResult, Vec_Int_t * vInput, int nVars, Vec_Int_t * vMemory )
00043 {
00044 unsigned uCube;
00045 int i;
00046
00047 cResult->nCubes = 0;
00048 cResult->pCubes = Vec_IntFetch( vMemory, Vec_IntSize(vInput) );
00049
00050 Vec_IntForEachEntry( vInput, uCube, i )
00051 Kit_SopPushCube( cResult, uCube );
00052 }
00053
00065 void Kit_SopCreateInverse( Kit_Sop_t * cResult, Vec_Int_t * vInput, int nLits, Vec_Int_t * vMemory )
00066 {
00067 unsigned uCube, uMask = 0;
00068 int i, nCubes = Vec_IntSize(vInput);
00069
00070 cResult->nCubes = 0;
00071 cResult->pCubes = Vec_IntFetch( vMemory, nCubes );
00072
00073
00074 for ( i = 0; i < nCubes; i++ )
00075 {
00076 uCube = Vec_IntEntry( vInput, i );
00077 uMask = ((uCube | (uCube >> 1)) & 0x55555555);
00078 uMask |= (uMask << 1);
00079 Kit_SopPushCube( cResult, uCube ^ uMask );
00080 }
00081 }
00082
00094 void Kit_SopDup( Kit_Sop_t * cResult, Kit_Sop_t * cSop, Vec_Int_t * vMemory )
00095 {
00096 unsigned uCube;
00097 int i;
00098
00099 cResult->nCubes = 0;
00100 cResult->pCubes = Vec_IntFetch( vMemory, Kit_SopCubeNum(cSop) );
00101
00102 Kit_SopForEachCube( cSop, uCube, i )
00103 Kit_SopPushCube( cResult, uCube );
00104 }
00105
00118 void Kit_SopDivideByLiteralQuo( Kit_Sop_t * cSop, int iLit )
00119 {
00120 unsigned uCube;
00121 int i, k = 0;
00122 Kit_SopForEachCube( cSop, uCube, i )
00123 {
00124 if ( Kit_CubeHasLit(uCube, iLit) )
00125 Kit_SopWriteCube( cSop, Kit_CubeRemLit(uCube, iLit), k++ );
00126 }
00127 Kit_SopShrink( cSop, k );
00128 }
00129
00130
00142 void Kit_SopDivideByCube( Kit_Sop_t * cSop, Kit_Sop_t * cDiv, Kit_Sop_t * vQuo, Kit_Sop_t * vRem, Vec_Int_t * vMemory )
00143 {
00144 unsigned uCube, uDiv;
00145 int i;
00146
00147 assert( Kit_SopCubeNum(cDiv) == 1 );
00148 uDiv = Kit_SopCube(cDiv, 0);
00149
00150 vQuo->nCubes = 0;
00151 vQuo->pCubes = Vec_IntFetch( vMemory, Kit_SopCubeNum(cSop) );
00152 vRem->nCubes = 0;
00153 vRem->pCubes = Vec_IntFetch( vMemory, Kit_SopCubeNum(cSop) );
00154
00155 Kit_SopForEachCube( cSop, uCube, i )
00156 {
00157 if ( Kit_CubeContains( uCube, uDiv ) )
00158 Kit_SopPushCube( vQuo, Kit_CubeSharp(uCube, uDiv) );
00159 else
00160 Kit_SopPushCube( vRem, uCube );
00161 }
00162 }
00163
00175 void Kit_SopDivideInternal( Kit_Sop_t * cSop, Kit_Sop_t * cDiv, Kit_Sop_t * vQuo, Kit_Sop_t * vRem, Vec_Int_t * vMemory )
00176 {
00177 unsigned uCube, uDiv, uCube2, uDiv2, uQuo;
00178 int i, i2, k, k2, nCubesRem;
00179 assert( Kit_SopCubeNum(cSop) >= Kit_SopCubeNum(cDiv) );
00180
00181 if ( Kit_SopCubeNum(cDiv) == 1 )
00182 {
00183 Kit_SopDivideByCube( cSop, cDiv, vQuo, vRem, vMemory );
00184 return;
00185 }
00186
00187 vQuo->nCubes = 0;
00188 vQuo->pCubes = Vec_IntFetch( vMemory, Kit_SopCubeNum(cSop) / Kit_SopCubeNum(cDiv) );
00189
00190
00191 Kit_SopForEachCube( cSop, uCube, i )
00192 {
00193
00194 if ( Kit_CubeIsMarked(uCube) )
00195 continue;
00196
00197 uDiv = ~0;
00198 Kit_SopForEachCube( cDiv, uDiv, k )
00199 if ( Kit_CubeContains( uCube, uDiv ) )
00200 break;
00201
00202 if ( k == Kit_SopCubeNum(cDiv) )
00203 continue;
00204
00205 uQuo = Kit_CubeSharp( uCube, uDiv );
00206
00207 uDiv2 = ~0;
00208 Kit_SopForEachCube( cDiv, uDiv2, k2 )
00209 {
00210 if ( k2 == k )
00211 continue;
00212
00213 Kit_SopForEachCube( cSop, uCube2, i2 )
00214 {
00215
00216 if ( Kit_CubeIsMarked(uCube2) )
00217 continue;
00218
00219 if ( Kit_CubeContains( uCube2, uDiv2 ) && uQuo == Kit_CubeSharp( uCube2, uDiv2 ) )
00220 break;
00221 }
00222
00223 if ( i2 == Kit_SopCubeNum(cSop) )
00224 break;
00225 }
00226
00227 if ( k2 != Kit_SopCubeNum(cDiv) )
00228 continue;
00229
00230 Kit_SopPushCube( vQuo, uQuo );
00231
00232
00233 Kit_SopWriteCube( cSop, Kit_CubeMark(uCube), i );
00234
00235 Kit_SopForEachCube( cDiv, uDiv2, k2 )
00236 {
00237 if ( k2 == k )
00238 continue;
00239
00240 Kit_SopForEachCube( cSop, uCube2, i2 )
00241 {
00242
00243 if ( Kit_CubeIsMarked(uCube2) )
00244 continue;
00245
00246 if ( Kit_CubeContains( uCube2, uDiv2 ) && uQuo == Kit_CubeSharp( uCube2, uDiv2 ) )
00247 break;
00248 }
00249 assert( i2 < Kit_SopCubeNum(cSop) );
00250
00251
00252 Kit_SopWriteCube( cSop, Kit_CubeMark(uCube2), i2 );
00253 }
00254 }
00255
00256 nCubesRem = Kit_SopCubeNum(cSop) - Kit_SopCubeNum(vQuo) * Kit_SopCubeNum(cDiv);
00257
00258 vRem->nCubes = 0;
00259 vRem->pCubes = Vec_IntFetch( vMemory, nCubesRem );
00260
00261
00262 Kit_SopForEachCube( cSop, uCube, i )
00263 {
00264 if ( !Kit_CubeIsMarked(uCube) )
00265 {
00266 Kit_SopPushCube( vRem, uCube );
00267 continue;
00268 }
00269 Kit_SopWriteCube( cSop, Kit_CubeUnmark(uCube), i );
00270 }
00271 assert( nCubesRem == Kit_SopCubeNum(vRem) );
00272 }
00273
00285 static inline unsigned Kit_SopCommonCube( Kit_Sop_t * cSop )
00286 {
00287 unsigned uMask, uCube;
00288 int i;
00289 uMask = ~(unsigned)0;
00290 Kit_SopForEachCube( cSop, uCube, i )
00291 uMask &= uCube;
00292 return uMask;
00293 }
00294
00306 void Kit_SopMakeCubeFree( Kit_Sop_t * cSop )
00307 {
00308 unsigned uMask, uCube;
00309 int i;
00310 uMask = Kit_SopCommonCube( cSop );
00311 if ( uMask == 0 )
00312 return;
00313
00314 Kit_SopForEachCube( cSop, uCube, i )
00315 Kit_SopWriteCube( cSop, Kit_CubeSharp(uCube, uMask), i );
00316 }
00317
00329 int Kit_SopIsCubeFree( Kit_Sop_t * cSop )
00330 {
00331 return Kit_SopCommonCube( cSop ) == 0;
00332 }
00333
00345 void Kit_SopCommonCubeCover( Kit_Sop_t * cResult, Kit_Sop_t * cSop, Vec_Int_t * vMemory )
00346 {
00347 assert( Kit_SopCubeNum(cSop) > 0 );
00348 cResult->nCubes = 0;
00349 cResult->pCubes = Vec_IntFetch( vMemory, 1 );
00350 Kit_SopPushCube( cResult, Kit_SopCommonCube(cSop) );
00351 }
00352
00353
00365 int Kit_SopAnyLiteral( Kit_Sop_t * cSop, int nLits )
00366 {
00367 unsigned uCube;
00368 int i, k, nLitsCur;
00369
00370 for ( i = 0; i < nLits; i++ )
00371 {
00372
00373 nLitsCur = 0;
00374 Kit_SopForEachCube( cSop, uCube, k )
00375 if ( Kit_CubeHasLit(uCube, i) )
00376 nLitsCur++;
00377 if ( nLitsCur > 1 )
00378 return i;
00379 }
00380 return -1;
00381 }
00382
00395 int Kit_SopWorstLiteral( Kit_Sop_t * cSop, int nLits )
00396 {
00397 unsigned uCube;
00398 int i, k, iMin, nLitsMin, nLitsCur;
00399 int fUseFirst = 1;
00400
00401
00402 iMin = -1;
00403 nLitsMin = 1000000;
00404 for ( i = 0; i < nLits; i++ )
00405 {
00406
00407 nLitsCur = 0;
00408 Kit_SopForEachCube( cSop, uCube, k )
00409 if ( Kit_CubeHasLit(uCube, i) )
00410 nLitsCur++;
00411
00412 if ( nLitsCur < 2 )
00413 continue;
00414
00415 if ( fUseFirst )
00416 {
00417 if ( nLitsMin > nLitsCur )
00418 {
00419 nLitsMin = nLitsCur;
00420 iMin = i;
00421 }
00422 }
00423 else
00424 {
00425 if ( nLitsMin >= nLitsCur )
00426 {
00427 nLitsMin = nLitsCur;
00428 iMin = i;
00429 }
00430 }
00431 }
00432 if ( nLitsMin < 1000000 )
00433 return iMin;
00434 return -1;
00435 }
00436
00449 int Kit_SopBestLiteral( Kit_Sop_t * cSop, int nLits, unsigned uMask )
00450 {
00451 unsigned uCube;
00452 int i, k, iMax, nLitsMax, nLitsCur;
00453 int fUseFirst = 1;
00454
00455
00456 iMax = -1;
00457 nLitsMax = -1;
00458 for ( i = 0; i < nLits; i++ )
00459 {
00460 if ( !Kit_CubeHasLit(uMask, i) )
00461 continue;
00462
00463 nLitsCur = 0;
00464 Kit_SopForEachCube( cSop, uCube, k )
00465 if ( Kit_CubeHasLit(uCube, i) )
00466 nLitsCur++;
00467
00468 if ( nLitsCur < 2 )
00469 continue;
00470
00471 if ( fUseFirst )
00472 {
00473 if ( nLitsMax < nLitsCur )
00474 {
00475 nLitsMax = nLitsCur;
00476 iMax = i;
00477 }
00478 }
00479 else
00480 {
00481 if ( nLitsMax <= nLitsCur )
00482 {
00483 nLitsMax = nLitsCur;
00484 iMax = i;
00485 }
00486 }
00487 }
00488 if ( nLitsMax >= 0 )
00489 return iMax;
00490 return -1;
00491 }
00492
00504 void Kit_SopDivisorZeroKernel_rec( Kit_Sop_t * cSop, int nLits )
00505 {
00506 int iLit;
00507
00508 iLit = Kit_SopWorstLiteral( cSop, nLits );
00509 if ( iLit == -1 )
00510 return;
00511
00512 Kit_SopDivideByLiteralQuo( cSop, iLit );
00513 Kit_SopMakeCubeFree( cSop );
00514
00515 Kit_SopDivisorZeroKernel_rec( cSop, nLits );
00516 }
00517
00529 int Kit_SopDivisor( Kit_Sop_t * cResult, Kit_Sop_t * cSop, int nLits, Vec_Int_t * vMemory )
00530 {
00531 if ( Kit_SopCubeNum(cSop) <= 1 )
00532 return 0;
00533 if ( Kit_SopAnyLiteral( cSop, nLits ) == -1 )
00534 return 0;
00535
00536 Kit_SopDup( cResult, cSop, vMemory );
00537
00538 Kit_SopDivisorZeroKernel_rec( cResult, nLits );
00539 assert( Kit_SopCubeNum(cResult) > 0 );
00540 return 1;
00541 }
00542
00543
00555 void Kit_SopBestLiteralCover( Kit_Sop_t * cResult, Kit_Sop_t * cSop, unsigned uCube, int nLits, Vec_Int_t * vMemory )
00556 {
00557 int iLitBest;
00558
00559 iLitBest = Kit_SopBestLiteral( cSop, nLits, uCube );
00560
00561 cResult->nCubes = 0;
00562 cResult->pCubes = Vec_IntFetch( vMemory, 1 );
00563
00564 Kit_SopPushCube( cResult, Kit_CubeSetLit(0, iLitBest) );
00565 }
00566
00567
00571
00572