43static inline int Mop_ManIsSopSymb(
char c ) {
return c ==
'0' || c ==
'1' || c ==
'-'; }
44static inline int Mop_ManIsSpace(
char c ) {
return c ==
' ' || c ==
'\t' || c ==
'\n' || c ==
'\v' || c ==
'\f' || c ==
'\r'; }
46static inline word * Mop_ManCubeIn(
Mop_Man_t *
p,
int i ) {
return Vec_WrdEntryP(
p->vWordsIn,
p->nWordsIn * i); }
47static inline word * Mop_ManCubeOut(
Mop_Man_t *
p,
int i ) {
return Vec_WrdEntryP(
p->vWordsOut,
p->nWordsOut * i); }
69 p->nWordsIn = Abc_Bit6WordNum( 2 * nIns );
70 p->nWordsOut = Abc_Bit6WordNum( nOuts );
71 p->vWordsIn = Vec_WrdStart( 2 *
p->nWordsIn * nCubes );
72 p->vWordsOut = Vec_WrdStart( 2 *
p->nWordsOut * nCubes );
73 p->vCubes = Vec_IntAlloc( 2 * nCubes );
74 p->vFree = Vec_IntAlloc( 2 * nCubes );
79 Vec_WrdFree(
p->vWordsIn );
80 Vec_WrdFree(
p->vWordsOut );
81 Vec_IntFree(
p->vCubes );
82 Vec_IntFree(
p->vFree );
100 int nFileSize, RetValue;
102 pFile = fopen( pFileName,
"rb" );
105 Abc_Print( -1,
"Mop_ManLoadFile(): The file is unavailable (absent or open).\n" );
109 nFileSize = ftell( pFile );
110 if ( nFileSize == 0 )
112 Abc_Print( -1,
"Mop_ManLoadFile(): The file is empty.\n" );
115 pContents =
ABC_ALLOC(
char, nFileSize + 10 );
117 RetValue = fread( pContents, nFileSize, 1, pFile );
119 strcpy( pContents + nFileSize,
"\n" );
136 char * pIns =
strstr( pBuffer,
".i " );
137 char * pOuts =
strstr( pBuffer,
".o " );
138 char * pStr = pBuffer;
int nCubes = 0;
139 if ( pIns == NULL || pOuts == NULL )
141 *pnIns = atoi( pIns + 2 );
142 *pnOuts = atoi( pOuts + 2 );
144 nCubes += (*pStr++ ==
'\n');
150 int nIns, nOuts, nCubes, iCube;
152 if ( pBuffer == NULL )
159 pToken =
strtok( pBuffer,
"\n" );
162 while ( Mop_ManIsSpace(*pToken) )
164 if ( Mop_ManIsSopSymb(*pToken) )
166 pToken =
strtok( NULL,
"\n" );
169 for ( iCube = 0; pToken && Mop_ManIsSopSymb(*pToken); iCube++ )
171 char * pTokenCopy = pToken;
172 int i, o, nVars[2] = {nIns, nOuts};
173 word * pCube[2] = { Mop_ManCubeIn(
p, iCube), Mop_ManCubeOut(
p, iCube) };
174 for ( o = 0; o < 2; o++ )
176 while ( Mop_ManIsSpace(*pToken) )
178 for ( i = 0; i < nVars[o]; i++, pToken++ )
180 if ( !Mop_ManIsSopSymb(*pToken) )
182 printf(
"Cannot read cube %d (%s).\n", iCube+1, pTokenCopy );
189 if ( *pToken ==
'1' )
190 Abc_TtSetBit( pCube[o], i );
192 else if ( *pToken ==
'0' )
193 Abc_TtSetBit( pCube[o], 2*i );
194 else if ( *pToken ==
'1' )
195 Abc_TtSetBit( pCube[o], 2*i+1 );
199 Vec_IntPush(
p->vCubes, iCube );
200 pToken =
strtok( NULL,
"\n" );
202 for ( ; iCube < 2 * nCubes; iCube++ )
203 Vec_IntPush(
p->vFree, iCube );
210 char Symb[4] = {
'-',
'0',
'1',
'?' };
211 word * pCubeIn = Mop_ManCubeIn(
p, iCube );
212 word * pCubeOut = Mop_ManCubeOut(
p, iCube );
213 for ( k = 0; k <
p->nIns; k++ )
214 printf(
"%c", Symb[Abc_TtGetQua(pCubeIn, k)] );
216 for ( k = 0; k <
p->nOuts; k++ )
217 printf(
"%d", Abc_TtGetBit(pCubeOut, k) );
223 printf(
".%d\n",
p->nIns );
224 printf(
".%d\n",
p->nOuts );
241static inline int Mop_ManCountOnes(
word * pCube,
int nWords )
244 for ( w = 0; w <
nWords; w++ )
245 Count += Abc_TtCountOnes( pCube[w] );
248static inline int Mop_ManCountOutputLits(
Mop_Man_t *
p )
250 int i, iCube, nOutLits = 0;
252 nOutLits += Mop_ManCountOnes( Mop_ManCubeOut(
p, iCube),
p->nWordsOut );
258 Vec_Wec_t * vGroups = Vec_WecStart(
p->nIns );
260 Vec_WecPush( vGroups, Mop_ManCountOnes(Mop_ManCubeIn(
p, iCube),
p->nWordsIn), iCube );
266 int nBefore = Vec_IntSize(
p->vCubes);
268 Vec_IntClear(
p->vCubes );
272 Vec_IntPush(
p->vCubes, iCube1 );
273 return nBefore - Vec_IntSize(
p->vCubes);
275static inline int Mop_ManCheckContain(
word * pBig,
word * pSmall,
int nWords )
278 for ( w = 0; w <
nWords; w++ )
279 if ( pSmall[w] != (pSmall[w] & pBig[w]) )
283static inline void Mop_ManRemoveEmpty(
Mop_Man_t *
p )
285 int w, i, k = 0, iCube;
288 word * pCube = Mop_ManCubeOut(
p, iCube );
289 for ( w = 0; w <
p->nWordsOut; w++ )
292 if ( w < p->nWordsOut )
293 Vec_IntWriteEntry(
p->vCubes, k++, iCube );
295 Vec_IntShrink(
p->vCubes, k );
311 int i, v, iCube, nVars = 32 *
p->nWordsIn;
312 Vec_Int_t * vStats = Vec_IntStart( nVars );
315 word * pCube = Mop_ManCubeIn(
p, iCube);
316 int nOutLits = Mop_ManCountOnes( Mop_ManCubeOut(
p, iCube),
p->nWordsOut );
317 for ( v = 0; v < nVars; v++ )
318 if ( Abc_TtGetQua(pCube, v) )
319 Vec_IntAddToEntry( vStats, v, nOutLits );
336static inline int Mop_ManFindDiffVar(
word * pCube1,
word * pCube2,
int nWords )
339 for ( w = 0; w <
nWords; w++ )
341 word Xor = pCube1[w] ^ pCube2[w];
342 for ( i = 0; i < 32; i++ )
343 if ( (Xor >> (i << 1)) & 0x3 )
350static inline int Mop_ManCheckDist1(
word * pCube1,
word * pCube2,
int nWords )
353 for ( w = 0; w <
nWords; w++ )
355 word Xor = pCube1[w] ^ pCube2[w];
358 if ( (Xor ^ (Xor >> 1)) &
ABC_CONST(0x5555555555555555) )
360 Xor &= (Xor >> 1) &
ABC_CONST(0x5555555555555555);
365 if ( (Xor & (Xor-1)) )
372static inline void Map_ManGroupCompact(
Vec_Int_t * vGroup )
377 Vec_IntWriteEntry( vGroup, k++, Entry );
378 Vec_IntShrink( vGroup, k );
383 int w, c1, c2, iCube1, iCube2,
nEqual = 0;
387 word * pCube1Out, * pCube1 = Mop_ManCubeIn(
p, iCube1 );
391 word * pCube2Out, * pCube2 = Mop_ManCubeIn(
p, iCube2 );
392 if (
memcmp(pCube1, pCube2,
sizeof(
word)*
p->nWordsIn) )
395 pCube1Out = Mop_ManCubeOut(
p, iCube1 );
396 pCube2Out = Mop_ManCubeOut(
p, iCube2 );
397 for ( w = 0; w <
p->nWordsOut; w++ )
398 pCube1Out[w] |= pCube2Out[w];
399 Vec_IntWriteEntry( vGroup, c2, -1 );
400 Vec_IntPush(
p->vFree, iCube2 );
405 Map_ManGroupCompact( vGroup );
411 int i, Entry, Entry2;
412 Vec_Int_t * vCounts = Vec_IntStart( nObjs );
413 Vec_Int_t * vPairsNew = Vec_IntAlloc( Vec_IntSize(vPairs) );
415 Vec_IntAddToEntry( vCounts, Entry, 1 );
418 if ( Vec_IntEntry(vCounts, Entry) == 1 || Vec_IntEntry(vCounts, Entry2) == 1 )
420 if ( Vec_IntEntry(vCounts, Entry) == 1 )
421 Vec_IntPushTwo( vPairsNew, Entry, Entry2 );
423 Vec_IntPushTwo( vPairsNew, Entry2, Entry );
424 Vec_IntWriteEntry( vCounts, Entry, -1 );
425 Vec_IntWriteEntry( vCounts, Entry2, -1 );
429 if ( Vec_IntEntry(vCounts, Entry) > 0 && Vec_IntEntry(vCounts, Entry2) > 0 )
431 Vec_IntPushTwo( vPairsNew, Entry, Entry2 );
432 Vec_IntWriteEntry( vCounts, Entry, -1 );
433 Vec_IntWriteEntry( vCounts, Entry2, -1 );
437 if ( Vec_IntEntry(vCounts, Entry) > 0 || Vec_IntEntry(vCounts, Entry2) > 0 )
439 if ( Vec_IntEntry(vCounts, Entry) > 0 )
440 Vec_IntPushTwo( vPairsNew, Entry, Entry2 );
442 Vec_IntPushTwo( vPairsNew, Entry2, Entry );
443 Vec_IntWriteEntry( vCounts, Entry, -1 );
444 Vec_IntWriteEntry( vCounts, Entry2, -1 );
446 Vec_IntFree( vCounts );
450 Vec_Int_t * vTemp1 = Vec_IntDup( vPairs );
451 Vec_Int_t * vTemp2 = Vec_IntDup( vPairsNew );
452 Vec_IntUniqify( vTemp1 );
453 Vec_IntUniqify( vTemp2 );
454 assert( Vec_IntEqual( vTemp1, vTemp2 ) );
455 Vec_IntFree( vTemp1 );
456 Vec_IntFree( vTemp2 );
463 int c1, c2, iCube1, iCube2;
464 Vec_Int_t * vPairs = Vec_IntAlloc( 100 );
467 word * pCube1Out, * pCube1 = Mop_ManCubeIn(
p, iCube1 );
470 word * pCube2Out, * pCube2 = Mop_ManCubeIn(
p, iCube2 );
471 if ( !Mop_ManCheckDist1(pCube1, pCube2,
p->nWordsIn) )
473 pCube1Out = Mop_ManCubeOut(
p, iCube1 );
474 pCube2Out = Mop_ManCubeOut(
p, iCube2 );
475 if ( !
memcmp(pCube1Out, pCube2Out,
sizeof(
word)*
p->nWordsOut) )
476 Vec_IntPushTwo( vPairs, c1, c2 );
486 int nCubes = Vec_IntSize(vGroup) + Vec_IntSize(vGroupPrev);
487 int w, i, c1, c2, iCubeNew, iVar;
489 word * pCube, * pCube1, * pCube2;
490 Vec_Int_t * vToFree = Vec_IntAlloc( Vec_IntSize(vPairsNew) );
493 pCube1 = Mop_ManCubeIn(
p, Vec_IntEntry(vGroup, c1) );
494 pCube2 = Mop_ManCubeIn(
p, Vec_IntEntry(vGroup, c2) );
495 assert( Mop_ManCheckDist1(pCube1, pCube2,
p->nWordsIn) );
498 iVar = Mop_ManFindDiffVar( pCube1, pCube2,
p->nWordsIn );
499 if ( Vec_IntEntry( vStats, iVar ) > nLimit )
501 Vec_IntPush( vToFree, c1 );
502 Vec_IntPush( vToFree, c2 );
504 iCubeNew = Vec_IntPop(
p->vFree );
505 pCube = Mop_ManCubeIn(
p, iCubeNew );
506 for ( w = 0; w <
p->nWordsIn; w++ )
507 pCube[w] = pCube1[w] & pCube2[w];
509 pCube = Mop_ManCubeOut(
p, iCubeNew );
510 pCube1 = Mop_ManCubeOut(
p, Vec_IntEntry(vGroup, c1) );
511 pCube2 = Mop_ManCubeOut(
p, Vec_IntEntry(vGroup, c2) );
514 for ( w = 0; w <
p->nWordsOut; w++ )
515 pCube[w] = pCube1[w];
517 Vec_IntPush( vGroupPrev, iCubeNew );
522 if ( Vec_IntEntry(vGroup, c1) == -1 )
524 Vec_IntPush(
p->vFree, Vec_IntEntry(vGroup, c1) );
525 Vec_IntWriteEntry( vGroup, c1, -1 );
527 Vec_IntFree( vToFree );
528 if ( Vec_IntSize(vPairsNew) > 0 )
529 Map_ManGroupCompact( vGroup );
530 Vec_IntFree( vPairs );
531 Vec_IntFree( vPairsNew );
532 return nCubes - Vec_IntSize(vGroup) - Vec_IntSize(vGroupPrev);
537 int w, c1, c2, iCube1, iCube2, Count = 0;
541 word * pCube1Out, * pCube1 = Mop_ManCubeIn(
p, iCube1 );
545 word * pCube2Out, * pCube2 = Mop_ManCubeIn(
p, iCube2 );
546 if ( !Mop_ManCheckDist1(pCube1, pCube2,
p->nWordsIn) )
548 pCube1Out = Mop_ManCubeOut(
p, iCube1 );
549 pCube2Out = Mop_ManCubeOut(
p, iCube2 );
551 if ( Mop_ManCheckContain(pCube1Out, pCube2Out,
p->nWordsOut) )
554 for ( w = 0; w <
p->nWordsIn; w++ )
555 pCube2[w] &= pCube1[w];
557 for ( w = 0; w <
p->nWordsOut; w++ )
558 pCube1Out[w] &= ~pCube2Out[w];
560 Vec_IntPush( vGroupPrev, iCube2 );
561 Vec_IntWriteEntry( vGroup, c2, -1 );
564 else if ( Mop_ManCheckContain(pCube2Out, pCube1Out,
p->nWordsOut) )
567 for ( w = 0; w <
p->nWordsIn; w++ )
568 pCube1[w] &= pCube2[w];
570 for ( w = 0; w <
p->nWordsOut; w++ )
571 pCube2Out[w] &= ~pCube1Out[w];
573 Vec_IntPush( vGroupPrev, iCube1 );
574 Vec_IntWriteEntry( vGroup, c1, -1 );
580 Map_ManGroupCompact( vGroup );
586 int i,
nEqual, nReduce, Count = 0;
589 if ( Vec_IntSize(vGroup) == 0 )
593 printf(
"Detected constant-1 cover.\n" );
600 Count +=
nEqual + nReduce;
608 int w, c1, c2, iCube1, iCube2, Count = 0;
611 word * pCube1Out, * pCube1 = Mop_ManCubeIn(
p, iCube1 );
615 word * pCube2Out, * pCube2 = Mop_ManCubeIn(
p, iCube2 );
616 if ( !Mop_ManCheckContain(pCube2, pCube1,
p->nWordsIn) )
618 pCube1Out = Mop_ManCubeOut(
p, iCube1 );
619 pCube2Out = Mop_ManCubeOut(
p, iCube2 );
620 for ( w = 0; w <
p->nWordsOut; w++ )
621 pCube2Out[w] &= ~pCube1Out[w];
622 for ( w = 0; w <
p->nWordsOut; w++ )
625 if ( w < p->nWordsOut )
628 Vec_IntWriteEntry( vGroup2, c2, -1 );
629 Vec_IntPush(
p->vFree, iCube2 );
634 Map_ManGroupCompact( vGroup2 );
652 int nCubes = Vec_IntSize(
p->vCubes);
654 Vec_Wec_t * vGroups = Mop_ManCreateGroups(
p );
656 int nOutLits = Mop_ManCountOutputLits(
p );
662 int Removed = Mop_ManUnCreateGroups(
p, vGroups );
663 int nOutLits2 = Mop_ManCountOutputLits(
p );
664 Vec_WecFree( vGroups );
666 Vec_IntFree( vStats );
667 assert( Removed == Count1 + Count2 + Count3 );
669 printf(
"Cubes: %d -> %d. C = %d. M = %d. C = %d. M = %d. C = %d. Output lits: %d -> %d. ",
670 nCubes, Vec_IntSize(
p->vCubes), Count1, Count2, Count3, Count4, Count5, nOutLits, nOutLits2 );
671 Abc_PrintTime( 1,
"Time", Abc_Clock() - clk );
690 int i, k, nOutLits, nOutLits2,
nEqual = 0, nContain = 0;
691 Vec_Wec_t * vGroups = Mop_ManCreateGroups(
p );
693 nOutLits = Mop_ManCountOutputLits(
p );
702 nOutLits2 = Mop_ManCountOutputLits(
p );
703 Mop_ManUnCreateGroups(
p, vGroups );
704 Vec_WecFree( vGroups );
706 printf(
"Total = %d. Reduced %d equal and %d contained cubes. Output lits: %d -> %d. ", Vec_IntSize(
p->vCubes),
nEqual, nContain, nOutLits, nOutLits2 );
707 Abc_PrintTime( 1,
"Time", Abc_Clock() - clk );
728 word * pCube = Mop_ManCubeOut(
p, iCube );
729 for ( k = 0; k <
p->nOuts; k++ )
730 if ( Abc_TtGetBit( pCube, k ) )
731 Vec_WecPush( vOuts, k, iCube );
738 char Symb[4] = {
'-',
'0',
'1',
'?' };
744 for ( i = 0; i <
p->nIns; i++ )
745 Abc_NtkCreatePi(pNtk);
746 for ( i = 0; i <
p->nOuts; i++ )
748 Vec_Int_t * vThis = Vec_WecEntry( vOuts, i );
750 Abc_Obj_t * pNode = Abc_NtkCreateNode(pNtk);
752 if ( Vec_IntSize(vThis) == 0 )
757 for ( k = 0; k <
p->nIns; k++ )
759 Vec_StrClear( vSop );
762 word * pCube = Mop_ManCubeIn(
p, iCube );
763 for ( k = 0; k <
p->nIns; k++ )
764 Vec_StrPush( vSop, Symb[Abc_TtGetQua(pCube, k)] );
765 Vec_StrAppend( vSop,
" 1\n" );
767 Vec_StrPush( vSop,
'\0' );
771 Vec_WecFree( vOuts );
794 Mop_ManRemoveEmpty(
p );
struct Abc_Obj_t_ Abc_Obj_t
ABC_DLL Abc_Ntk_t * Abc_NtkAlloc(Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan)
DECLARATIONS ///.
ABC_DLL void Abc_ObjAddFanin(Abc_Obj_t *pObj, Abc_Obj_t *pFanin)
struct Abc_Ntk_t_ Abc_Ntk_t
ABC_DLL void Abc_NtkAddDummyPoNames(Abc_Ntk_t *pNtk)
ABC_DLL char * Abc_SopRegister(Mem_Flex_t *pMan, const char *pName)
DECLARATIONS ///.
ABC_DLL void Abc_NtkAddDummyPiNames(Abc_Ntk_t *pNtk)
#define ABC_ALLOC(type, num)
#define ABC_INFINITY
MACRO DEFINITIONS ///.
#define ABC_CALLOC(type, num)
#define ABC_CONST(number)
PARAMETERS ///.
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
struct Vec_Str_t_ Vec_Str_t
int Mop_ManRemoveIdentical(Mop_Man_t *p, Vec_Int_t *vGroup)
Vec_Int_t * Mop_ManCollectStats(Mop_Man_t *p)
void Mop_ManReduce2(Mop_Man_t *p)
void Mop_ManPrint(Mop_Man_t *p)
char * Mop_ManLoadFile(char *pFileName)
int Mop_ManMergeDist1Pairs(Mop_Man_t *p, Vec_Int_t *vGroup, Vec_Int_t *vGroupPrev, Vec_Int_t *vStats, int nLimit)
Vec_Int_t * Mop_ManCompatiblePairs(Vec_Int_t *vPairs, int nObjs)
void Mop_ManStop(Mop_Man_t *p)
int Mop_ManMergeDist1Pairs2(Mop_Man_t *p, Vec_Int_t *vGroup, Vec_Int_t *vGroupPrev)
int Mop_ManMergeContainAll(Mop_Man_t *p, Vec_Wec_t *vGroups)
Vec_Int_t * Mop_ManFindDist1Pairs(Mop_Man_t *p, Vec_Int_t *vGroup)
Vec_Wec_t * Mop_ManCubeCount(Mop_Man_t *p)
Mop_Man_t * Mop_ManAlloc(int nIns, int nOuts, int nCubes)
FUNCTION DEFINITIONS ///.
void Mop_ManReduce(Mop_Man_t *p)
Abc_Ntk_t * Mop_ManTest(char *pFileName, int fMerge, int fVerbose)
Mop_Man_t * Mop_ManRead(char *pFileName)
void Mop_ManPrintOne(Mop_Man_t *p, int iCube)
Abc_Ntk_t * Mop_ManDerive(Mop_Man_t *p, char *pFileName)
int Mop_ManMergeContainTwo(Mop_Man_t *p, Vec_Int_t *vGroup, Vec_Int_t *vGroup2)
int Mop_ManReadParams(char *pBuffer, int *pnIns, int *pnOuts)
int Mop_ManMergeDist1All(Mop_Man_t *p, Vec_Wec_t *vGroups, Vec_Int_t *vStats, int nLimit)
typedefABC_NAMESPACE_IMPL_START struct Mop_Man_t_ Mop_Man_t
DECLARATIONS ///.
unsigned __int64 word
DECLARATIONS ///.
struct Mem_Flex_t_ Mem_Flex_t
#define Vec_IntForEachEntryDouble(vVec, Entry1, Entry2, i)
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
#define Vec_IntForEachEntryStart(vVec, Entry, i, Start)
#define Vec_WecForEachLevel(vGlob, vVec, i)
MACRO DEFINITIONS ///.
#define Vec_WecForEachLevelReverse(vGlob, vVec, i)
#define Vec_WecForEachLevelStart(vGlob, vVec, i, LevelStart)
typedefABC_NAMESPACE_HEADER_START struct Vec_Wec_t_ Vec_Wec_t
INCLUDES ///.
typedefABC_NAMESPACE_HEADER_START struct Vec_Wrd_t_ Vec_Wrd_t
INCLUDES ///.