00001
00019 #include "mvc.h"
00020
00024
00025 static int bit_count[256] = {
00026 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
00027 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
00028 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
00029 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
00030 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
00031 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
00032 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
00033 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
00034 };
00035
00036
00037 static void Mvc_CoverCopyColumn( Mvc_Cover_t * pCoverOld, Mvc_Cover_t * pCoverNew, int iColOld, int iColNew );
00038
00039
00043
00055 void Mvc_CoverSupport( Mvc_Cover_t * pCover, Mvc_Cube_t * pSupp )
00056 {
00057 Mvc_Cube_t * pCube;
00058
00059 Mvc_CubeBitClean( pSupp );
00060
00061 Mvc_CoverForEachCube( pCover, pCube )
00062 Mvc_CubeBitOr( pSupp, pSupp, pCube );
00063 }
00064
00076 void Mvc_CoverSupportAnd( Mvc_Cover_t * pCover, Mvc_Cube_t * pSupp )
00077 {
00078 Mvc_Cube_t * pCube;
00079
00080 Mvc_CubeBitFill( pSupp );
00081
00082 Mvc_CoverForEachCube( pCover, pCube )
00083 Mvc_CubeBitAnd( pSupp, pSupp, pCube );
00084 }
00085
00097 int Mvc_CoverSupportSizeBinary( Mvc_Cover_t * pCover )
00098 {
00099 Mvc_Cube_t * pSupp;
00100 int Counter, i, v0, v1;
00101
00102 pSupp = Mvc_CubeAlloc( pCover );
00103 Mvc_CoverSupportAnd( pCover, pSupp );
00104 Counter = pCover->nBits/2;
00105 for ( i = 0; i < pCover->nBits/2; i++ )
00106 {
00107 v0 = Mvc_CubeBitValue( pSupp, 2*i );
00108 v1 = Mvc_CubeBitValue( pSupp, 2*i+1 );
00109 if ( v0 && v1 )
00110 Counter--;
00111 }
00112 Mvc_CubeFree( pCover, pSupp );
00113 return Counter;
00114 }
00115
00127 int Mvc_CoverSupportVarBelongs( Mvc_Cover_t * pCover, int iVar )
00128 {
00129 Mvc_Cube_t * pSupp;
00130 int RetValue, v0, v1;
00131
00132 pSupp = Mvc_CubeAlloc( pCover );
00133 Mvc_CoverSupportAnd( pCover, pSupp );
00134 v0 = Mvc_CubeBitValue( pSupp, 2*iVar );
00135 v1 = Mvc_CubeBitValue( pSupp, 2*iVar+1 );
00136 RetValue = (int)( !v0 || !v1 );
00137 Mvc_CubeFree( pCover, pSupp );
00138 return RetValue;
00139 }
00140
00152 void Mvc_CoverCommonCube( Mvc_Cover_t * pCover, Mvc_Cube_t * pComCube )
00153 {
00154 Mvc_Cube_t * pCube;
00155
00156 Mvc_CubeBitFill( pComCube );
00157
00158 Mvc_CoverForEachCube( pCover, pCube )
00159 Mvc_CubeBitAnd( pComCube, pComCube, pCube );
00160 }
00161
00173 int Mvc_CoverIsCubeFree( Mvc_Cover_t * pCover )
00174 {
00175 int Result;
00176
00177 Mvc_CoverAllocateMask( pCover );
00178 Mvc_CoverCommonCube( pCover, pCover->pMask );
00179
00180 Mvc_CubeBitEmpty( Result, pCover->pMask );
00181 return Result;
00182 }
00183
00195 void Mvc_CoverMakeCubeFree( Mvc_Cover_t * pCover )
00196 {
00197 Mvc_Cube_t * pCube;
00198
00199 Mvc_CoverAllocateMask( pCover );
00200 Mvc_CoverCommonCube( pCover, pCover->pMask );
00201
00202 Mvc_CoverForEachCube( pCover, pCube )
00203 Mvc_CubeBitSharp( pCube, pCube, pCover->pMask );
00204 }
00205
00217 Mvc_Cover_t * Mvc_CoverCommonCubeCover( Mvc_Cover_t * pCover )
00218 {
00219 Mvc_Cover_t * pRes;
00220 Mvc_Cube_t * pCube;
00221
00222 pRes = Mvc_CoverClone( pCover );
00223
00224 pCube = Mvc_CubeAlloc( pRes );
00225
00226 Mvc_CoverCommonCube( pCover, pCube );
00227
00228 Mvc_CoverAddCubeTail( pRes, pCube );
00229 return pRes;
00230 }
00231
00232
00244 int Mvc_CoverCheckSuppContainment( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 )
00245 {
00246 int Result;
00247 assert( pCover1->nBits == pCover2->nBits );
00248
00249 Mvc_CoverAllocateMask( pCover1 );
00250 Mvc_CoverSupport( pCover1, pCover1->pMask );
00251 Mvc_CoverAllocateMask( pCover2 );
00252 Mvc_CoverSupport( pCover2, pCover2->pMask );
00253
00254 Mvc_CubeBitNotImpl( Result, pCover2->pMask, pCover1->pMask );
00255 return !Result;
00256 }
00257
00269 int Mvc_CoverSetCubeSizes( Mvc_Cover_t * pCover )
00270 {
00271 Mvc_Cube_t * pCube;
00272 unsigned char * pByte, * pByteStart, * pByteStop;
00273 int nBytes, nOnes;
00274
00275
00276 nBytes = pCover->nBits / (8 * sizeof(unsigned char)) + (int)(pCover->nBits % (8 * sizeof(unsigned char)) > 0);
00277
00278 Mvc_CoverForEachCube( pCover, pCube )
00279 {
00280
00281 nOnes = 0;
00282
00283 pByteStart = (unsigned char *)pCube->pData;
00284 pByteStop = pByteStart + nBytes;
00285
00286 for ( pByte = pByteStart; pByte < pByteStop; pByte++ )
00287 nOnes += bit_count[*pByte];
00288
00289 Mvc_CubeSetSize( pCube, nOnes );
00290 }
00291 return 1;
00292 }
00293
00305 int Mvc_CoverGetCubeSize( Mvc_Cube_t * pCube )
00306 {
00307 unsigned char * pByte, * pByteStart, * pByteStop;
00308 int nOnes, nBytes, nBits;
00309
00310 nBits = (pCube->iLast + 1) * sizeof(Mvc_CubeWord_t) * 8 - pCube->nUnused;
00311 nBytes = nBits / (8 * sizeof(unsigned char)) + (int)(nBits % (8 * sizeof(unsigned char)) > 0);
00312
00313 nOnes = 0;
00314
00315 pByteStart = (unsigned char *)pCube->pData;
00316 pByteStop = pByteStart + nBytes;
00317
00318 for ( pByte = pByteStart; pByte < pByteStop; pByte++ )
00319 nOnes += bit_count[*pByte];
00320 return nOnes;
00321 }
00322
00339 int Mvc_CoverCountCubePairDiffs( Mvc_Cover_t * pCover, unsigned char pDiffs[] )
00340 {
00341 Mvc_Cube_t * pCube1;
00342 Mvc_Cube_t * pCube2;
00343 Mvc_Cube_t * pMask;
00344 unsigned char * pByte, * pByteStart, * pByteStop;
00345 int nBytes, nOnes;
00346 int nCubePairs;
00347
00348
00349 pMask = Mvc_CubeAlloc( pCover );
00350
00351 nBytes = pCover->nBits / (8 * sizeof(unsigned char)) + (int)(pCover->nBits % (8 * sizeof(unsigned char)) > 0);
00352
00353 nCubePairs = 0;
00354 Mvc_CoverForEachCube( pCover, pCube1 )
00355 {
00356 Mvc_CoverForEachCubeStart( Mvc_CubeReadNext(pCube1), pCube2 )
00357 {
00358
00359 Mvc_CubeBitExor( pMask, pCube1, pCube2 );
00360
00361 pByteStart = (unsigned char *)pMask->pData;
00362 pByteStop = pByteStart + nBytes;
00363
00364 nOnes = 0;
00365
00366 for ( pByte = pByteStart; pByte < pByteStop; pByte++ )
00367 nOnes += bit_count[*pByte];
00368
00369 pDiffs[nCubePairs++] = nOnes;
00370 }
00371 }
00372
00373 Mvc_CubeFree( pCover, pMask );
00374 return 1;
00375 }
00376
00377
00397 Mvc_Cover_t * Mvc_CoverRemap( Mvc_Cover_t * p, int * pVarsRem, int nVarsRem )
00398 {
00399 Mvc_Cover_t * pCover;
00400 Mvc_Cube_t * pCube, * pCubeCopy;
00401 int i;
00402
00403 pCover = Mvc_CoverAlloc( p->pMem, nVarsRem );
00404
00405 Mvc_CoverForEachCube( p, pCube )
00406 {
00407 pCubeCopy = Mvc_CubeAlloc( pCover );
00408
00409 Mvc_CubeBitFill( pCubeCopy );
00410 Mvc_CoverAddCubeTail( pCover, pCubeCopy );
00411 }
00412
00413 for ( i = 0; i < nVarsRem; i++ )
00414 {
00415 if (pVarsRem[i] < 0)
00416 continue;
00417 assert( pVarsRem[i] >= 0 && pVarsRem[i] < p->nBits );
00418 Mvc_CoverCopyColumn( p, pCover, pVarsRem[i], i );
00419 }
00420 return pCover;
00421 }
00422
00437 void Mvc_CoverCopyColumn( Mvc_Cover_t * pCoverOld, Mvc_Cover_t * pCoverNew,
00438 int iColOld, int iColNew )
00439 {
00440 Mvc_Cube_t * pCubeOld, * pCubeNew;
00441 int iWordOld, iWordNew, iBitOld, iBitNew;
00442
00443 assert( Mvc_CoverReadCubeNum(pCoverOld) == Mvc_CoverReadCubeNum(pCoverNew) );
00444
00445
00446 iWordOld = Mvc_CubeWhichWord(iColOld);
00447 iBitOld = Mvc_CubeWhichBit(iColOld);
00448 iWordNew = Mvc_CubeWhichWord(iColNew);
00449 iBitNew = Mvc_CubeWhichBit(iColNew);
00450
00451
00452 pCubeNew = Mvc_CoverReadCubeHead(pCoverNew);
00453 Mvc_CoverForEachCube( pCoverOld, pCubeOld )
00454 {
00455 if ( pCubeOld->pData[iWordOld] & (1<<iBitOld) )
00456 pCubeNew->pData[iWordNew] |= (1<<iBitNew);
00457 else
00458 pCubeNew->pData[iWordNew] &= ~(1<<iBitNew);
00459 pCubeNew = Mvc_CubeReadNext( pCubeNew );
00460 }
00461 }
00462
00474 void Mvc_CoverInverse( Mvc_Cover_t * pCover )
00475 {
00476 Mvc_Cube_t * pCube;
00477
00478 Mvc_CoverForEachCube( pCover, pCube )
00479 Mvc_CubeBitNot( pCube );
00480 }
00481
00493 Mvc_Cover_t * Mvc_CoverRemoveDontCareLits( Mvc_Cover_t * pCover )
00494 {
00495 Mvc_Cover_t * pCoverNew;
00496 Mvc_Cube_t * pCube;
00497
00498 pCoverNew = Mvc_CoverDup( pCover );
00499 Mvc_CoverForEachCube( pCoverNew, pCube )
00500 Mvc_CubeBitRemoveDcs( pCube );
00501 return pCoverNew;
00502 }
00503
00515 Mvc_Cover_t * Mvc_CoverCofactor( Mvc_Cover_t * p, int iValue, int iValueOther )
00516 {
00517 Mvc_Cover_t * pCover;
00518 Mvc_Cube_t * pCube, * pCubeCopy;
00519
00520 pCover = Mvc_CoverClone( p );
00521
00522 Mvc_CoverForEachCube( p, pCube )
00523 if ( Mvc_CubeBitValue( pCube, iValue ) )
00524 {
00525 pCubeCopy = Mvc_CubeDup( pCover, pCube );
00526 Mvc_CoverAddCubeTail( pCover, pCubeCopy );
00527 Mvc_CubeBitInsert( pCubeCopy, iValueOther );
00528 }
00529 return pCover;
00530 }
00531
00543 Mvc_Cover_t * Mvc_CoverFlipVar( Mvc_Cover_t * p, int iValue0, int iValue1 )
00544 {
00545 Mvc_Cover_t * pCover;
00546 Mvc_Cube_t * pCube, * pCubeCopy;
00547 int Value0, Value1, Temp;
00548
00549 assert( iValue0 + 1 == iValue1 );
00550
00551
00552 pCover = Mvc_CoverClone( p );
00553
00554 Mvc_CoverForEachCube( p, pCube )
00555 {
00556 pCubeCopy = Mvc_CubeDup( pCover, pCube );
00557 Mvc_CoverAddCubeTail( pCover, pCubeCopy );
00558
00559
00560 Value0 = Mvc_CubeBitValue( pCubeCopy, iValue0 );
00561 Value1 = Mvc_CubeBitValue( pCubeCopy, iValue1 );
00562
00563
00564 if ( Value0 && Value1 )
00565 continue;
00566
00567 assert( Value0 || Value1 );
00568
00569
00570 Temp = Value0;
00571 Value0 = Value1;
00572 Value1 = Temp;
00573
00574
00575 if ( Value0 )
00576 Mvc_CubeBitInsert( pCubeCopy, iValue0 );
00577 else
00578 Mvc_CubeBitRemove( pCubeCopy, iValue0 );
00579
00580 if ( Value1 )
00581 Mvc_CubeBitInsert( pCubeCopy, iValue1 );
00582 else
00583 Mvc_CubeBitRemove( pCubeCopy, iValue1 );
00584 }
00585 return pCover;
00586 }
00587
00603 Mvc_Cover_t * Mvc_CoverUnivQuantify( Mvc_Cover_t * p,
00604 int iValueA0, int iValueA1, int iValueB0, int iValueB1 )
00605 {
00606 Mvc_Cover_t * pCover;
00607 Mvc_Cube_t * pCube, * pCubeCopy;
00608 int ValueA0, ValueA1, ValueB0, ValueB1;
00609
00610
00611 pCover = Mvc_CoverClone( p );
00612
00613 Mvc_CoverForEachCube( p, pCube )
00614 {
00615
00616 ValueA0 = Mvc_CubeBitValue( pCube, iValueA0 );
00617 ValueA1 = Mvc_CubeBitValue( pCube, iValueA1 );
00618 ValueB0 = Mvc_CubeBitValue( pCube, iValueB0 );
00619 ValueB1 = Mvc_CubeBitValue( pCube, iValueB1 );
00620
00621
00622 assert( ValueA0 || ValueA1 );
00623 assert( ValueB0 || ValueB1 );
00624
00625
00626 if ( ValueA0 != ValueB0 && ValueA1 != ValueB1 )
00627 continue;
00628
00629
00630 pCubeCopy = Mvc_CubeDup( pCover, pCube );
00631 Mvc_CoverAddCubeTail( pCover, pCubeCopy );
00632
00633
00634 if ( ValueA0 && ValueB0 )
00635 Mvc_CubeBitInsert( pCubeCopy, iValueA0 );
00636 else
00637 Mvc_CubeBitRemove( pCubeCopy, iValueA0 );
00638
00639 if ( ValueA1 && ValueB1 )
00640 Mvc_CubeBitInsert( pCubeCopy, iValueA1 );
00641 else
00642 Mvc_CubeBitRemove( pCubeCopy, iValueA1 );
00643
00644
00645 Mvc_CubeBitInsert( pCubeCopy, iValueB0 );
00646 Mvc_CubeBitInsert( pCubeCopy, iValueB1 );
00647 }
00648 return pCover;
00649 }
00650
00651 #if 0
00652
00665 Mvc_Cover_t ** Mvc_CoverCofactors( Mvc_Data_t * pData, Mvc_Cover_t * pCover, int iVar )
00666 {
00667 Mvc_Cover_t ** ppCofs;
00668 Mvc_Cube_t * pCube, * pCubeNew;
00669 int i, nValues, iValueFirst, Res;
00670
00671
00672 iValueFirst = Vm_VarMapReadValuesFirst(pData->pVm, iVar);
00673 nValues = Vm_VarMapReadValues(pData->pVm, iVar);
00674 ppCofs = ALLOC( Mvc_Cover_t *, nValues + 1 );
00675 for ( i = 0; i <= nValues; i++ )
00676 ppCofs[i] = Mvc_CoverClone( pCover );
00677
00678
00679 Mvc_CoverForEachCube( pCover, pCube )
00680 {
00681
00682 Mvc_CubeBitEqualUnderMask( Res, pCube, pData->ppMasks[iVar], pData->ppMasks[iVar] );
00683 if ( Res )
00684 {
00685 pCubeNew = Mvc_CubeDup(pCover, pCube);
00686 Mvc_CoverAddCubeTail( ppCofs[nValues], pCubeNew );
00687 continue;
00688 }
00689
00690
00691 for ( i = 0; i < nValues; i++ )
00692 if ( Mvc_CubeBitValue( pCube, iValueFirst + i ) )
00693 {
00694 pCubeNew = Mvc_CubeDup(pCover, pCube);
00695 Mvc_CubeBitOr( pCubeNew, pCubeNew, pData->ppMasks[iVar] );
00696 Mvc_CoverAddCubeTail( ppCofs[i], pCubeNew );
00697 }
00698 }
00699 return ppCofs;
00700 }
00701
00716 int Mvr_CoverCountLitsWithValue( Mvc_Data_t * pData, Mvc_Cover_t * pCover, int iVar, int iValue )
00717 {
00718 Mvc_Cube_t * pCube;
00719 int iValueFirst, Res, Counter;
00720
00721 Counter = 0;
00722 iValueFirst = Vm_VarMapReadValuesFirst( pData->pVm, iVar );
00723 Mvc_CoverForEachCube( pCover, pCube )
00724 {
00725
00726 Mvc_CubeBitEqualUnderMask( Res, pCube, pData->ppMasks[iVar], pData->ppMasks[iVar] );
00727 if ( Res )
00728 continue;
00729
00730 Counter += Mvc_CubeBitValue( pCube, iValueFirst + iValue );
00731 }
00732 return Counter;
00733 }
00734
00750 Mvc_Cover_t * Mvc_CoverCreateExpanded( Mvc_Cover_t * pCover, Vm_VarMap_t * pVmNew )
00751 {
00752 Mvc_Cover_t * pCoverNew;
00753 Mvc_Cube_t * pCube, * pCubeNew;
00754 int i, iLast, iLastNew;
00755
00756
00757 pCoverNew = Mvc_CoverAlloc( pCover->pMem, Vm_VarMapReadValuesInNum(pVmNew) );
00758
00759
00760 Mvc_CoverAllocateMask( pCoverNew );
00761 Mvc_CubeBitClean( pCoverNew->pMask );
00762 for ( i = pCover->nBits; i < pCoverNew->nBits; i++ )
00763 Mvc_CubeBitInsert( pCoverNew->pMask, i );
00764
00765
00766 iLast = pCover->nWords? pCover->nWords - 1: 0;
00767 iLastNew = pCoverNew->nWords? pCoverNew->nWords - 1: 0;
00768
00769
00770 Mvc_CoverForEachCube( pCover, pCube )
00771 {
00772 pCubeNew = Mvc_CubeAlloc( pCoverNew );
00773 Mvc_CubeBitClean( pCubeNew );
00774
00775
00776 Mvc_CubeSetLast( pCubeNew, iLast );
00777 Mvc_CubeBitCopy( pCubeNew, pCube );
00778 Mvc_CubeSetLast( pCubeNew, iLastNew );
00779
00780 Mvc_CubeBitOr( pCubeNew, pCubeNew, pCoverNew->pMask );
00781
00782 Mvc_CoverAddCubeTail( pCoverNew, pCubeNew );
00783 }
00784 return pCoverNew;
00785 }
00786
00787 #endif
00788
00801 Mvc_Cover_t * Mvc_CoverTranspose( Mvc_Cover_t * pCover )
00802 {
00803 Mvc_Cover_t * pRes;
00804 Mvc_Cube_t * pCubeRes, * pCube;
00805 int nWord, nBit, i, iCube;
00806
00807 pRes = Mvc_CoverAlloc( pCover->pMem, Mvc_CoverReadCubeNum(pCover) );
00808 for ( i = 0; i < pCover->nBits; i++ )
00809 {
00810
00811 nWord = Mvc_CubeWhichWord(i);
00812 nBit = Mvc_CubeWhichBit(i);
00813
00814 pCubeRes = Mvc_CubeAlloc( pRes );
00815 Mvc_CubeBitClean( pCubeRes );
00816 iCube = 0;
00817 Mvc_CoverForEachCube( pCover, pCube )
00818 {
00819 if ( pCube->pData[nWord] & (1<<nBit) )
00820 Mvc_CubeBitInsert( pCubeRes, iCube );
00821 iCube++;
00822 }
00823 Mvc_CoverAddCubeTail( pRes, pCubeRes );
00824 }
00825 return pRes;
00826 }
00827
00839 int Mvc_UtilsCheckUnusedZeros( Mvc_Cover_t * pCover )
00840 {
00841 unsigned Unsigned;
00842 Mvc_Cube_t * pCube;
00843 int nCubes;
00844
00845 nCubes = 0;
00846 Mvc_CoverForEachCube( pCover, pCube )
00847 {
00848 if ( pCube->nUnused == 0 )
00849 continue;
00850
00851 Unsigned = ( pCube->pData[pCube->iLast] &
00852 (BITS_FULL << (32-pCube->nUnused)) );
00853 if( Unsigned )
00854 {
00855 printf( "Cube %2d out of %2d contains dirty bits.\n", nCubes,
00856 Mvc_CoverReadCubeNum(pCover) );
00857 }
00858 nCubes++;
00859 }
00860 return 1;
00861 }
00862
00863
00867
00868