blob: 59ed694511336ac9e461b7e70176046afac440e4 [file] [log] [blame]
/**CFile****************************************************************
FileName [sswSat.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Inductive prover with constraints.]
Synopsis [Calls to the SAT solver.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 1, 2008.]
Revision [$Id: sswSat.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
***********************************************************************/
#include "sswInt.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Runs equivalence test for the two nodes.]
Description [Both nodes should be regular and different from each other.]
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_NodesAreEquiv( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew )
{
int nBTLimit = p->pPars->nBTLimit;
int pLits[3], nLits, RetValue, RetValue1;
abctime clk;//, status;
p->nSatCalls++;
p->pMSat->nSolverCalls++;
// sanity checks
assert( !Aig_IsComplement(pOld) );
assert( !Aig_IsComplement(pNew) );
assert( pOld != pNew );
assert( p->pMSat != NULL );
// if the nodes do not have SAT variables, allocate them
Ssw_CnfNodeAddToSolver( p->pMSat, pOld );
Ssw_CnfNodeAddToSolver( p->pMSat, pNew );
// solve under assumptions
// A = 1; B = 0 OR A = 1; B = 1
nLits = 2;
pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,pOld), 0 );
pLits[1] = toLitCond( Ssw_ObjSatNum(p->pMSat,pNew), pOld->fPhase == pNew->fPhase );
if ( p->iOutputLit > -1 )
pLits[nLits++] = p->iOutputLit;
if ( p->pPars->fPolarFlip )
{
if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] );
}
//Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 );
if ( p->pMSat->pSat->qtail != p->pMSat->pSat->qhead )
{
RetValue = sat_solver_simplify(p->pMSat->pSat);
assert( RetValue != 0 );
}
clk = Abc_Clock();
RetValue1 = sat_solver_solve( p->pMSat->pSat, pLits, pLits + nLits,
(ABC_INT64_T)nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
p->timeSat += Abc_Clock() - clk;
if ( RetValue1 == l_False )
{
p->timeSatUnsat += Abc_Clock() - clk;
if ( nLits == 2 )
{
pLits[0] = lit_neg( pLits[0] );
pLits[1] = lit_neg( pLits[1] );
RetValue = sat_solver_addclause( p->pMSat->pSat, pLits, pLits + 2 );
assert( RetValue );
/*
if ( p->pMSat->pSat->qtail != p->pMSat->pSat->qhead )
{
RetValue = sat_solver_simplify(p->pMSat->pSat);
assert( RetValue != 0 );
}
*/
}
p->nSatCallsUnsat++;
}
else if ( RetValue1 == l_True )
{
p->timeSatSat += Abc_Clock() - clk;
p->nSatCallsSat++;
return 0;
}
else // if ( RetValue1 == l_Undef )
{
p->timeSatUndec += Abc_Clock() - clk;
p->nSatFailsReal++;
return -1;
}
// if the old node was constant 0, we already know the answer
if ( pOld == Aig_ManConst1(p->pFrames) )
{
p->nSatProof++;
return 1;
}
// solve under assumptions
// A = 0; B = 1 OR A = 0; B = 0
nLits = 2;
pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,pOld), 1 );
pLits[1] = toLitCond( Ssw_ObjSatNum(p->pMSat,pNew), pOld->fPhase ^ pNew->fPhase );
if ( p->iOutputLit > -1 )
pLits[nLits++] = p->iOutputLit;
if ( p->pPars->fPolarFlip )
{
if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] );
}
if ( p->pMSat->pSat->qtail != p->pMSat->pSat->qhead )
{
RetValue = sat_solver_simplify(p->pMSat->pSat);
assert( RetValue != 0 );
}
clk = Abc_Clock();
RetValue1 = sat_solver_solve( p->pMSat->pSat, pLits, pLits + nLits,
(ABC_INT64_T)nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
p->timeSat += Abc_Clock() - clk;
if ( RetValue1 == l_False )
{
p->timeSatUnsat += Abc_Clock() - clk;
if ( nLits == 2 )
{
pLits[0] = lit_neg( pLits[0] );
pLits[1] = lit_neg( pLits[1] );
RetValue = sat_solver_addclause( p->pMSat->pSat, pLits, pLits + 2 );
assert( RetValue );
/*
if ( p->pMSat->pSat->qtail != p->pMSat->pSat->qhead )
{
RetValue = sat_solver_simplify(p->pMSat->pSat);
assert( RetValue != 0 );
}
*/
}
p->nSatCallsUnsat++;
}
else if ( RetValue1 == l_True )
{
p->timeSatSat += Abc_Clock() - clk;
p->nSatCallsSat++;
return 0;
}
else // if ( RetValue1 == l_Undef )
{
p->timeSatUndec += Abc_Clock() - clk;
p->nSatFailsReal++;
return -1;
}
// return SAT proof
p->nSatProof++;
return 1;
}
/**Function*************************************************************
Synopsis [Constrains two nodes to be equivalent in the SAT solver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew )
{
int pLits[2], RetValue, fComplNew;
Aig_Obj_t * pTemp;
// sanity checks
assert( Aig_Regular(pOld) != Aig_Regular(pNew) );
assert( p->pPars->fConstrs || Aig_ObjPhaseReal(pOld) == Aig_ObjPhaseReal(pNew) );
// move constant to the old node
if ( Aig_Regular(pNew) == Aig_ManConst1(p->pFrames) )
{
assert( Aig_Regular(pOld) != Aig_ManConst1(p->pFrames) );
pTemp = pOld;
pOld = pNew;
pNew = pTemp;
}
// move complement to the new node
if ( Aig_IsComplement(pOld) )
{
pOld = Aig_Regular(pOld);
pNew = Aig_Not(pNew);
}
assert( p->pMSat != NULL );
// if the nodes do not have SAT variables, allocate them
Ssw_CnfNodeAddToSolver( p->pMSat, pOld );
Ssw_CnfNodeAddToSolver( p->pMSat, Aig_Regular(pNew) );
// transform the new node
fComplNew = Aig_IsComplement( pNew );
pNew = Aig_Regular( pNew );
// consider the constant 1 case
if ( pOld == Aig_ManConst1(p->pFrames) )
{
// add constraint A = 1 ----> A
pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,pNew), fComplNew );
if ( p->pPars->fPolarFlip )
{
if ( pNew->fPhase ) pLits[0] = lit_neg( pLits[0] );
}
RetValue = sat_solver_addclause( p->pMSat->pSat, pLits, pLits + 1 );
assert( RetValue );
}
else
{
// add constraint A = B ----> (A v !B)(!A v B)
// (A v !B)
pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,pOld), 0 );
pLits[1] = toLitCond( Ssw_ObjSatNum(p->pMSat,pNew), !fComplNew );
if ( p->pPars->fPolarFlip )
{
if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] );
}
pLits[0] = lit_neg( pLits[0] );
pLits[1] = lit_neg( pLits[1] );
RetValue = sat_solver_addclause( p->pMSat->pSat, pLits, pLits + 2 );
assert( RetValue );
// (!A v B)
pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,pOld), 1 );
pLits[1] = toLitCond( Ssw_ObjSatNum(p->pMSat,pNew), fComplNew);
if ( p->pPars->fPolarFlip )
{
if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] );
}
pLits[0] = lit_neg( pLits[0] );
pLits[1] = lit_neg( pLits[1] );
RetValue = sat_solver_addclause( p->pMSat->pSat, pLits, pLits + 2 );
assert( RetValue );
}
return 1;
}
/**Function*************************************************************
Synopsis [Constrains one node in the SAT solver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_NodeIsConstrained( Ssw_Man_t * p, Aig_Obj_t * pPoObj )
{
int RetValue, Lit;
Ssw_CnfNodeAddToSolver( p->pMSat, Aig_ObjFanin0(pPoObj) );
// add constraint A = 1 ----> A
Lit = toLitCond( Ssw_ObjSatNum(p->pMSat,Aig_ObjFanin0(pPoObj)), !Aig_ObjFaninC0(pPoObj) );
if ( p->pPars->fPolarFlip )
{
if ( Aig_ObjFanin0(pPoObj)->fPhase ) Lit = lit_neg( Lit );
}
RetValue = sat_solver_addclause( p->pMSat->pSat, &Lit, &Lit + 1 );
assert( RetValue );
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END