| /**CFile**************************************************************** |
| |
| FileName [bbrCex.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [BDD-based reachability analysis.] |
| |
| Synopsis [Procedures to derive a satisfiable counter-example.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - June 20, 2005.] |
| |
| Revision [$Id: bbrCex.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "bbr.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| extern DdNode * Bbr_bddComputeRangeCube( DdManager * dd, int iStart, int iStop ); |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Derives the counter-example using the set of reached states.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Abc_Cex_t * Aig_ManVerifyUsingBddsCountExample( Aig_Man_t * p, DdManager * dd, |
| DdNode ** pbParts, Vec_Ptr_t * vOnionRings, DdNode * bCubeFirst, |
| int iOutput, int fVerbose, int fSilent ) |
| { |
| Abc_Cex_t * pCex; |
| Aig_Obj_t * pObj; |
| Bbr_ImageTree_t * pTree; |
| DdNode * bCubeNs, * bState, * bImage; |
| DdNode * bTemp, * bVar, * bRing; |
| int i, v, RetValue, nPiOffset; |
| char * pValues; |
| abctime clk = Abc_Clock(); |
| //printf( "\nDeriving counter-example.\n" ); |
| |
| // allocate room for the counter-example |
| pCex = Abc_CexAlloc( Saig_ManRegNum(p), Saig_ManPiNum(p), Vec_PtrSize(vOnionRings)+1 ); |
| pCex->iFrame = Vec_PtrSize(vOnionRings); |
| pCex->iPo = iOutput; |
| nPiOffset = Saig_ManRegNum(p) + Saig_ManPiNum(p) * Vec_PtrSize(vOnionRings); |
| |
| // create the cube of NS variables |
| bCubeNs = Bbr_bddComputeRangeCube( dd, Saig_ManCiNum(p), Saig_ManCiNum(p)+Saig_ManRegNum(p) ); Cudd_Ref( bCubeNs ); |
| pTree = Bbr_bddImageStart( dd, bCubeNs, Saig_ManRegNum(p), pbParts, Saig_ManCiNum(p), dd->vars, 100000000, fVerbose ); |
| Cudd_RecursiveDeref( dd, bCubeNs ); |
| if ( pTree == NULL ) |
| { |
| if ( !fSilent ) |
| printf( "BDDs blew up during qualitification scheduling. " ); |
| return NULL; |
| } |
| |
| // allocate room for the cube |
| pValues = ABC_ALLOC( char, dd->size ); |
| |
| // get the last cube |
| RetValue = Cudd_bddPickOneCube( dd, bCubeFirst, pValues ); |
| assert( RetValue ); |
| |
| // write PIs of counter-example |
| Saig_ManForEachPi( p, pObj, i ) |
| if ( pValues[i] == 1 ) |
| Abc_InfoSetBit( pCex->pData, nPiOffset + i ); |
| nPiOffset -= Saig_ManPiNum(p); |
| |
| // write state in terms of NS variables |
| bState = (dd)->one; Cudd_Ref( bState ); |
| Saig_ManForEachLo( p, pObj, i ) |
| { |
| bVar = Cudd_NotCond( dd->vars[Saig_ManCiNum(p)+i], pValues[Saig_ManPiNum(p)+i] != 1 ); |
| bState = Cudd_bddAnd( dd, bTemp = bState, bVar ); Cudd_Ref( bState ); |
| Cudd_RecursiveDeref( dd, bTemp ); |
| } |
| |
| // perform backward analysis |
| Vec_PtrForEachEntryReverse( DdNode *, vOnionRings, bRing, v ) |
| { |
| // compute the next states |
| bImage = Bbr_bddImageCompute( pTree, bState ); |
| if ( bImage == NULL ) |
| { |
| Cudd_RecursiveDeref( dd, bState ); |
| if ( !fSilent ) |
| printf( "BDDs blew up during image computation. " ); |
| Bbr_bddImageTreeDelete( pTree ); |
| ABC_FREE( pValues ); |
| return NULL; |
| } |
| Cudd_Ref( bImage ); |
| Cudd_RecursiveDeref( dd, bState ); |
| |
| // intersect with the previous set |
| bImage = Cudd_bddAnd( dd, bTemp = bImage, bRing ); Cudd_Ref( bImage ); |
| Cudd_RecursiveDeref( dd, bTemp ); |
| |
| // find any assignment of the BDD |
| RetValue = Cudd_bddPickOneCube( dd, bImage, pValues ); |
| assert( RetValue ); |
| Cudd_RecursiveDeref( dd, bImage ); |
| |
| // write PIs of counter-example |
| Saig_ManForEachPi( p, pObj, i ) |
| if ( pValues[i] == 1 ) |
| Abc_InfoSetBit( pCex->pData, nPiOffset + i ); |
| nPiOffset -= Saig_ManPiNum(p); |
| |
| // check that we get the init state |
| if ( v == 0 ) |
| { |
| Saig_ManForEachLo( p, pObj, i ) |
| assert( pValues[Saig_ManPiNum(p)+i] == 0 ); |
| break; |
| } |
| |
| // write state in terms of NS variables |
| bState = (dd)->one; Cudd_Ref( bState ); |
| Saig_ManForEachLo( p, pObj, i ) |
| { |
| bVar = Cudd_NotCond( dd->vars[Saig_ManCiNum(p)+i], pValues[Saig_ManPiNum(p)+i] != 1 ); |
| bState = Cudd_bddAnd( dd, bTemp = bState, bVar ); Cudd_Ref( bState ); |
| Cudd_RecursiveDeref( dd, bTemp ); |
| } |
| } |
| // cleanup |
| Bbr_bddImageTreeDelete( pTree ); |
| ABC_FREE( pValues ); |
| // verify the counter example |
| if ( Vec_PtrSize(vOnionRings) < 1000 ) |
| { |
| RetValue = Saig_ManVerifyCex( p, pCex ); |
| if ( RetValue == 0 && !fSilent ) |
| printf( "Aig_ManVerifyUsingBdds(): Counter-example verification has FAILED.\n" ); |
| } |
| if ( fVerbose && !fSilent ) |
| { |
| ABC_PRT( "Counter-example generation time", Abc_Clock() - clk ); |
| } |
| return pCex; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |