| /**CFile**************************************************************** |
| |
| FileName [llb1Constr.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [BDD based reachability.] |
| |
| Synopsis [Computing inductive constraints.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - June 20, 2005.] |
| |
| Revision [$Id: llb1Constr.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "llbInt.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Returns the array of constraint candidates.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Llb_ManCountEntries( Vec_Int_t * vCands ) |
| { |
| int i, Entry, Counter = 0; |
| Vec_IntForEachEntry( vCands, Entry, i ) |
| Counter += ((Entry == 0) || (Entry == 1)); |
| return Counter; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Returns the array of constraint candidates.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Llb_ManPrintEntries( Aig_Man_t * p, Vec_Int_t * vCands ) |
| { |
| int i, Entry; |
| if ( vCands == NULL ) |
| { |
| printf( "There is no hints.\n" ); |
| return; |
| } |
| Entry = Llb_ManCountEntries(vCands); |
| printf( "\n*** Using %d hint%s:\n", Entry, (Entry != 1 ? "s":"") ); |
| Vec_IntForEachEntry( vCands, Entry, i ) |
| { |
| if ( Entry != 0 && Entry != 1 ) |
| continue; |
| printf( "%c", Entry ? '+' : '-' ); |
| printf( "%-6d : ", i ); |
| Aig_ObjPrint( p, Aig_ManObj(p, i) ); |
| printf( "\n" ); |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Dereference BDD nodes.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Llb_ManDerefenceBdds( Aig_Man_t * p, DdManager * dd ) |
| { |
| Aig_Obj_t * pObj; |
| int i; |
| Aig_ManForEachObj( p, pObj, i ) |
| Cudd_RecursiveDeref( dd, (DdNode *)pObj->pData ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Returns the array of constraint candidates.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| DdNode * Llb_ManComputeIndCase_rec( Aig_Man_t * p, Aig_Obj_t * pObj, DdManager * dd, Vec_Ptr_t * vBdds ) |
| { |
| DdNode * bBdd0, * bBdd1; |
| DdNode * bFunc = (DdNode *)Vec_PtrEntry( vBdds, Aig_ObjId(pObj) ); |
| if ( bFunc != NULL ) |
| return bFunc; |
| assert( Aig_ObjIsNode(pObj) ); |
| bBdd0 = Llb_ManComputeIndCase_rec( p, Aig_ObjFanin0(pObj), dd, vBdds ); |
| bBdd1 = Llb_ManComputeIndCase_rec( p, Aig_ObjFanin1(pObj), dd, vBdds ); |
| bBdd0 = Cudd_NotCond( bBdd0, Aig_ObjFaninC0(pObj) ); |
| bBdd1 = Cudd_NotCond( bBdd1, Aig_ObjFaninC1(pObj) ); |
| bFunc = Cudd_bddAnd( dd, bBdd0, bBdd1 ); Cudd_Ref( bFunc ); |
| Vec_PtrWriteEntry( vBdds, Aig_ObjId(pObj), bFunc ); |
| return bFunc; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Returns the array of constraint candidates.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Llb_ManComputeIndCase( Aig_Man_t * p, DdManager * dd, Vec_Int_t * vNodes ) |
| { |
| Vec_Ptr_t * vBdds; |
| Aig_Obj_t * pObj; |
| DdNode * bFunc; |
| int i, Entry; |
| vBdds = Vec_PtrStart( Aig_ManObjNumMax(p) ); |
| bFunc = Cudd_ReadOne(dd); Cudd_Ref( bFunc ); |
| Vec_PtrWriteEntry( vBdds, Aig_ObjId(Aig_ManConst1(p)), bFunc ); |
| Saig_ManForEachPi( p, pObj, i ) |
| { |
| bFunc = Cudd_bddIthVar( dd, Aig_ManCiNum(p) + i ); Cudd_Ref( bFunc ); |
| Vec_PtrWriteEntry( vBdds, Aig_ObjId(pObj), bFunc ); |
| } |
| Saig_ManForEachLi( p, pObj, i ) |
| { |
| bFunc = (DdNode *)pObj->pData; Cudd_Ref( bFunc ); |
| Vec_PtrWriteEntry( vBdds, Aig_ObjId(Saig_ObjLiToLo(p, pObj)), bFunc ); |
| } |
| Vec_IntForEachEntry( vNodes, Entry, i ) |
| { |
| if ( Entry != 0 && Entry != 1 ) |
| continue; |
| pObj = Aig_ManObj( p, i ); |
| bFunc = Llb_ManComputeIndCase_rec( p, pObj, dd, vBdds ); |
| if ( Entry == 0 ) |
| { |
| // Extra_bddPrint( dd, Cudd_Not(pObj->pData) ); printf( "\n" ); |
| // Extra_bddPrint( dd, Cudd_Not(bFunc) ); printf( "\n" ); |
| if ( !Cudd_bddLeq( dd, Cudd_Not(pObj->pData), Cudd_Not(bFunc) ) ) |
| Vec_IntWriteEntry( vNodes, i, -1 ); |
| } |
| else if ( Entry == 1 ) |
| { |
| // Extra_bddPrint( dd, pObj->pData ); printf( "\n" ); |
| // Extra_bddPrint( dd, bFunc ); printf( "\n" ); |
| if ( !Cudd_bddLeq( dd, (DdNode *)pObj->pData, bFunc ) ) |
| Vec_IntWriteEntry( vNodes, i, -1 ); |
| } |
| } |
| Vec_PtrForEachEntry( DdNode *, vBdds, bFunc, i ) |
| if ( bFunc ) |
| Cudd_RecursiveDeref( dd, bFunc ); |
| Vec_PtrFree( vBdds ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Returns the array of constraint candidates.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Vec_Int_t * Llb_ManComputeBaseCase( Aig_Man_t * p, DdManager * dd ) |
| { |
| Vec_Int_t * vNodes; |
| Aig_Obj_t * pObj, * pRoot; |
| int i; |
| pRoot = Aig_ManCo( p, 0 ); |
| vNodes = Vec_IntStartFull( Aig_ManObjNumMax(p) ); |
| Aig_ManForEachObj( p, pObj, i ) |
| { |
| if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsCi(pObj) ) |
| continue; |
| if ( Cudd_bddLeq( dd, (DdNode *)pObj->pData, Cudd_Not(pRoot->pData) ) ) |
| Vec_IntWriteEntry( vNodes, i, 1 ); |
| else if ( Cudd_bddLeq( dd, Cudd_Not((DdNode *)pObj->pData), Cudd_Not(pRoot->pData) ) ) |
| Vec_IntWriteEntry( vNodes, i, 0 ); |
| } |
| return vNodes; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Constructs global BDDs for each object in the AIG manager.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| DdManager * Llb_ManConstructGlobalBdds( Aig_Man_t * p ) |
| { |
| DdManager * dd; |
| DdNode * bBdd0, * bBdd1; |
| Aig_Obj_t * pObj; |
| int i; |
| dd = Cudd_Init( Aig_ManCiNum(p), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); |
| Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT ); |
| pObj = Aig_ManConst1(p); |
| pObj->pData = Cudd_ReadOne(dd); Cudd_Ref( (DdNode *)pObj->pData ); |
| Aig_ManForEachCi( p, pObj, i ) |
| { |
| pObj->pData = Cudd_bddIthVar(dd, i); Cudd_Ref( (DdNode *)pObj->pData ); |
| } |
| Aig_ManForEachNode( p, pObj, i ) |
| { |
| bBdd0 = Cudd_NotCond( (DdNode *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) ); |
| bBdd1 = Cudd_NotCond( (DdNode *)Aig_ObjFanin1(pObj)->pData, Aig_ObjFaninC1(pObj) ); |
| pObj->pData = Cudd_bddAnd( dd, bBdd0, bBdd1 ); Cudd_Ref( (DdNode *)pObj->pData ); |
| } |
| Aig_ManForEachCo( p, pObj, i ) |
| { |
| pObj->pData = Cudd_NotCond( (DdNode *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) ); Cudd_Ref( (DdNode *)pObj->pData ); |
| } |
| return dd; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Derives inductive constraints.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Vec_Int_t * Llb_ManDeriveConstraints( Aig_Man_t * p ) |
| { |
| DdManager * dd; |
| Vec_Int_t * vNodes; |
| if ( Saig_ManPoNum(p) != 1 ) |
| { |
| printf( "The AIG has %d property outputs.\n", Saig_ManPoNum(p) ); |
| return NULL; |
| } |
| assert( Saig_ManPoNum(p) == 1 ); |
| dd = Llb_ManConstructGlobalBdds( p ); |
| vNodes = Llb_ManComputeBaseCase( p, dd ); |
| if ( Llb_ManCountEntries(vNodes) > 0 ) |
| Llb_ManComputeIndCase( p, dd, vNodes ); |
| if ( Llb_ManCountEntries(vNodes) == 0 ) |
| Vec_IntFreeP( &vNodes ); |
| Llb_ManDerefenceBdds( p, dd ); |
| Extra_StopManager( dd ); |
| return vNodes; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Tests derived constraints.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Llb_ManConstrTest( Aig_Man_t * p ) |
| { |
| Vec_Int_t * vNodes; |
| vNodes = Llb_ManDeriveConstraints( p ); |
| Llb_ManPrintEntries( p, vNodes ); |
| Vec_IntFreeP( &vNodes ); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |