/**Function************************************************************* Synopsis [Addes clauses to the solver.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static void Gia_ManAddClausesSuper( Ssc_Man_t * p, Gia_Obj_t * pNode, Vec_Int_t * vSuper ) { int i, RetValue, Lit, LitNode, pLits[2]; assert( !Gia_IsComplement(pNode) ); assert( Gia_ObjIsAnd( pNode ) ); // suppose AND-gate is A & B = C // add !A => !C or A + !C // add !B => !C or B + !C LitNode = Ssc_ObjSatLit( p, Gia_Obj2Lit(p->pFraig,pNode) ); Vec_IntForEachEntry( vSuper, Lit, i ) { pLits[0] = Ssc_ObjSatLit( p, Lit ); pLits[1] = Abc_LitNot( LitNode ); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); assert( RetValue ); // update literals Vec_IntWriteEntry( vSuper, i, Abc_LitNot(pLits[0]) ); }
/**Function************************************************************* Synopsis [Addes clauses to the solver.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static void Gia_ManAddClausesMux( Ssc_Man_t * p, Gia_Obj_t * pNode ) { Gia_Obj_t * pNodeI, * pNodeT, * pNodeE; int pLits[4], LitF, LitI, LitT, LitE, RetValue; assert( !Gia_IsComplement( pNode ) ); assert( Gia_ObjIsMuxType( pNode ) ); // get nodes (I = if, T = then, E = else) pNodeI = Gia_ObjRecognizeMux( pNode, &pNodeT, &pNodeE ); // get the Litiable numbers LitF = Ssc_ObjSatLit( p, Gia_Obj2Lit(p->pFraig,pNode) ); LitI = Ssc_ObjSatLit( p, Gia_Obj2Lit(p->pFraig,pNodeI) ); LitT = Ssc_ObjSatLit( p, Gia_Obj2Lit(p->pFraig,pNodeT) ); LitE = Ssc_ObjSatLit( p, Gia_Obj2Lit(p->pFraig,pNodeE) ); // f = ITE(i, t, e) // i' + t' + f // i' + t + f' // i + e' + f // i + e + f' // create four clauses pLits[0] = Abc_LitNotCond(LitI, 1); pLits[1] = Abc_LitNotCond(LitT, 1); pLits[2] = Abc_LitNotCond(LitF, 0); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); assert( RetValue ); pLits[0] = Abc_LitNotCond(LitI, 1); pLits[1] = Abc_LitNotCond(LitT, 0); pLits[2] = Abc_LitNotCond(LitF, 1); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); assert( RetValue ); pLits[0] = Abc_LitNotCond(LitI, 0); pLits[1] = Abc_LitNotCond(LitE, 1); pLits[2] = Abc_LitNotCond(LitF, 0); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); assert( RetValue ); pLits[0] = Abc_LitNotCond(LitI, 0); pLits[1] = Abc_LitNotCond(LitE, 0); pLits[2] = Abc_LitNotCond(LitF, 1); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); assert( RetValue ); // two additional clauses // t' & e' -> f' // t & e -> f // t + e + f' // t' + e' + f if ( LitT == LitE ) { // assert( fCompT == !fCompE ); return; } pLits[0] = Abc_LitNotCond(LitT, 0); pLits[1] = Abc_LitNotCond(LitE, 0); pLits[2] = Abc_LitNotCond(LitF, 1); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); assert( RetValue ); pLits[0] = Abc_LitNotCond(LitT, 1); pLits[1] = Abc_LitNotCond(LitE, 1); pLits[2] = Abc_LitNotCond(LitF, 0); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); assert( RetValue ); }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Ssc_PerformSweeping( Gia_Man_t * pAig, Gia_Man_t * pCare, Ssc_Pars_t * pPars ) { Ssc_Man_t * p; Gia_Man_t * pResult, * pTemp; Gia_Obj_t * pObj, * pRepr; abctime clk, clkTotal = Abc_Clock(); int i, fCompl, nRefined, status; clk = Abc_Clock(); assert( Gia_ManRegNum(pCare) == 0 ); assert( Gia_ManCiNum(pAig) == Gia_ManCiNum(pCare) ); assert( Gia_ManIsNormalized(pAig) ); assert( Gia_ManIsNormalized(pCare) ); // reset random numbers Gia_ManRandom( 1 ); // sweeping manager p = Ssc_ManStart( pAig, pCare, pPars ); if ( p == NULL ) return Gia_ManDup( pAig ); if ( p->pPars->fVerbose ) printf( "Care set produced %d hits out of %d.\n", Ssc_GiaEstimateCare(p->pFraig, 5), 640 ); // perform simulation while ( 1 ) { // simulate care set Ssc_GiaRandomPiPattern( p->pFraig, 5, NULL ); Ssc_GiaSimRound( p->pFraig ); // transfer care patterns to user's AIG if ( !Ssc_GiaTransferPiPattern( pAig, p->pFraig, p->vPivot ) ) break; // simulate the main AIG Ssc_GiaSimRound( pAig ); nRefined = Ssc_GiaClassesRefine( pAig ); if ( pPars->fVerbose ) Gia_ManEquivPrintClasses( pAig, 0, 0 ); if ( nRefined <= Gia_ManCandNum(pAig) / 100 ) break; } p->timeSimInit += Abc_Clock() - clk; // prepare user's AIG Gia_ManFillValue(pAig); Gia_ManConst0(pAig)->Value = 0; Gia_ManForEachCi( pAig, pObj, i ) pObj->Value = Gia_Obj2Lit( p->pFraig, Gia_ManCi(p->pFraig, i) ); // Gia_ManLevelNum(pAig); // prepare swept AIG (should be done after starting SAT solver in Ssc_ManStart) Gia_ManHashStart( p->pFraig ); // perform sweeping Ssc_GiaResetPiPattern( pAig, pPars->nWords ); Ssc_GiaSavePiPattern( pAig, p->vPivot ); Gia_ManForEachCand( pAig, pObj, i ) { if ( pAig->iPatsPi == 64 * pPars->nWords ) { clk = Abc_Clock(); Ssc_GiaSimRound( pAig ); Ssc_GiaClassesRefine( pAig ); if ( pPars->fVerbose ) Gia_ManEquivPrintClasses( pAig, 0, 0 ); Ssc_GiaClassesCheckPairs( pAig, p->vDisPairs ); Vec_IntClear( p->vDisPairs ); // prepare next patterns Ssc_GiaResetPiPattern( pAig, pPars->nWords ); Ssc_GiaSavePiPattern( pAig, p->vPivot ); p->timeSimSat += Abc_Clock() - clk; //printf( "\n" ); } if ( Gia_ObjIsAnd(pObj) ) pObj->Value = Gia_ManHashAnd( p->pFraig, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); if ( !Gia_ObjHasRepr(pAig, i) ) continue; pRepr = Gia_ObjReprObj(pAig, i); if ( (int)pObj->Value == Abc_LitNotCond( pRepr->Value, pRepr->fPhase ^ pObj->fPhase ) ) { Gia_ObjSetProved( pAig, i ); continue; } assert( Abc_Lit2Var(pRepr->Value) != Abc_Lit2Var(pObj->Value) ); fCompl = pRepr->fPhase ^ pObj->fPhase ^ Abc_LitIsCompl(pRepr->Value) ^ Abc_LitIsCompl(pObj->Value); // perform SAT call clk = Abc_Clock(); p->nSatCalls++; status = Ssc_ManCheckEquivalence( p, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl ); if ( status == l_False ) { p->nSatCallsUnsat++; pObj->Value = Abc_LitNotCond( pRepr->Value, pRepr->fPhase ^ pObj->fPhase ); Gia_ObjSetProved( pAig, i ); } else if ( status == l_True ) { p->nSatCallsSat++; Ssc_GiaSavePiPattern( pAig, p->vPattern ); Vec_IntPush( p->vDisPairs, Gia_ObjRepr(p->pAig, i) ); Vec_IntPush( p->vDisPairs, i ); // printf( "Try %2d and %2d: ", Gia_ObjRepr(p->pAig, i), i ); // Vec_IntPrint( p->vPattern ); if ( Gia_ObjRepr(p->pAig, i) > 0 ) Ssc_GiaResimulateOneClass( p, Gia_ObjRepr(p->pAig, i), i ); } else if ( status == l_Undef ) p->nSatCallsUndec++; else assert( 0 ); p->timeSat += Abc_Clock() - clk; } if ( pAig->iPatsPi > 1 ) { clk = Abc_Clock(); while ( pAig->iPatsPi < 64 * pPars->nWords ) Ssc_GiaSavePiPattern( pAig, p->vPivot ); Ssc_GiaSimRound( pAig ); Ssc_GiaClassesRefine( pAig ); if ( pPars->fVerbose ) Gia_ManEquivPrintClasses( pAig, 0, 0 ); Ssc_GiaClassesCheckPairs( pAig, p->vDisPairs ); Vec_IntClear( p->vDisPairs ); p->timeSimSat += Abc_Clock() - clk; } // Gia_ManEquivPrintClasses( pAig, 1, 0 ); // Gia_ManPrint( pAig ); // generate the resulting AIG pResult = Gia_ManEquivReduce( pAig, 0, 0, 1, 0 ); if ( pResult == NULL ) { printf( "There is no equivalences.\n" ); ABC_FREE( pAig->pReprs ); ABC_FREE( pAig->pNexts ); pResult = Gia_ManDup( pAig ); } pResult = Gia_ManCleanup( pTemp = pResult ); Gia_ManStop( pTemp ); p->timeTotal = Abc_Clock() - clkTotal; if ( pPars->fVerbose ) Ssc_ManPrintStats( p ); Ssc_ManStop( p ); // count the number of representatives if ( pPars->fVerbose ) { Abc_Print( 1, "Reduction in AIG nodes:%8d ->%8d (%6.2f %%). ", Gia_ManAndNum(pAig), Gia_ManAndNum(pResult), 100.0 - 100.0 * Gia_ManAndNum(pResult) / Gia_ManAndNum(pAig) ); Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal ); } return pResult; }