/**CFile**************************************************************** FileName [bmcFx.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [SAT-based bounded model checking.] Synopsis [INT-FX: Interpolation-based logic sharing extraction.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: bmcFx.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ #include "bmc.h" #include "misc/vec/vecWec.h" #include "sat/cnf/cnf.h" #include "sat/bsat/satStore.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Create hash table to hash divisors.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ #define TAB_UNUSED 0x7FFF typedef struct Tab_Obj_t_ Tab_Obj_t; // 16 bytes struct Tab_Obj_t_ { int Table; int Next; unsigned Cost : 17; unsigned LitA : 15; unsigned LitB : 15; unsigned LitC : 15; unsigned Func : 2; }; typedef struct Tab_Tab_t_ Tab_Tab_t; // 16 bytes struct Tab_Tab_t_ { int SizeMask; int nBins; Tab_Obj_t * pBins; }; static inline Tab_Tab_t * Tab_TabAlloc( int LogSize ) { Tab_Tab_t * p = ABC_CALLOC( Tab_Tab_t, 1 ); assert( LogSize >= 4 && LogSize <= 31 ); p->SizeMask = (1 << LogSize) - 1; p->pBins = ABC_CALLOC( Tab_Obj_t, p->SizeMask + 1 ); p->nBins = 1; return p; } static inline void Tab_TabFree( Tab_Tab_t * p ) { ABC_FREE( p->pBins ); ABC_FREE( p ); } static inline Vec_Int_t * Tab_TabFindBest( Tab_Tab_t * p, int nDivs ) { char * pNames[5] = {"const1", "and", "xor", "mux", "none"}; int * pOrder, i; Vec_Int_t * vDivs = Vec_IntAlloc( 100 ); Vec_Int_t * vCosts = Vec_IntAlloc( p->nBins ); Tab_Obj_t * pEnt, * pLimit = p->pBins + p->nBins; for ( pEnt = p->pBins; pEnt < pLimit; pEnt++ ) Vec_IntPush( vCosts, -(int)pEnt->Cost ); pOrder = Abc_MergeSortCost( Vec_IntArray(vCosts), Vec_IntSize(vCosts) ); for ( i = 0; i < Vec_IntSize(vCosts); i++ ) { pEnt = p->pBins + pOrder[i]; if ( i == nDivs || pEnt->Cost == 1 ) break; printf( "Lit0 = %5d. Lit1 = %5d. Lit2 = %5d. Func = %s. Cost = %3d.\n", pEnt->LitA, pEnt->LitB, pEnt->LitC, pNames[pEnt->Func], pEnt->Cost ); Vec_IntPushTwo( vDivs, pEnt->Func, pEnt->LitA ); Vec_IntPushTwo( vDivs, pEnt->LitB, pEnt->LitC ); } Vec_IntFree( vCosts ); ABC_FREE( pOrder ); return vDivs; } static inline int Tab_Hash( int LitA, int LitB, int LitC, int Func, int Mask ) { return (LitA * 50331653 + LitB * 100663319 + LitC * 201326611 + Func * 402653189) & Mask; } static inline void Tab_TabRehash( Tab_Tab_t * p ) { Tab_Obj_t * pEnt, * pLimit, * pBin; assert( p->nBins == p->SizeMask + 1 ); // realloc memory p->pBins = ABC_REALLOC( Tab_Obj_t, p->pBins, 2 * (p->SizeMask + 1) ); memset( p->pBins + p->SizeMask + 1, 0, sizeof(Tab_Obj_t) * (p->SizeMask + 1) ); // clean entries pLimit = p->pBins + p->SizeMask + 1; for ( pEnt = p->pBins; pEnt < pLimit; pEnt++ ) pEnt->Table = pEnt->Next = 0; // rehash entries p->SizeMask = 2 * p->SizeMask + 1; for ( pEnt = p->pBins + 1; pEnt < pLimit; pEnt++ ) { pBin = p->pBins + Tab_Hash( pEnt->LitA, pEnt->LitB, pEnt->LitC, pEnt->Func, p->SizeMask ); pEnt->Next = pBin->Table; pBin->Table = pEnt - p->pBins; assert( !pEnt->Next || pEnt->Next != pBin->Table ); } } static inline Tab_Obj_t * Tab_TabEntry( Tab_Tab_t * p, int i ) { return i ? p->pBins + i : NULL; } static inline int Tab_TabHashAdd( Tab_Tab_t * p, int * pLits, int Func, int Cost ) { if ( p->nBins == p->SizeMask + 1 ) Tab_TabRehash( p ); assert( p->nBins < p->SizeMask + 1 ); { Tab_Obj_t * pEnt, * pBin = p->pBins + Tab_Hash(pLits[0], pLits[1], pLits[2], Func, p->SizeMask); for ( pEnt = Tab_TabEntry(p, pBin->Table); pEnt; pEnt = Tab_TabEntry(p, pEnt->Next) ) if ( (int)pEnt->LitA == pLits[0] && (int)pEnt->LitB == pLits[1] && (int)pEnt->LitC == pLits[2] && (int)pEnt->Func == Func ) { pEnt->Cost += Cost; return 1; } pEnt = p->pBins + p->nBins; pEnt->LitA = pLits[0]; pEnt->LitB = pLits[1]; pEnt->LitC = pLits[2]; pEnt->Func = Func; pEnt->Cost = Cost; pEnt->Next = pBin->Table; pBin->Table = p->nBins++; assert( !pEnt->Next || pEnt->Next != pBin->Table ); return 0; } } /**Function************************************************************* Synopsis [Input is four literals. Output is type, polarity and fanins.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ // name types typedef enum { DIV_CST = 0, // 0: constant 1 DIV_AND, // 1: and (ordered fanins) DIV_XOR, // 2: xor (ordered fanins) DIV_MUX, // 3: mux (c, d1, d0) DIV_NONE // 4: not used } Div_Type_t; static inline Div_Type_t Bmc_FxDivOr( int LitA, int LitB, int * pLits, int * pPhase ) { assert( LitA != LitB ); if ( Abc_Lit2Var(LitA) == Abc_Lit2Var(LitB) ) return DIV_CST; if ( LitA > LitB ) ABC_SWAP( int, LitA, LitB ); pLits[0] = Abc_LitNot(LitA); pLits[1] = Abc_LitNot(LitB); *pPhase = 1; return DIV_AND; } static inline Div_Type_t Bmc_FxDivXor( int LitA, int LitB, int * pLits, int * pPhase ) { assert( LitA != LitB ); *pPhase ^= Abc_LitIsCompl(LitA); *pPhase ^= Abc_LitIsCompl(LitB); pLits[0] = Abc_LitRegular(LitA); pLits[1] = Abc_LitRegular(LitB); return DIV_XOR; } static inline Div_Type_t Bmc_FxDivMux( int LitC, int LitCn, int LitT, int LitE, int * pLits, int * pPhase ) { assert( LitC != LitCn ); assert( Abc_Lit2Var(LitC) == Abc_Lit2Var(LitCn) ); assert( Abc_Lit2Var(LitC) != Abc_Lit2Var(LitT) ); assert( Abc_Lit2Var(LitC) != Abc_Lit2Var(LitE) ); assert( Abc_Lit2Var(LitC) != Abc_Lit2Var(LitE) ); if ( Abc_LitIsCompl(LitC) ) { LitC = Abc_LitRegular(LitC); ABC_SWAP( int, LitT, LitE ); } if ( Abc_LitIsCompl(LitT) ) { *pPhase ^= 1; LitT = Abc_LitNot(LitT); LitE = Abc_LitNot(LitE); } pLits[0] = LitC; pLits[1] = LitT; pLits[2] = LitE; return DIV_MUX; } static inline Div_Type_t Div_FindType( int LitA[2], int LitB[2], int * pLits, int * pPhase ) { *pPhase = 0; pLits[0] = pLits[1] = pLits[2] = TAB_UNUSED; if ( LitA[0] == -1 && LitA[1] == -1 ) return DIV_CST; if ( LitB[0] == -1 && LitB[1] == -1 ) return DIV_CST; assert( LitA[0] >= 0 && LitB[0] >= 0 ); assert( LitA[0] != LitB[0] ); if ( LitA[1] == -1 && LitB[1] == -1 ) return Bmc_FxDivOr( LitA[0], LitB[0], pLits, pPhase ); assert( LitA[1] != LitB[1] ); if ( LitA[1] == -1 || LitB[1] == -1 ) { if ( LitA[1] == -1 ) { ABC_SWAP( int, LitA[0], LitB[0] ); ABC_SWAP( int, LitA[1], LitB[1] ); } assert( LitA[0] >= 0 && LitA[1] >= 0 ); assert( LitB[0] >= 0 && LitB[1] == -1 ); if ( Abc_Lit2Var(LitB[0]) == Abc_Lit2Var(LitA[0]) ) return Bmc_FxDivOr( LitB[0], LitA[1], pLits, pPhase ); if ( Abc_Lit2Var(LitB[0]) == Abc_Lit2Var(LitA[1]) ) return Bmc_FxDivOr( LitB[0], LitA[0], pLits, pPhase ); return DIV_NONE; } if ( Abc_Lit2Var(LitA[0]) == Abc_Lit2Var(LitB[0]) && Abc_Lit2Var(LitA[1]) == Abc_Lit2Var(LitB[1]) ) return Bmc_FxDivXor( LitA[0], LitB[1], pLits, pPhase ); if ( Abc_Lit2Var(LitA[0]) == Abc_Lit2Var(LitB[0]) ) return Bmc_FxDivMux( LitA[0], LitB[0], LitA[1], LitB[1], pLits, pPhase ); if ( Abc_Lit2Var(LitA[0]) == Abc_Lit2Var(LitB[1]) ) return Bmc_FxDivMux( LitA[0], LitB[1], LitA[1], LitB[0], pLits, pPhase ); if ( Abc_Lit2Var(LitA[1]) == Abc_Lit2Var(LitB[0]) ) return Bmc_FxDivMux( LitA[1], LitB[0], LitA[0], LitB[1], pLits, pPhase ); if ( Abc_Lit2Var(LitA[1]) == Abc_Lit2Var(LitB[1]) ) return Bmc_FxDivMux( LitA[1], LitB[1], LitA[0], LitB[0], pLits, pPhase ); return DIV_NONE; } /**Function************************************************************* Synopsis [Returns the number of shared variables, or -1 if failed.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline int Div_AddLit( int Lit, int pLits[2] ) { if ( pLits[0] == -1 ) pLits[0] = Lit; else if ( pLits[1] == -1 ) pLits[1] = Lit; else return 1; return 0; } int Div_FindDiv( Vec_Int_t * vA, Vec_Int_t * vB, int pLitsA[2], int pLitsB[2] ) { int Counter = 0; int * pBegA = vA->pArray, * pEndA = vA->pArray + vA->nSize; int * pBegB = vB->pArray, * pEndB = vB->pArray + vB->nSize; pLitsA[0] = pLitsA[1] = pLitsB[0] = pLitsB[1] = -1; while ( pBegA < pEndA && pBegB < pEndB ) { if ( *pBegA == *pBegB ) pBegA++, pBegB++, Counter++; else if ( *pBegA < *pBegB ) { if ( Div_AddLit( *pBegA++, pLitsA ) ) return -1; } else { if ( Div_AddLit( *pBegB++, pLitsB ) ) return -1; } } while ( pBegA < pEndA ) if ( Div_AddLit( *pBegA++, pLitsA ) ) return -1; while ( pBegB < pEndB ) if ( Div_AddLit( *pBegB++, pLitsB ) ) return -1; return Counter; } void Div_CubePrintOne( Vec_Int_t * vCube, Vec_Str_t * vStr, int nVars ) { int i, Lit; Vec_StrFill( vStr, nVars, '-' ); Vec_IntForEachEntry( vCube, Lit, i ) Vec_StrWriteEntry( vStr, Abc_Lit2Var(Lit), (char)(Abc_LitIsCompl(Lit) ? '0' : '1') ); printf( "%s\n", Vec_StrArray(vStr) ); } void Div_CubePrint( Vec_Wec_t * p, int nVars ) { Vec_Int_t * vCube; int i; Vec_Str_t * vStr = Vec_StrStart( nVars + 1 ); Vec_WecForEachLevel( p, vCube, i ) Div_CubePrintOne( vCube, vStr, nVars ); Vec_StrFree( vStr ); } Vec_Int_t * Div_CubePairs( Vec_Wec_t * p, int nVars, int nDivs ) { int fVerbose = 0; char * pNames[5] = {"const1", "and", "xor", "mux", "none"}; Vec_Int_t * vCube1, * vCube2, * vDivs; int i1, i2, i, k, pLitsA[2], pLitsB[2], pLits[4], Type, Phase, nBase, Count = 0; Vec_Str_t * vStr = Vec_StrStart( nVars + 1 ); Tab_Tab_t * pTab = Tab_TabAlloc( 5 ); Vec_WecForEachLevel( p, vCube1, i ) { // add lit pairs pLits[2] = TAB_UNUSED; Vec_IntForEachEntry( vCube1, pLits[0], i1 ) Vec_IntForEachEntryStart( vCube1, pLits[1], i2, i1+1 ) { Tab_TabHashAdd( pTab, pLits, DIV_AND, 1 ); } Vec_WecForEachLevelStart( p, vCube2, k, i+1 ) { nBase = Div_FindDiv( vCube1, vCube2, pLitsA, pLitsB ); if ( nBase == -1 ) continue; Type = Div_FindType(pLitsA, pLitsB, pLits, &Phase); if ( Type >= DIV_AND && Type <= DIV_MUX ) Tab_TabHashAdd( pTab, pLits, Type, nBase ); if ( fVerbose ) { printf( "Pair %d:\n", Count++ ); Div_CubePrintOne( vCube1, vStr, nVars ); Div_CubePrintOne( vCube2, vStr, nVars ); printf( "Result = %d ", nBase ); assert( nBase > 0 ); printf( "Type = %s ", pNames[Type] ); printf( "LitA = %d ", pLits[0] ); printf( "LitB = %d ", pLits[1] ); printf( "LitC = %d ", pLits[2] ); printf( "Phase = %d ", Phase ); printf( "\n" ); } } } // print the table printf( "Divisors = %d.\n", pTab->nBins ); vDivs = Tab_TabFindBest( pTab, nDivs ); // cleanup Vec_StrFree( vStr ); Tab_TabFree( pTab ); return vDivs; } /**Function************************************************************* Synopsis [Solve the enumeration problem.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ 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 nBTLimit = 1000000; int fUseOrder = 1; Vec_Int_t * vLevel = NULL; Vec_Int_t * vLits = Vec_IntAlloc( Vec_IntSize(vVars) ); Vec_Int_t * vLits2 = Vec_IntAlloc( Vec_IntSize(vVars) ); Vec_Str_t * vCube = Vec_StrStart( Vec_IntSize(vVars)+1 ); int status, i, k, n, Lit, Lit2, iVar, nFinal, * pFinal, pLits[2], nIter = 0, RetValue = 0; int Before, After, Total = 0, nLits = 0; pLits[0] = Abc_Var2Lit( iOut + 1, 0 ); // F = 1 pLits[1] = Abc_Var2Lit( iAuxVar, 0 ); // iNewLit if ( vCubes ) Vec_WecClear( vCubes ); if ( fDumpPla ) printf( ".i %d\n", Vec_IntSize(vVars) ); if ( fDumpPla ) printf( ".o %d\n", 1 ); while ( 1 ) { // find onset minterm status = sat_solver_solve( pSat, pLits, pLits + 2, nBTLimit, 0, 0, 0 ); if ( status == l_Undef ) { RetValue = -1; break; } if ( status == l_False ) { RetValue = 1; break; } assert( status == l_True ); // collect divisor literals Vec_IntClear( vLits ); Vec_IntPush( vLits, Abc_LitNot(pLits[0]) ); // F = 0 // Vec_IntForEachEntryReverse( vVars, iVar, i ) Vec_IntForEachEntry( vVars, iVar, i ) Vec_IntPush( vLits, sat_solver_var_literal(pSat, iVar) ); if ( fUseOrder ) { ////////////////////////////////////////////////////////////// // save these literals Vec_IntClear( vLits2 ); Vec_IntAppend( vLits2, vLits ); Before = Vec_IntSize(vLits2); // try removing literals from the cube Vec_IntForEachEntry( vLits2, Lit2, k ) { if ( Lit2 == Abc_LitNot(pLits[0]) ) continue; Vec_IntClear( vLits ); Vec_IntForEachEntry( vLits2, Lit, n ) if ( Lit != -1 && Lit != Lit2 ) Vec_IntPush( vLits, Lit ); // call sat status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits), nBTLimit, 0, 0, 0 ); if ( status == l_Undef ) assert( 0 ); if ( status == l_True ) // SAT continue; // Lit2 can be removed Vec_IntWriteEntry( vLits2, k, -1 ); } // make one final run Vec_IntClear( vLits ); Vec_IntForEachEntry( vLits2, Lit2, k ) if ( Lit2 != -1 ) Vec_IntPush( vLits, Lit2 ); status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits), nBTLimit, 0, 0, 0 ); assert( status == l_False ); // get subset of literals nFinal = sat_solver_final( pSat, &pFinal ); ////////////////////////////////////////////////////////////// } else { /////////////////////////////////////////////////////////////// // check against offset status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits), nBTLimit, 0, 0, 0 ); if ( status == l_Undef ) { RetValue = -1; break; } if ( status == l_True ) break; assert( status == l_False ); // get subset of literals nFinal = sat_solver_final( pSat, &pFinal ); Before = nFinal; //printf( "Before %d. ", nFinal ); /* // save these literals Vec_IntClear( vLits ); for ( i = 0; i < nFinal; i++ ) Vec_IntPush( vLits, Abc_LitNot(pFinal[i]) ); Vec_IntReverseOrder( vLits ); // make one final run status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits), nBTLimit, 0, 0, 0 ); assert( status == l_False ); nFinal = sat_solver_final( pSat, &pFinal ); */ // save these literals Vec_IntClear( vLits2 ); for ( i = 0; i < nFinal; i++ ) Vec_IntPush( vLits2, Abc_LitNot(pFinal[i]) ); Vec_IntSort( vLits2, 1 ); // try removing literals from the cube Vec_IntForEachEntry( vLits2, Lit2, k ) { if ( Lit2 == Abc_LitNot(pLits[0]) ) continue; Vec_IntClear( vLits ); Vec_IntForEachEntry( vLits2, Lit, n ) if ( Lit != -1 && Lit != Lit2 ) Vec_IntPush( vLits, Lit ); // call sat status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits), nBTLimit, 0, 0, 0 ); if ( status == l_Undef ) assert( 0 ); if ( status == l_True ) // SAT continue; // Lit2 can be removed Vec_IntWriteEntry( vLits2, k, -1 ); } // make one final run Vec_IntClear( vLits ); Vec_IntForEachEntry( vLits2, Lit2, k ) if ( Lit2 != -1 ) Vec_IntPush( vLits, Lit2 ); status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits), nBTLimit, 0, 0, 0 ); assert( status == l_False ); // put them back nFinal = 0; Vec_IntForEachEntry( vLits2, Lit2, k ) if ( Lit2 != -1 ) pFinal[nFinal++] = Abc_LitNot(Lit2); ///////////////////////////////////////////////////////// } //printf( "After %d. \n", nFinal ); After = nFinal; Total += Before - After; // get subset of literals //nFinal = sat_solver_final( pSat, &pFinal ); // compute cube and add clause Vec_IntClear( vLits ); Vec_IntPush( vLits, Abc_LitNot(pLits[1]) ); // NOT(iNewLit) if ( fDumpPla ) Vec_StrFill( vCube, Vec_IntSize(vVars), '-' ); if ( vCubes ) vLevel = Vec_WecPushLevel( vCubes ); for ( i = 0; i < nFinal; i++ ) { if ( pFinal[i] == pLits[0] ) continue; Vec_IntPush( vLits, pFinal[i] ); iVar = Vec_IntFind( vVars, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 && iVar < Vec_IntSize(vVars) ); //printf( "%s%d ", Abc_LitIsCompl(pFinal[i]) ? "+":"-", iVar ); if ( fDumpPla ) Vec_StrWriteEntry( vCube, iVar, (char)(!Abc_LitIsCompl(pFinal[i]) ? '0' : '1') ); if ( vLevel ) Vec_IntPush( vLevel, Abc_Var2Lit(iVar, !Abc_LitIsCompl(pFinal[i])) ); } if ( vCubes ) Vec_IntSort( vLevel, 0 ); if ( fDumpPla ) printf( "%s 1\n", Vec_StrArray(vCube) ); status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits) ); assert( status ); nLits += Vec_IntSize(vLevel); nIter++; } if ( fDumpPla ) printf( ".e\n" ); if ( fDumpPla ) printf( ".p %d\n\n", nIter ); if ( fVerbose ) printf( "Cubes = %d. Reduced = %d. Lits = %d\n", nIter, Total, nLits ); if ( pCounter ) *pCounter = nIter; // assert( status == l_True ); Vec_IntFree( vLits ); Vec_IntFree( vLits2 ); Vec_StrFree( vCube ); return RetValue; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Bmc_FxCompute( Gia_Man_t * p ) { // create dual-output circuit with on-set/off-set extern Gia_Man_t * Gia_ManDupOnsetOffset( Gia_Man_t * p ); Gia_Man_t * p2 = Gia_ManDupOnsetOffset( p ); // create SAT solver Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p2, 8, 0, 0, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); // compute parameters int nOuts = Gia_ManCoNum(p); int nCiVars = Gia_ManCiNum(p), iCiVarBeg = pCnf->nVars - nCiVars;// - 1; int o, i, n, RetValue, nCounter, iAuxVarStart = sat_solver_nvars( pSat ); int nCubes[2][2] = {{0}}; // create variables Vec_Int_t * vVars = Vec_IntAlloc( nCiVars ); for ( n = 0; n < nCiVars; n++ ) Vec_IntPush( vVars, iCiVarBeg + n ); sat_solver_setnvars( pSat, iAuxVarStart + 4*nOuts ); // iterate through outputs for ( o = 0; o < nOuts; o++ ) for ( i = 0; i < 2; i++ ) for ( n = 0; n < 2; n++ ) // 0=onset, 1=offset // for ( n = 1; n >= 0; n-- ) // 0=onset, 1=offset { printf( "Out %3d %sset ", o, n ? "off" : " on" ); RetValue = Bmc_FxSolve( pSat, Abc_Var2Lit(o, n), iAuxVarStart + 2*i*nOuts + Abc_Var2Lit(o, n), vVars, 0, 0, &nCounter, NULL ); if ( RetValue == 0 ) printf( "Mismatch\n" ); if ( RetValue == -1 ) printf( "Timeout\n" ); nCubes[i][n] += nCounter; } // cleanup Vec_IntFree( vVars ); sat_solver_delete( pSat ); Cnf_DataFree( pCnf ); Gia_ManStop( p2 ); printf( "Onset = %5d. Offset = %5d. Onset = %5d. Offset = %5d.\n", nCubes[0][0], nCubes[0][1], nCubes[1][0], nCubes[1][1] ); return 1; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Bmc_FxAddClauses( sat_solver * pSat, Vec_Int_t * vDivs, int iCiVarBeg, int iVarStart ) { int i, Func, pLits[3], nDivs = Vec_IntSize(vDivs)/4; assert( Vec_IntSize(vDivs) % 4 == 0 ); // create new var for each divisor for ( i = 0; i < nDivs; i++ ) { Func = Vec_IntEntry(vDivs, 4*i+0); pLits[0] = Vec_IntEntry(vDivs, 4*i+1); pLits[1] = Vec_IntEntry(vDivs, 4*i+2); pLits[2] = Vec_IntEntry(vDivs, 4*i+3); //printf( "Adding clause with vars %d %d -> %d\n", iCiVarBeg + Abc_Lit2Var(pLits[0]), iCiVarBeg + Abc_Lit2Var(pLits[1]), iVarStart + nDivs - 1 - i ); if ( Func == DIV_AND ) sat_solver_add_and( pSat, iVarStart + nDivs - 1 - i, iCiVarBeg + Abc_Lit2Var(pLits[0]), iCiVarBeg + Abc_Lit2Var(pLits[1]), Abc_LitIsCompl(pLits[0]), Abc_LitIsCompl(pLits[1]), 0 ); else if ( Func == DIV_XOR ) sat_solver_add_xor( pSat, iVarStart + nDivs - 1 - i, iCiVarBeg + Abc_Lit2Var(pLits[0]), iCiVarBeg + Abc_Lit2Var(pLits[1]), 0 ); else if ( Func == DIV_MUX ) sat_solver_add_mux( pSat, iVarStart + nDivs - 1 - i, iCiVarBeg + Abc_Lit2Var(pLits[0]), iCiVarBeg + Abc_Lit2Var(pLits[1]), iCiVarBeg + Abc_Lit2Var(pLits[2]), Abc_LitIsCompl(pLits[0]), Abc_LitIsCompl(pLits[1]), Abc_LitIsCompl(pLits[2]), 0 ); else assert( 0 ); } } int Bmc_FxComputeOne( Gia_Man_t * p, int nIterMax, int nDiv2Add ) { int Extra = 1000; // create SAT solver Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); // compute parameters int nCiVars = Gia_ManCiNum(p); // PI count int iCiVarBeg = pCnf->nVars - nCiVars;//- 1; // first PI var int iCiVarCur = iCiVarBeg + nCiVars; // current unused PI var int n, Iter, RetValue; // create variables int iAuxVarStart = sat_solver_nvars(pSat) + Extra; // the aux var sat_solver_setnvars( pSat, iAuxVarStart + 1 + nIterMax ); for ( Iter = 0; Iter < nIterMax; Iter++ ) { Vec_Wec_t * vCubes = Vec_WecAlloc( 1000 ); // collect variables Vec_Int_t * vVar2Sat = Vec_IntAlloc( iCiVarCur-iCiVarBeg ), * vDivs; // for ( n = iCiVarCur - 1; n >= iCiVarBeg; n-- ) for ( n = iCiVarBeg; n < iCiVarCur; n++ ) Vec_IntPush( vVar2Sat, n ); // iterate through outputs printf( "\nIteration %d (Aux = %d)\n", Iter, iAuxVarStart + Iter ); RetValue = Bmc_FxSolve( pSat, 0, iAuxVarStart + Iter, vVar2Sat, 1, 1, NULL, vCubes ); if ( RetValue == 0 ) printf( "Mismatch\n" ); if ( RetValue == -1 ) printf( "Timeout\n" ); // print cubes //Div_CubePrint( vCubes, nCiVars ); vDivs = Div_CubePairs( vCubes, nCiVars, nDiv2Add ); Vec_WecFree( vCubes ); // add clauses and update variables Bmc_FxAddClauses( pSat, vDivs, iCiVarBeg, iCiVarCur ); iCiVarCur += Vec_IntSize(vDivs)/4; Vec_IntFree( vDivs ); // cleanup assert( Vec_IntSize(vVar2Sat) <= nCiVars + Extra ); Vec_IntFree( vVar2Sat ); } // cleanup sat_solver_delete( pSat ); Cnf_DataFree( pCnf ); return 1; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END