| /**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 |
| |