/**CFile**************************************************************** FileName [intM114.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Interpolation engine.] Synopsis [Intepolation using ABC's proof generator added to MiniSat-1.14c.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 24, 2008.] Revision [$Id: intM114.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ #include "intInt.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Returns the SAT solver for one interpolation run.] Description [pInter is the previous interpolant. pAig is one time frame. pFrames is the unrolled time frames.] SideEffects [] SeeAlso [] ***********************************************************************/ sat_solver * Inter_ManDeriveSatSolver( Aig_Man_t * pInter, Cnf_Dat_t * pCnfInter, Aig_Man_t * pAig, Cnf_Dat_t * pCnfAig, Aig_Man_t * pFrames, Cnf_Dat_t * pCnfFrames, Vec_Int_t * vVarsAB, int fUseBackward ) { sat_solver * pSat; Aig_Obj_t * pObj, * pObj2; int i, Lits[2]; //Aig_ManDumpBlif( pInter, "out_inter.blif", NULL, NULL ); //Aig_ManDumpBlif( pAig, "out_aig.blif", NULL, NULL ); //Aig_ManDumpBlif( pFrames, "out_frames.blif", NULL, NULL ); // sanity checks assert( Aig_ManRegNum(pInter) == 0 ); assert( Aig_ManRegNum(pAig) > 0 ); assert( Aig_ManRegNum(pFrames) == 0 ); assert( Aig_ManCoNum(pInter) == 1 ); assert( Aig_ManCoNum(pFrames) == fUseBackward? Saig_ManRegNum(pAig) : 1 ); assert( fUseBackward || Aig_ManCiNum(pInter) == Aig_ManRegNum(pAig) ); // assert( (Aig_ManCiNum(pFrames) - Aig_ManRegNum(pAig)) % Saig_ManPiNum(pAig) == 0 ); // prepare CNFs Cnf_DataLift( pCnfAig, pCnfFrames->nVars ); Cnf_DataLift( pCnfInter, pCnfFrames->nVars + pCnfAig->nVars ); // start the solver pSat = sat_solver_new(); sat_solver_store_alloc( pSat ); sat_solver_setnvars( pSat, pCnfInter->nVars + pCnfAig->nVars + pCnfFrames->nVars ); // add clauses of A // interpolant for ( i = 0; i < pCnfInter->nClauses; i++ ) { if ( !sat_solver_addclause( pSat, pCnfInter->pClauses[i], pCnfInter->pClauses[i+1] ) ) { sat_solver_delete( pSat ); // return clauses to the original state Cnf_DataLift( pCnfAig, -pCnfFrames->nVars ); Cnf_DataLift( pCnfInter, -pCnfFrames->nVars -pCnfAig->nVars ); return NULL; } } // connector clauses if ( fUseBackward ) { Saig_ManForEachLi( pAig, pObj2, i ) { if ( Saig_ManRegNum(pAig) == Aig_ManCiNum(pInter) ) pObj = Aig_ManCi( pInter, i ); else { assert( Aig_ManCiNum(pAig) == Aig_ManCiNum(pInter) ); pObj = Aig_ManCi( pInter, Aig_ManCiNum(pAig)-Saig_ManRegNum(pAig) + i ); } Lits[0] = toLitCond( pCnfInter->pVarNums[pObj->Id], 0 ); Lits[1] = toLitCond( pCnfAig->pVarNums[pObj2->Id], 1 ); if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) assert( 0 ); Lits[0] = toLitCond( pCnfInter->pVarNums[pObj->Id], 1 ); Lits[1] = toLitCond( pCnfAig->pVarNums[pObj2->Id], 0 ); if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) assert( 0 ); } } else { Aig_ManForEachCi( pInter, pObj, i ) { pObj2 = Saig_ManLo( pAig, i ); Lits[0] = toLitCond( pCnfInter->pVarNums[pObj->Id], 0 ); Lits[1] = toLitCond( pCnfAig->pVarNums[pObj2->Id], 1 ); if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) assert( 0 ); Lits[0] = toLitCond( pCnfInter->pVarNums[pObj->Id], 1 ); Lits[1] = toLitCond( pCnfAig->pVarNums[pObj2->Id], 0 ); if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) assert( 0 ); } } // one timeframe for ( i = 0; i < pCnfAig->nClauses; i++ ) { if ( !sat_solver_addclause( pSat, pCnfAig->pClauses[i], pCnfAig->pClauses[i+1] ) ) assert( 0 ); } // connector clauses Vec_IntClear( vVarsAB ); if ( fUseBackward ) { Aig_ManForEachCo( pFrames, pObj, i ) { assert( pCnfFrames->pVarNums[pObj->Id] >= 0 ); Vec_IntPush( vVarsAB, pCnfFrames->pVarNums[pObj->Id] ); pObj2 = Saig_ManLo( pAig, i ); Lits[0] = toLitCond( pCnfFrames->pVarNums[pObj->Id], 0 ); Lits[1] = toLitCond( pCnfAig->pVarNums[pObj2->Id], 1 ); if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) assert( 0 ); Lits[0] = toLitCond( pCnfFrames->pVarNums[pObj->Id], 1 ); Lits[1] = toLitCond( pCnfAig->pVarNums[pObj2->Id], 0 ); if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) assert( 0 ); } } else { Aig_ManForEachCi( pFrames, pObj, i ) { if ( i == Aig_ManRegNum(pAig) ) break; Vec_IntPush( vVarsAB, pCnfFrames->pVarNums[pObj->Id] ); pObj2 = Saig_ManLi( pAig, i ); Lits[0] = toLitCond( pCnfFrames->pVarNums[pObj->Id], 0 ); Lits[1] = toLitCond( pCnfAig->pVarNums[pObj2->Id], 1 ); if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) assert( 0 ); Lits[0] = toLitCond( pCnfFrames->pVarNums[pObj->Id], 1 ); Lits[1] = toLitCond( pCnfAig->pVarNums[pObj2->Id], 0 ); if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) assert( 0 ); } } // add clauses of B sat_solver_store_mark_clauses_a( pSat ); for ( i = 0; i < pCnfFrames->nClauses; i++ ) { if ( !sat_solver_addclause( pSat, pCnfFrames->pClauses[i], pCnfFrames->pClauses[i+1] ) ) { pSat->fSolved = 1; break; } } sat_solver_store_mark_roots( pSat ); // return clauses to the original state Cnf_DataLift( pCnfAig, -pCnfFrames->nVars ); Cnf_DataLift( pCnfInter, -pCnfFrames->nVars -pCnfAig->nVars ); return pSat; } /**Function************************************************************* Synopsis [Performs one SAT run with interpolation.] Description [Returns 1 if proven. 0 if failed. -1 if undecided.] SideEffects [] SeeAlso [] ***********************************************************************/ int Inter_ManPerformOneStep( Inter_Man_t * p, int fUseBias, int fUseBackward, abctime nTimeNewOut ) { sat_solver * pSat; void * pSatCnf = NULL; Inta_Man_t * pManInterA; // Intb_Man_t * pManInterB; int * pGlobalVars; int status, RetValue; int i, Var; abctime clk; // assert( p->pInterNew == NULL ); // derive the SAT solver pSat = Inter_ManDeriveSatSolver( p->pInter, p->pCnfInter, p->pAigTrans, p->pCnfAig, p->pFrames, p->pCnfFrames, p->vVarsAB, fUseBackward ); if ( pSat == NULL ) { p->pInterNew = NULL; return 1; } // set runtime limit if ( nTimeNewOut ) sat_solver_set_runtime_limit( pSat, nTimeNewOut ); // collect global variables pGlobalVars = ABC_CALLOC( int, sat_solver_nvars(pSat) ); Vec_IntForEachEntry( p->vVarsAB, Var, i ) pGlobalVars[Var] = 1; pSat->pGlobalVars = fUseBias? pGlobalVars : NULL; // solve the problem clk = Abc_Clock(); status = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)p->nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); p->nConfCur = pSat->stats.conflicts; p->timeSat += Abc_Clock() - clk; pSat->pGlobalVars = NULL; ABC_FREE( pGlobalVars ); if ( status == l_False ) { pSatCnf = sat_solver_store_release( pSat ); RetValue = 1; } else if ( status == l_True ) { RetValue = 0; } else { RetValue = -1; } sat_solver_delete( pSat ); if ( pSatCnf == NULL ) return RetValue; // create the resulting manager clk = Abc_Clock(); /* if ( !fUseIp ) { pManInterA = Inta_ManAlloc(); p->pInterNew = Inta_ManInterpolate( pManInterA, pSatCnf, p->vVarsAB, 0 ); Inta_ManFree( pManInterA ); } else { Aig_Man_t * pInterNew2; int RetValue; pManInterA = Inta_ManAlloc(); p->pInterNew = Inta_ManInterpolate( pManInterA, pSatCnf, p->vVarsAB, 0 ); // Inter_ManVerifyInterpolant1( pManInterA, pSatCnf, p->pInterNew ); Inta_ManFree( pManInterA ); pManInterB = Intb_ManAlloc(); pInterNew2 = Intb_ManInterpolate( pManInterB, pSatCnf, p->vVarsAB, 0 ); Inter_ManVerifyInterpolant2( pManInterB, pSatCnf, pInterNew2 ); Intb_ManFree( pManInterB ); // check relationship RetValue = Inter_ManCheckEquivalence( pInterNew2, p->pInterNew ); if ( RetValue ) printf( "Equivalence \"Ip == Im\" holds\n" ); else { // printf( "Equivalence \"Ip == Im\" does not hold\n" ); RetValue = Inter_ManCheckContainment( pInterNew2, p->pInterNew ); if ( RetValue ) printf( "Containment \"Ip -> Im\" holds\n" ); else printf( "Containment \"Ip -> Im\" does not hold\n" ); RetValue = Inter_ManCheckContainment( p->pInterNew, pInterNew2 ); if ( RetValue ) printf( "Containment \"Im -> Ip\" holds\n" ); else printf( "Containment \"Im -> Ip\" does not hold\n" ); } Aig_ManStop( pInterNew2 ); } */ pManInterA = Inta_ManAlloc(); p->pInterNew = (Aig_Man_t *)Inta_ManInterpolate( pManInterA, (Sto_Man_t *)pSatCnf, nTimeNewOut, p->vVarsAB, 0 ); Inta_ManFree( pManInterA ); p->timeInt += Abc_Clock() - clk; Sto_ManFree( (Sto_Man_t *)pSatCnf ); if ( p->pInterNew == NULL ) RetValue = -1; return RetValue; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END