blob: f09a41f8e09b5dbfc4c1dd34c9f4e829513af680 [file]
/**CFile****************************************************************
FileName [aigInter.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [AIG package.]
Synopsis [Interpolate two AIGs.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: aigInter.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig.h"
#include "sat/cnf/cnf.h"
#include "sat/bsat/satStore.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
extern abctime timeCnf;
extern abctime timeSat;
extern abctime timeInt;
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_ManInterFast( Aig_Man_t * pManOn, Aig_Man_t * pManOff, int fVerbose )
{
sat_solver * pSat;
Cnf_Dat_t * pCnfOn, * pCnfOff;
Aig_Obj_t * pObj, * pObj2;
int Lits[3], status, i;
// abctime clk = Abc_Clock();
assert( Aig_ManCiNum(pManOn) == Aig_ManCiNum(pManOff) );
assert( Aig_ManCoNum(pManOn) == Aig_ManCoNum(pManOff) );
// derive CNFs
pManOn->nRegs = Aig_ManCoNum(pManOn);
pCnfOn = Cnf_Derive( pManOn, Aig_ManCoNum(pManOn) );
pManOn->nRegs = 0;
pManOff->nRegs = Aig_ManCoNum(pManOn);
pCnfOff = Cnf_Derive( pManOff, Aig_ManCoNum(pManOff) );
pManOff->nRegs = 0;
// pCnfOn = Cnf_DeriveSimple( pManOn, Aig_ManCoNum(pManOn) );
// pCnfOff = Cnf_DeriveSimple( pManOff, Aig_ManCoNum(pManOn) );
Cnf_DataLift( pCnfOff, pCnfOn->nVars );
// start the solver
pSat = sat_solver_new();
sat_solver_setnvars( pSat, pCnfOn->nVars + pCnfOff->nVars );
// add clauses of A
for ( i = 0; i < pCnfOn->nClauses; i++ )
{
if ( !sat_solver_addclause( pSat, pCnfOn->pClauses[i], pCnfOn->pClauses[i+1] ) )
{
Cnf_DataFree( pCnfOn );
Cnf_DataFree( pCnfOff );
sat_solver_delete( pSat );
return;
}
}
// add clauses of B
for ( i = 0; i < pCnfOff->nClauses; i++ )
{
if ( !sat_solver_addclause( pSat, pCnfOff->pClauses[i], pCnfOff->pClauses[i+1] ) )
{
Cnf_DataFree( pCnfOn );
Cnf_DataFree( pCnfOff );
sat_solver_delete( pSat );
return;
}
}
// add PI clauses
// collect the common variables
Aig_ManForEachCi( pManOn, pObj, i )
{
pObj2 = Aig_ManCi( pManOff, i );
Lits[0] = toLitCond( pCnfOn->pVarNums[pObj->Id], 0 );
Lits[1] = toLitCond( pCnfOff->pVarNums[pObj2->Id], 1 );
if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) )
assert( 0 );
Lits[0] = toLitCond( pCnfOn->pVarNums[pObj->Id], 1 );
Lits[1] = toLitCond( pCnfOff->pVarNums[pObj2->Id], 0 );
if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) )
assert( 0 );
}
status = sat_solver_simplify( pSat );
assert( status != 0 );
// solve incremental SAT problems
Aig_ManForEachCo( pManOn, pObj, i )
{
pObj2 = Aig_ManCo( pManOff, i );
Lits[0] = toLitCond( pCnfOn->pVarNums[pObj->Id], 0 );
Lits[1] = toLitCond( pCnfOff->pVarNums[pObj2->Id], 0 );
status = sat_solver_solve( pSat, Lits, Lits+2, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
if ( status != l_False )
printf( "The incremental SAT problem is not UNSAT.\n" );
}
Cnf_DataFree( pCnfOn );
Cnf_DataFree( pCnfOff );
sat_solver_delete( pSat );
// ABC_PRT( "Fast interpolation time", Abc_Clock() - clk );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Aig_ManInter( Aig_Man_t * pManOn, Aig_Man_t * pManOff, int fRelation, int fVerbose )
{
void * pSatCnf = NULL;
Inta_Man_t * pManInter;
Aig_Man_t * pRes;
sat_solver * pSat;
Cnf_Dat_t * pCnfOn, * pCnfOff;
Vec_Int_t * vVarsAB;
Aig_Obj_t * pObj, * pObj2;
int Lits[3], status, i;
abctime clk;
int iLast = -1; // Suppress "might be used uninitialized"
assert( Aig_ManCiNum(pManOn) == Aig_ManCiNum(pManOff) );
clk = Abc_Clock();
// derive CNFs
// pCnfOn = Cnf_Derive( pManOn, 0 );
// pCnfOff = Cnf_Derive( pManOff, 0 );
pCnfOn = Cnf_DeriveSimple( pManOn, 0 );
pCnfOff = Cnf_DeriveSimple( pManOff, 0 );
Cnf_DataLift( pCnfOff, pCnfOn->nVars );
timeCnf += Abc_Clock() - clk;
clk = Abc_Clock();
// start the solver
pSat = sat_solver_new();
sat_solver_store_alloc( pSat );
sat_solver_setnvars( pSat, pCnfOn->nVars + pCnfOff->nVars );
// add clauses of A
for ( i = 0; i < pCnfOn->nClauses; i++ )
{
if ( !sat_solver_addclause( pSat, pCnfOn->pClauses[i], pCnfOn->pClauses[i+1] ) )
{
Cnf_DataFree( pCnfOn );
Cnf_DataFree( pCnfOff );
sat_solver_delete( pSat );
return NULL;
}
}
sat_solver_store_mark_clauses_a( pSat );
// update the last clause
if ( fRelation )
{
extern int sat_solver_store_change_last( sat_solver * pSat );
iLast = sat_solver_store_change_last( pSat );
}
// add clauses of B
for ( i = 0; i < pCnfOff->nClauses; i++ )
{
if ( !sat_solver_addclause( pSat, pCnfOff->pClauses[i], pCnfOff->pClauses[i+1] ) )
{
Cnf_DataFree( pCnfOn );
Cnf_DataFree( pCnfOff );
sat_solver_delete( pSat );
return NULL;
}
}
// add PI clauses
// collect the common variables
vVarsAB = Vec_IntAlloc( Aig_ManCiNum(pManOn) );
if ( fRelation )
Vec_IntPush( vVarsAB, iLast );
Aig_ManForEachCi( pManOn, pObj, i )
{
Vec_IntPush( vVarsAB, pCnfOn->pVarNums[pObj->Id] );
pObj2 = Aig_ManCi( pManOff, i );
Lits[0] = toLitCond( pCnfOn->pVarNums[pObj->Id], 0 );
Lits[1] = toLitCond( pCnfOff->pVarNums[pObj2->Id], 1 );
if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) )
assert( 0 );
Lits[0] = toLitCond( pCnfOn->pVarNums[pObj->Id], 1 );
Lits[1] = toLitCond( pCnfOff->pVarNums[pObj2->Id], 0 );
if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) )
assert( 0 );
}
Cnf_DataFree( pCnfOn );
Cnf_DataFree( pCnfOff );
sat_solver_store_mark_roots( pSat );
/*
status = sat_solver_simplify(pSat);
if ( status == 0 )
{
Vec_IntFree( vVarsAB );
Cnf_DataFree( pCnfOn );
Cnf_DataFree( pCnfOff );
sat_solver_delete( pSat );
return NULL;
}
*/
// solve the problem
status = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
timeSat += Abc_Clock() - clk;
if ( status == l_False )
{
pSatCnf = sat_solver_store_release( pSat );
// printf( "unsat\n" );
}
else if ( status == l_True )
{
// printf( "sat\n" );
}
else
{
// printf( "undef\n" );
}
sat_solver_delete( pSat );
if ( pSatCnf == NULL )
{
printf( "The SAT problem is not unsat.\n" );
Vec_IntFree( vVarsAB );
return NULL;
}
// create the resulting manager
clk = Abc_Clock();
pManInter = Inta_ManAlloc();
pRes = (Aig_Man_t *)Inta_ManInterpolate( pManInter, (Sto_Man_t *)pSatCnf, 0, vVarsAB, fVerbose );
Inta_ManFree( pManInter );
timeInt += Abc_Clock() - clk;
/*
// test UNSAT core computation
{
Intp_Man_t * pManProof;
Vec_Int_t * vCore;
pManProof = Intp_ManAlloc();
vCore = Intp_ManUnsatCore( pManProof, pSatCnf, 0 );
Intp_ManFree( pManProof );
Vec_IntFree( vCore );
}
*/
Vec_IntFree( vVarsAB );
Sto_ManFree( (Sto_Man_t *)pSatCnf );
// Ioa_WriteAiger( pRes, "inter2.aig", 0, 0 );
return pRes;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END