abc/src/base/abci/abcDetect.c
/**Function*************************************************************

  Synopsis    [Detect equivalence classes of nodes in terms of their TFO.]

  Description [Given is the logic network (pNtk) and the set of objects
  (primary inputs or internal nodes) to be considered (vObjs), this function
  returns a set of equivalence classes of these objects in terms of their 
  transitive fanout (TFO). Two objects belong to the same class if the set 
  of COs they feed into are the same.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Function
Synopsis    [Detect equivalence classes of nodes in terms of their TFO.]

Description [Given is the logic network (pNtk) and the set of objects
(primary inputs or internal nodes) to be considered (vObjs), this function
returns a set of equivalence classes of these objects in terms of their
transitive fanout (TFO). Two objects belong to the same class if the set
of COs they feed into are the same.]




Function Synopsis [ Detect equivalence classes of nodes in terms of their TFO . ] Description [ Given is the logic network ( pNtk ) and the set of objects ( primary inputs or internal nodes ) to be considered ( vObjs ) this function returns a set of equivalence classes of these objects in terms of their transitive fanout ( TFO ) . Two objects belong to the same class if the set of COs they feed into are the same . ]
int Abc_NtkDetectObjClasses_rec( Abc_Obj_t * pObj, Vec_Int_t * vMap, Hsh_VecMan_t * pHash, Vec_Int_t * vTemp )
{
    Vec_Int_t * vArray, * vSet;
    Abc_Obj_t * pNext; int i;
    int Entry = Vec_IntEntry(vMap, Abc_ObjId(pObj));
    if ( Entry != -1 ) 
        return Entry;
    assert( Abc_ObjIsCi(pObj) || Abc_ObjIsNode(pObj) );
    if ( Abc_ObjFanoutNum(pObj) == 0 )
    {
        Vec_IntWriteEntry( vMap, Abc_ObjId(pObj), 0 );
        return 0;
    }
    Entry = Abc_NtkDetectObjClasses_rec( Abc_ObjFanout0(pObj), vMap, pHash, vTemp );
    if ( Abc_ObjFanoutNum(pObj) == 1 )
    {
        Vec_IntWriteEntry( vMap, Abc_ObjId(pObj), Entry );
        return Entry;
    }
    vSet = Vec_IntAlloc( 16 );
    vArray = Hsh_VecReadEntry( pHash, Entry );
    Vec_IntClear( vSet );
    Vec_IntAppend( vSet, vArray );
    Abc_ObjForEachFanout( pObj, pNext, i )
    {
        if ( i == 0 ) 
            continue;
        Entry = Abc_NtkDetectObjClasses_rec( pNext, vMap, pHash, vTemp );
        vArray = Hsh_VecReadEntry( pHash, Entry );
        Vec_IntTwoMerge2( vSet, vArray, vTemp );
        ABC_SWAP( Vec_Int_t, *vSet, *vTemp );
    }
    Entry = Hsh_VecManAdd( pHash, vSet );
    Vec_IntWriteEntry( vMap, Abc_ObjId(pObj), Entry );
    Vec_IntFree( vSet );
    return Entry;
}
int Abc_NtkDetectObjClasses_rec ( Abc_Obj_t * pObj , Vec_Int_t * vMap , Hsh_VecMan_t * pHash , Vec_Int_t * vTemp ) { Vec_Int_t * vArray , * vSet ; Abc_Obj_t * pNext ; int i ; int Entry = Vec_IntEntry ( vMap , Abc_ObjId ( pObj ) ) ; if ( Entry != -1 ) return Entry ; assert ( Abc_ObjIsCi ( pObj ) || Abc_ObjIsNode ( pObj ) ) ; if ( Abc_ObjFanoutNum ( pObj ) == 0 ) { Vec_IntWriteEntry ( vMap , Abc_ObjId ( pObj ) , 0 ) ; return 0 ; } Entry = Abc_NtkDetectObjClasses_rec ( Abc_ObjFanout0 ( pObj ) , vMap , pHash , vTemp ) ; if ( Abc_ObjFanoutNum ( pObj ) == 1 ) { Vec_IntWriteEntry ( vMap , Abc_ObjId ( pObj ) , Entry ) ; return Entry ; } vSet = Vec_IntAlloc ( 16 ) ; vArray = Hsh_VecReadEntry ( pHash , Entry ) ; Vec_IntClear ( vSet ) ; Vec_IntAppend ( vSet , vArray ) ; Abc_ObjForEachFanout ( pObj , pNext , i ) { if ( i == 0 ) continue ; Entry = Abc_NtkDetectObjClasses_rec ( pNext , vMap , pHash , vTemp ) ; vArray = Hsh_VecReadEntry ( pHash , Entry ) ; Vec_IntTwoMerge2 ( vSet , vArray , vTemp ) ; ABC_SWAP ( Vec_Int_t , * vSet , * vTemp ) ; } Entry = Hsh_VecManAdd ( pHash , vSet ) ; Vec_IntWriteEntry ( vMap , Abc_ObjId ( pObj ) , Entry ) ; Vec_IntFree ( vSet ) ; return Entry ; }
Function
Synopsis    [Detect equivalence classes of nodes in terms of their TFO.]
Function Synopsis [ Detect equivalence classes of nodes in terms of their TFO . ]
// get the CO set for this object // the set is already computed // compute a new CO set // if there is no fanouts, the set of COs is empty // compute the set for the first fanout // initialize the set with that of first fanout // iteratively add sets of other fanouts // create or find new set and map the object into it