48#define TAB_UNUSED 0x7FFF
67static inline Tab_Tab_t * Tab_TabAlloc(
int LogSize )
70 assert( LogSize >= 4 && LogSize <= 31 );
71 p->SizeMask = (1 << LogSize) - 1;
83 char * pNames[5] = {
"const1",
"and",
"xor",
"mux",
"none"};
88 for ( pEnt =
p->pBins; pEnt < pLimit; pEnt++ )
89 Vec_IntPush( vCosts, -(
int)pEnt->
Cost );
91 for ( i = 0; i < Vec_IntSize(vCosts); i++ )
93 pEnt =
p->pBins + pOrder[i];
94 if ( i == nDivs || pEnt->
Cost == 1 )
96 printf(
"Lit0 = %5d. Lit1 = %5d. Lit2 = %5d. Func = %s. Cost = %3d.\n",
98 Vec_IntPushTwo( vDivs, pEnt->
Func, pEnt->
LitA );
99 Vec_IntPushTwo( vDivs, pEnt->
LitB, pEnt->
LitC );
101 Vec_IntFree( vCosts );
105static inline int Tab_Hash(
int LitA,
int LitB,
int LitC,
int Func,
int Mask )
107 return (LitA * 50331653 + LitB * 100663319 + LitC * 201326611 + Func * 402653189) & Mask;
109static inline void Tab_TabRehash(
Tab_Tab_t *
p )
112 assert(
p->nBins ==
p->SizeMask + 1 );
117 pLimit =
p->pBins +
p->SizeMask + 1;
118 for ( pEnt =
p->pBins; pEnt < pLimit; pEnt++ )
121 p->SizeMask = 2 *
p->SizeMask + 1;
122 for ( pEnt =
p->pBins + 1; pEnt < pLimit; pEnt++ )
124 pBin =
p->pBins + Tab_Hash( pEnt->
LitA, pEnt->
LitB, pEnt->
LitC, pEnt->
Func,
p->SizeMask );
126 pBin->
Table = pEnt -
p->pBins;
130static inline Tab_Obj_t * Tab_TabEntry(
Tab_Tab_t *
p,
int i ) {
return i ?
p->pBins + i : NULL; }
131static inline int Tab_TabHashAdd(
Tab_Tab_t *
p,
int * pLits,
int Func,
int Cost )
133 if (
p->nBins ==
p->SizeMask + 1 )
135 assert(
p->nBins <
p->SizeMask + 1 );
137 Tab_Obj_t * pEnt, * pBin =
p->pBins + Tab_Hash(pLits[0], pLits[1], pLits[2], Func,
p->SizeMask);
138 for ( pEnt = Tab_TabEntry(
p, pBin->
Table); pEnt; pEnt = Tab_TabEntry(
p, pEnt->
Next) )
139 if ( (
int)pEnt->
LitA == pLits[0] && (
int)pEnt->
LitB == pLits[1] && (
int)pEnt->
LitC == pLits[2] && (
int)pEnt->
Func == Func )
140 { pEnt->
Cost += Cost;
return 1; }
141 pEnt =
p->pBins +
p->nBins;
142 pEnt->
LitA = pLits[0];
143 pEnt->
LitB = pLits[1];
144 pEnt->
LitC = pLits[2];
175static inline Div_Type_t Bmc_FxDivOr(
int LitA,
int LitB,
int * pLits,
int * pPhase )
178 if ( Abc_Lit2Var(LitA) == Abc_Lit2Var(LitB) )
182 pLits[0] = Abc_LitNot(LitA);
183 pLits[1] = Abc_LitNot(LitB);
187static inline Div_Type_t Bmc_FxDivXor(
int LitA,
int LitB,
int * pLits,
int * pPhase )
190 *pPhase ^= Abc_LitIsCompl(LitA);
191 *pPhase ^= Abc_LitIsCompl(LitB);
192 pLits[0] = Abc_LitRegular(LitA);
193 pLits[1] = Abc_LitRegular(LitB);
196static inline Div_Type_t Bmc_FxDivMux(
int LitC,
int LitCn,
int LitT,
int LitE,
int * pLits,
int * pPhase )
199 assert( Abc_Lit2Var(LitC) == Abc_Lit2Var(LitCn) );
200 assert( Abc_Lit2Var(LitC) != Abc_Lit2Var(LitT) );
201 assert( Abc_Lit2Var(LitC) != Abc_Lit2Var(LitE) );
202 assert( Abc_Lit2Var(LitC) != Abc_Lit2Var(LitE) );
203 if ( Abc_LitIsCompl(LitC) )
205 LitC = Abc_LitRegular(LitC);
208 if ( Abc_LitIsCompl(LitT) )
211 LitT = Abc_LitNot(LitT);
212 LitE = Abc_LitNot(LitE);
219static inline Div_Type_t Div_FindType(
int LitA[2],
int LitB[2],
int * pLits,
int * pPhase )
223 if ( LitA[0] == -1 && LitA[1] == -1 )
return DIV_CST;
224 if ( LitB[0] == -1 && LitB[1] == -1 )
return DIV_CST;
225 assert( LitA[0] >= 0 && LitB[0] >= 0 );
226 assert( LitA[0] != LitB[0] );
227 if ( LitA[1] == -1 && LitB[1] == -1 )
228 return Bmc_FxDivOr( LitA[0], LitB[0], pLits, pPhase );
229 assert( LitA[1] != LitB[1] );
230 if ( LitA[1] == -1 || LitB[1] == -1 )
237 assert( LitA[0] >= 0 && LitA[1] >= 0 );
238 assert( LitB[0] >= 0 && LitB[1] == -1 );
239 if ( Abc_Lit2Var(LitB[0]) == Abc_Lit2Var(LitA[0]) )
240 return Bmc_FxDivOr( LitB[0], LitA[1], pLits, pPhase );
241 if ( Abc_Lit2Var(LitB[0]) == Abc_Lit2Var(LitA[1]) )
242 return Bmc_FxDivOr( LitB[0], LitA[0], pLits, pPhase );
245 if ( Abc_Lit2Var(LitA[0]) == Abc_Lit2Var(LitB[0]) && Abc_Lit2Var(LitA[1]) == Abc_Lit2Var(LitB[1]) )
246 return Bmc_FxDivXor( LitA[0], LitB[1], pLits, pPhase );
247 if ( Abc_Lit2Var(LitA[0]) == Abc_Lit2Var(LitB[0]) )
248 return Bmc_FxDivMux( LitA[0], LitB[0], LitA[1], LitB[1], pLits, pPhase );
249 if ( Abc_Lit2Var(LitA[0]) == Abc_Lit2Var(LitB[1]) )
250 return Bmc_FxDivMux( LitA[0], LitB[1], LitA[1], LitB[0], pLits, pPhase );
251 if ( Abc_Lit2Var(LitA[1]) == Abc_Lit2Var(LitB[0]) )
252 return Bmc_FxDivMux( LitA[1], LitB[0], LitA[0], LitB[1], pLits, pPhase );
253 if ( Abc_Lit2Var(LitA[1]) == Abc_Lit2Var(LitB[1]) )
254 return Bmc_FxDivMux( LitA[1], LitB[1], LitA[0], LitB[0], pLits, pPhase );
269static inline int Div_AddLit(
int Lit,
int pLits[2] )
271 if ( pLits[0] == -1 )
273 else if ( pLits[1] == -1 )
281 int * pBegA = vA->pArray, * pEndA = vA->pArray + vA->nSize;
282 int * pBegB = vB->pArray, * pEndB = vB->pArray + vB->nSize;
283 pLitsA[0] = pLitsA[1] = pLitsB[0] = pLitsB[1] = -1;
284 while ( pBegA < pEndA && pBegB < pEndB )
286 if ( *pBegA == *pBegB )
287 pBegA++, pBegB++, Counter++;
288 else if ( *pBegA < *pBegB )
290 if ( Div_AddLit( *pBegA++, pLitsA ) )
295 if ( Div_AddLit( *pBegB++, pLitsB ) )
299 while ( pBegA < pEndA )
300 if ( Div_AddLit( *pBegA++, pLitsA ) )
302 while ( pBegB < pEndB )
303 if ( Div_AddLit( *pBegB++, pLitsB ) )
311 Vec_StrFill( vStr, nVars,
'-' );
313 Vec_StrWriteEntry( vStr, Abc_Lit2Var(Lit), (
char)(Abc_LitIsCompl(Lit) ?
'0' :
'1') );
314 printf(
"%s\n", Vec_StrArray(vStr) );
319 Vec_Str_t * vStr = Vec_StrStart( nVars + 1 );
328 char * pNames[5] = {
"const1",
"and",
"xor",
"mux",
"none"};
330 int i1, i2, i, k, pLitsA[2], pLitsB[2], pLits[4], Type, Phase, nBase, Count = 0;
331 Vec_Str_t * vStr = Vec_StrStart( nVars + 1 );
340 Tab_TabHashAdd( pTab, pLits,
DIV_AND, 1 );
345 nBase =
Div_FindDiv( vCube1, vCube2, pLitsA, pLitsB );
348 Type = Div_FindType(pLitsA, pLitsB, pLits, &Phase);
350 Tab_TabHashAdd( pTab, pLits, Type, nBase );
354 printf(
"Pair %d:\n", Count++ );
357 printf(
"Result = %d ", nBase );
360 printf(
"Type = %s ", pNames[Type] );
361 printf(
"LitA = %d ", pLits[0] );
362 printf(
"LitB = %d ", pLits[1] );
363 printf(
"LitC = %d ", pLits[2] );
364 printf(
"Phase = %d ", Phase );
370 printf(
"Divisors = %d.\n", pTab->
nBins );
371 vDivs = Tab_TabFindBest( pTab, nDivs );
391 int nBTLimit = 1000000;
394 Vec_Int_t * vLits = Vec_IntAlloc( Vec_IntSize(vVars) );
395 Vec_Int_t * vLits2 = Vec_IntAlloc( Vec_IntSize(vVars) );
396 Vec_Str_t * vCube = Vec_StrStart( Vec_IntSize(vVars)+1 );
397 int status, i, k, n, Lit, Lit2, iVar, nFinal, * pFinal, pLits[2], nIter = 0, RetValue = 0;
398 int Before, After, Total = 0, nLits = 0;
399 pLits[0] = Abc_Var2Lit( iOut + 1, 0 );
400 pLits[1] = Abc_Var2Lit( iAuxVar, 0 );
402 Vec_WecClear( vCubes );
404 printf(
".i %d\n", Vec_IntSize(vVars) );
406 printf(
".o %d\n", 1 );
412 { RetValue = -1;
break; }
414 { RetValue = 1;
break; }
417 Vec_IntClear( vLits );
418 Vec_IntPush( vLits, Abc_LitNot(pLits[0]) );
421 Vec_IntPush( vLits, sat_solver_var_literal(pSat, iVar) );
427 Vec_IntClear( vLits2 );
428 Vec_IntAppend( vLits2, vLits );
429 Before = Vec_IntSize(vLits2);
434 if ( Lit2 == Abc_LitNot(pLits[0]) )
436 Vec_IntClear( vLits );
438 if ( Lit != -1 && Lit != Lit2 )
439 Vec_IntPush( vLits, Lit );
441 status =
sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits), nBTLimit, 0, 0, 0 );
447 Vec_IntWriteEntry( vLits2, k, -1 );
451 Vec_IntClear( vLits );
454 Vec_IntPush( vLits, Lit2 );
455 status =
sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits), nBTLimit, 0, 0, 0 );
459 nFinal = sat_solver_final( pSat, &pFinal );
466 status =
sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits), nBTLimit, 0, 0, 0 );
468 { RetValue = -1;
break; }
473 nFinal = sat_solver_final( pSat, &pFinal );
491 Vec_IntClear( vLits2 );
492 for ( i = 0; i < nFinal; i++ )
493 Vec_IntPush( vLits2, Abc_LitNot(pFinal[i]) );
494 Vec_IntSort( vLits2, 1 );
499 if ( Lit2 == Abc_LitNot(pLits[0]) )
501 Vec_IntClear( vLits );
503 if ( Lit != -1 && Lit != Lit2 )
504 Vec_IntPush( vLits, Lit );
506 status =
sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits), nBTLimit, 0, 0, 0 );
512 Vec_IntWriteEntry( vLits2, k, -1 );
516 Vec_IntClear( vLits );
519 Vec_IntPush( vLits, Lit2 );
520 status =
sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits), nBTLimit, 0, 0, 0 );
527 pFinal[nFinal++] = Abc_LitNot(Lit2);
534 Total += Before - After;
539 Vec_IntClear( vLits );
540 Vec_IntPush( vLits, Abc_LitNot(pLits[1]) );
542 Vec_StrFill( vCube, Vec_IntSize(vVars),
'-' );
544 vLevel = Vec_WecPushLevel( vCubes );
545 for ( i = 0; i < nFinal; i++ )
547 if ( pFinal[i] == pLits[0] )
549 Vec_IntPush( vLits, pFinal[i] );
550 iVar = Vec_IntFind( vVars, Abc_Lit2Var(pFinal[i]) );
551 assert( iVar >= 0 && iVar < Vec_IntSize(vVars) );
554 Vec_StrWriteEntry( vCube, iVar, (
char)(!Abc_LitIsCompl(pFinal[i]) ?
'0' :
'1') );
556 Vec_IntPush( vLevel, Abc_Var2Lit(iVar, !Abc_LitIsCompl(pFinal[i])) );
559 Vec_IntSort( vLevel, 0 );
561 printf(
"%s 1\n", Vec_StrArray(vCube) );
562 status =
sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits) );
564 nLits += Vec_IntSize(vLevel);
570 printf(
".p %d\n\n", nIter );
572 printf(
"Cubes = %d. Reduced = %d. Lits = %d\n", nIter, Total, nLits );
576 Vec_IntFree( vLits );
577 Vec_IntFree( vLits2 );
578 Vec_StrFree( vCube );
602 int nOuts = Gia_ManCoNum(
p);
603 int nCiVars = Gia_ManCiNum(
p), iCiVarBeg = pCnf->
nVars - nCiVars;
605 int nCubes[2][2] = {{0}};
607 Vec_Int_t * vVars = Vec_IntAlloc( nCiVars );
608 for ( n = 0; n < nCiVars; n++ )
609 Vec_IntPush( vVars, iCiVarBeg + n );
612 for ( o = 0; o < nOuts; o++ )
613 for ( i = 0; i < 2; i++ )
614 for ( n = 0; n < 2; n++ )
617 printf(
"Out %3d %sset ", o, n ?
"off" :
" on" );
618 RetValue =
Bmc_FxSolve( pSat, Abc_Var2Lit(o, n), iAuxVarStart + 2*i*nOuts + Abc_Var2Lit(o, n), vVars, 0, 0, &nCounter, NULL );
620 printf(
"Mismatch\n" );
621 if ( RetValue == -1 )
622 printf(
"Timeout\n" );
623 nCubes[i][n] += nCounter;
626 Vec_IntFree( vVars );
630 printf(
"Onset = %5d. Offset = %5d. Onset = %5d. Offset = %5d.\n", nCubes[0][0], nCubes[0][1], nCubes[1][0], nCubes[1][1] );
647 int i, Func, pLits[3], nDivs = Vec_IntSize(vDivs)/4;
648 assert( Vec_IntSize(vDivs) % 4 == 0 );
650 for ( i = 0; i < nDivs; i++ )
652 Func = Vec_IntEntry(vDivs, 4*i+0);
653 pLits[0] = Vec_IntEntry(vDivs, 4*i+1);
654 pLits[1] = Vec_IntEntry(vDivs, 4*i+2);
655 pLits[2] = Vec_IntEntry(vDivs, 4*i+3);
659 iVarStart + nDivs - 1 - i, iCiVarBeg + Abc_Lit2Var(pLits[0]), iCiVarBeg + Abc_Lit2Var(pLits[1]),
660 Abc_LitIsCompl(pLits[0]), Abc_LitIsCompl(pLits[1]), 0 );
663 iVarStart + nDivs - 1 - i, iCiVarBeg + Abc_Lit2Var(pLits[0]), iCiVarBeg + Abc_Lit2Var(pLits[1]), 0 );
665 sat_solver_add_mux( pSat,
666 iVarStart + nDivs - 1 - i, iCiVarBeg + Abc_Lit2Var(pLits[0]), iCiVarBeg + Abc_Lit2Var(pLits[1]), iCiVarBeg + Abc_Lit2Var(pLits[2]),
667 Abc_LitIsCompl(pLits[0]), Abc_LitIsCompl(pLits[1]), Abc_LitIsCompl(pLits[2]), 0 );
678 int nCiVars = Gia_ManCiNum(
p);
679 int iCiVarBeg = pCnf->
nVars - nCiVars;
680 int iCiVarCur = iCiVarBeg + nCiVars;
681 int n, Iter, RetValue;
685 for ( Iter = 0; Iter < nIterMax; Iter++ )
687 Vec_Wec_t * vCubes = Vec_WecAlloc( 1000 );
689 Vec_Int_t * vVar2Sat = Vec_IntAlloc( iCiVarCur-iCiVarBeg ), * vDivs;
691 for ( n = iCiVarBeg; n < iCiVarCur; n++ )
692 Vec_IntPush( vVar2Sat, n );
694 printf(
"\nIteration %d (Aux = %d)\n", Iter, iAuxVarStart + Iter );
695 RetValue =
Bmc_FxSolve( pSat, 0, iAuxVarStart + Iter, vVar2Sat, 1, 1, NULL, vCubes );
697 printf(
"Mismatch\n" );
698 if ( RetValue == -1 )
699 printf(
"Timeout\n" );
703 Vec_WecFree( vCubes );
706 iCiVarCur += Vec_IntSize(vDivs)/4;
707 Vec_IntFree( vDivs );
709 assert( Vec_IntSize(vVar2Sat) <= nCiVars + Extra );
710 Vec_IntFree( vVar2Sat );
#define ABC_SWAP(Type, a, b)
int * Abc_MergeSortCost(int *pCosts, int nSize)
#define ABC_REALLOC(type, obj, num)
#define ABC_CALLOC(type, num)
#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
struct Tab_Tab_t_ Tab_Tab_t
int Bmc_FxSolve(sat_solver *pSat, int iOut, int iAuxVar, Vec_Int_t *vVars, int fDumpPla, int fVerbose, int *pCounter, Vec_Wec_t *vCubes)
int Bmc_FxCompute(Gia_Man_t *p)
void Div_CubePrint(Vec_Wec_t *p, int nVars)
void Div_CubePrintOne(Vec_Int_t *vCube, Vec_Str_t *vStr, int nVars)
int Bmc_FxComputeOne(Gia_Man_t *p, int nIterMax, int nDiv2Add)
Vec_Int_t * Div_CubePairs(Vec_Wec_t *p, int nVars, int nDivs)
void Bmc_FxAddClauses(sat_solver *pSat, Vec_Int_t *vDivs, int iCiVarBeg, int iVarStart)
int Div_FindDiv(Vec_Int_t *vA, Vec_Int_t *vB, int pLitsA[2], int pLitsB[2])
#define sat_solver_addclause
#define sat_solver_add_and
#define sat_solver_add_xor
struct Cnf_Dat_t_ Cnf_Dat_t
void Cnf_DataFree(Cnf_Dat_t *p)
Gia_Man_t * Gia_ManDupOnsetOffset(Gia_Man_t *p)
void Gia_ManStop(Gia_Man_t *p)
struct Gia_Man_t_ Gia_Man_t
void * Mf_ManGenerateCnf(Gia_Man_t *pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fMapping, int fVerbose)
struct Tab_Obj_t_ Tab_Obj_t
void * Cnf_DataWriteIntoSolver(Cnf_Dat_t *p, int nFrames, int fInit)
void sat_solver_setnvars(sat_solver *s, int n)
int sat_solver_nvars(sat_solver *s)
void sat_solver_delete(sat_solver *s)
#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_WecForEachLevelStart(vGlob, vVec, i, LevelStart)
typedefABC_NAMESPACE_HEADER_START struct Vec_Wec_t_ Vec_Wec_t
INCLUDES ///.