blob: f10006b7e6a6c9731a653ac1e6924134097b4bfb [file] [log] [blame]
/**CFile****************************************************************
FileName [intContain.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Interpolation engine.]
Synopsis [Interpolant containment checking.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 24, 2008.]
Revision [$Id: intContain.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "intInt.h"
#include "proof/fra/fra.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
extern int Inter_ManCheckUniqueness( Aig_Man_t * p, sat_solver * pSat, Cnf_Dat_t * pCnf, int nFrames );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Checks constainment of two interpolants.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Inter_ManCheckContainment( Aig_Man_t * pNew, Aig_Man_t * pOld )
{
Aig_Man_t * pMiter, * pAigTemp;
int RetValue;
pMiter = Aig_ManCreateMiter( pNew, pOld, 1 );
// pMiter = Dar_ManRwsat( pAigTemp = pMiter, 1, 0 );
// Aig_ManStop( pAigTemp );
RetValue = Fra_FraigMiterStatus( pMiter );
if ( RetValue == -1 )
{
pAigTemp = Fra_FraigEquivence( pMiter, 1000000, 1 );
RetValue = Fra_FraigMiterStatus( pAigTemp );
Aig_ManStop( pAigTemp );
// RetValue = Fra_FraigSat( pMiter, 1000000, 0, 0, 0, 0, 0, 0 );
}
assert( RetValue != -1 );
Aig_ManStop( pMiter );
return RetValue;
}
/**Function*************************************************************
Synopsis [Checks constainment of two interpolants.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Inter_ManCheckEquivalence( Aig_Man_t * pNew, Aig_Man_t * pOld )
{
Aig_Man_t * pMiter, * pAigTemp;
int RetValue;
pMiter = Aig_ManCreateMiter( pNew, pOld, 0 );
// pMiter = Dar_ManRwsat( pAigTemp = pMiter, 1, 0 );
// Aig_ManStop( pAigTemp );
RetValue = Fra_FraigMiterStatus( pMiter );
if ( RetValue == -1 )
{
pAigTemp = Fra_FraigEquivence( pMiter, 1000000, 1 );
RetValue = Fra_FraigMiterStatus( pAigTemp );
Aig_ManStop( pAigTemp );
// RetValue = Fra_FraigSat( pMiter, 1000000, 0, 0, 0, 0, 0, 0 );
}
assert( RetValue != -1 );
Aig_ManStop( pMiter );
return RetValue;
}
/**Function*************************************************************
Synopsis [Create timeframes of the manager for interpolation.]
Description [The resulting manager is combinational. The primary inputs
corresponding to register outputs are ordered first.]
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Inter_ManFramesLatches( Aig_Man_t * pAig, int nFrames, Vec_Ptr_t ** pvMapReg )
{
Aig_Man_t * pFrames;
Aig_Obj_t * pObj, * pObjLi, * pObjLo;
int i, f;
assert( Saig_ManRegNum(pAig) > 0 );
pFrames = Aig_ManStart( Aig_ManNodeNum(pAig) * nFrames );
// map the constant node
Aig_ManConst1(pAig)->pData = Aig_ManConst1( pFrames );
// create variables for register outputs
*pvMapReg = Vec_PtrAlloc( (nFrames+1) * Saig_ManRegNum(pAig) );
Saig_ManForEachLo( pAig, pObj, i )
{
pObj->pData = Aig_ObjCreateCi( pFrames );
Vec_PtrPush( *pvMapReg, pObj->pData );
}
// add timeframes
for ( f = 0; f < nFrames; f++ )
{
// create PI nodes for this frame
Saig_ManForEachPi( pAig, pObj, i )
pObj->pData = Aig_ObjCreateCi( pFrames );
// add internal nodes of this frame
Aig_ManForEachNode( pAig, pObj, i )
pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
// save register inputs
Saig_ManForEachLi( pAig, pObj, i )
pObj->pData = Aig_ObjChild0Copy(pObj);
// transfer to register outputs
Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i )
{
pObjLo->pData = pObjLi->pData;
Vec_PtrPush( *pvMapReg, pObjLo->pData );
}
}
return pFrames;
}
/**Function*************************************************************
Synopsis [Duplicates AIG while mapping PIs into the given array.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Inter_ManAppendCone( Aig_Man_t * pOld, Aig_Man_t * pNew, Aig_Obj_t ** ppNewPis, int fCompl )
{
Aig_Obj_t * pObj;
int i;
assert( Aig_ManCoNum(pOld) == 1 );
// create the PIs
Aig_ManCleanData( pOld );
Aig_ManConst1(pOld)->pData = Aig_ManConst1(pNew);
Aig_ManForEachCi( pOld, pObj, i )
pObj->pData = ppNewPis[i];
// duplicate internal nodes
Aig_ManForEachNode( pOld, pObj, i )
pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
// add one PO to new
pObj = Aig_ManCo( pOld, 0 );
Aig_ObjCreateCo( pNew, Aig_NotCond( Aig_ObjChild0Copy(pObj), fCompl ) );
}
/**Function*************************************************************
Synopsis [Checks constainment of two interpolants inductively.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Inter_ManCheckInductiveContainment( Aig_Man_t * pTrans, Aig_Man_t * pInter, int nSteps, int fBackward )
{
Aig_Man_t * pFrames;
Aig_Obj_t ** ppNodes;
Vec_Ptr_t * vMapRegs;
Cnf_Dat_t * pCnf;
sat_solver * pSat;
int f, nRegs, status;
nRegs = Saig_ManRegNum(pTrans);
assert( nRegs > 0 );
// generate the timeframes
pFrames = Inter_ManFramesLatches( pTrans, nSteps, &vMapRegs );
assert( Vec_PtrSize(vMapRegs) == (nSteps + 1) * nRegs );
// add main constraints to the timeframes
ppNodes = (Aig_Obj_t **)Vec_PtrArray(vMapRegs);
if ( !fBackward )
{
// forward inductive check: p -> p -> ... -> !p
for ( f = 0; f < nSteps; f++ )
Inter_ManAppendCone( pInter, pFrames, ppNodes + f * nRegs, 0 );
Inter_ManAppendCone( pInter, pFrames, ppNodes + f * nRegs, 1 );
}
else
{
// backward inductive check: p -> !p -> ... -> !p
Inter_ManAppendCone( pInter, pFrames, ppNodes + 0 * nRegs, 1 );
for ( f = 1; f <= nSteps; f++ )
Inter_ManAppendCone( pInter, pFrames, ppNodes + f * nRegs, 0 );
}
Vec_PtrFree( vMapRegs );
Aig_ManCleanup( pFrames );
// convert to CNF
pCnf = Cnf_Derive( pFrames, 0 );
pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
// Cnf_DataFree( pCnf );
// Aig_ManStop( pFrames );
if ( pSat == NULL )
{
Cnf_DataFree( pCnf );
Aig_ManStop( pFrames );
return 1;
}
// 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 );
// Inter_ManCheckUniqueness( pTrans, pSat, pCnf, nSteps );
Cnf_DataFree( pCnf );
Aig_ManStop( pFrames );
sat_solver_delete( pSat );
return status == l_False;
}
ABC_NAMESPACE_IMPL_END
#include "proof/fra/fra.h"
ABC_NAMESPACE_IMPL_START
/**Function*************************************************************
Synopsis [Check if cex satisfies uniqueness constraints.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Inter_ManCheckUniqueness( Aig_Man_t * p, sat_solver * pSat, Cnf_Dat_t * pCnf, int nFrames )
{
extern int Fra_SmlNodesCompareInFrame( Fra_Sml_t * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1, int iFrame0, int iFrame1 );
extern void Fra_SmlAssignConst( Fra_Sml_t * p, Aig_Obj_t * pObj, int fConst1, int iFrame );
extern void Fra_SmlSimulateOne( Fra_Sml_t * p );
Fra_Sml_t * pSml;
Vec_Int_t * vPis;
Aig_Obj_t * pObj, * pObj0;
int i, k, v, iBit, * pCounterEx;
int Counter;
if ( nFrames == 1 )
return 1;
// if ( pSat->model.size == 0 )
// possible consequences here!!!
assert( 0 );
if ( sat_solver_nvars(pSat) == 0 )
return 1;
// assert( Saig_ManPoNum(p) == 1 );
assert( Aig_ManRegNum(p) > 0 );
assert( Aig_ManRegNum(p) < Aig_ManCiNum(p) );
// get the counter-example
vPis = Vec_IntAlloc( 100 );
Aig_ManForEachCi( pCnf->pMan, pObj, k )
Vec_IntPush( vPis, pCnf->pVarNums[Aig_ObjId(pObj)] );
assert( Vec_IntSize(vPis) == Aig_ManRegNum(p) + nFrames * Saig_ManPiNum(p) );
pCounterEx = Sat_SolverGetModel( pSat, vPis->pArray, vPis->nSize );
Vec_IntFree( vPis );
// start a new sequential simulator
pSml = Fra_SmlStart( p, 0, nFrames, 1 );
// assign simulation info for the registers
iBit = 0;
Aig_ManForEachLoSeq( p, pObj, i )
Fra_SmlAssignConst( pSml, pObj, pCounterEx[iBit++], 0 );
// assign simulation info for the primary inputs
for ( i = 0; i < nFrames; i++ )
Aig_ManForEachPiSeq( p, pObj, k )
Fra_SmlAssignConst( pSml, pObj, pCounterEx[iBit++], i );
assert( iBit == Aig_ManCiNum(pCnf->pMan) );
// run simulation
Fra_SmlSimulateOne( pSml );
// check if the given output has failed
// RetValue = !Fra_SmlNodeIsZero( pSml, Aig_ManCo(pAig, 0) );
// assert( RetValue );
// check values at the internal nodes
Counter = 0;
for ( i = 0; i < nFrames; i++ )
for ( k = i+1; k < nFrames; k++ )
{
for ( v = 0; v < Aig_ManRegNum(p); v++ )
{
pObj0 = Aig_ManLo(p, v);
if ( !Fra_SmlNodesCompareInFrame( pSml, pObj0, pObj0, i, k ) )
break;
}
if ( v == Aig_ManRegNum(p) )
Counter++;
}
printf( "Uniquness does not hold in %d frames.\n", Counter );
Fra_SmlStop( pSml );
ABC_FREE( pCounterEx );
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END