Abc_NtkForEachObj( pNtk, pObj, i )
 {
     // skip constants, PIs, and latches
     if ( Abc_ObjFaninNum(pObj) == 0 || Abc_ObjIsLatch(pObj) )
         continue;
     // process the first fanin
     Vec_IntClear( vInitValues );
     pFaninNew = Abc_NodeAigToSeq( pObj->pCopy, pObj, 0, vInitValues );
     Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
     // store the initial values
     Vec_IntForEachEntry( vInitValues, Init, k )
         Seq_NodeInsertFirst( pObj->pCopy, 0, Init );
     // skip single-input nodes
     if ( Abc_ObjFaninNum(pObj) == 1 )
         continue;
     // process the second fanin
     Vec_IntClear( vInitValues );
     pFaninNew = Abc_NodeAigToSeq( pObj->pCopy, pObj, 1, vInitValues );
     Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
     // store the initial values
     Vec_IntForEachEntry( vInitValues, Init, k )
         Seq_NodeInsertFirst( pObj->pCopy, 1, Init );
 }
/**Function*************************************************************

  Synopsis    [Transforms the node to take fanout sharing into account.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Seq_NodeShareOne( Abc_Obj_t * pNode, Abc_InitType_t Init, Vec_Ptr_t * vNodes )
{
    Vec_Int_t * vNums  = Seq_ObjLNums( pNode );
    Vec_Ptr_t * vInits = Seq_NodeLats( pNode );
    Abc_Obj_t * pFanout, * pBuffer;
    Abc_InitType_t Type, InitNew;
    int i;
    // collect the fanouts that satisfy the property (have initial value Init or DC)
    InitNew = ABC_INIT_DC;
    Vec_PtrClear( vNodes );
    Abc_ObjForEachFanout( pNode, pFanout, i )
    {
        if ( Seq_ObjFanoutL(pNode, pFanout) == 0 )
            continue;
        Type = Seq_NodeGetInitLast( pFanout, Abc_ObjFanoutEdgeNum(pNode, pFanout) );
        if ( Type == Init )
            InitNew = Init;
        if ( Type == Init || Type == ABC_INIT_DC )
        {
            Vec_PtrPush( vNodes, pFanout );
            Seq_NodeDeleteLast( pFanout, Abc_ObjFanoutEdgeNum(pNode, pFanout) );
        }
    }
    // create the new buffer
    pBuffer = Abc_NtkCreateNode( pNode->pNtk );
    Abc_ObjAddFanin( pBuffer, pNode );

    // grow storage for initial states
    Vec_PtrGrow( vInits, 2 * pBuffer->Id + 2 );
    for ( i = Vec_PtrSize(vInits); i < 2 * (int)pBuffer->Id + 2; i++ )
        Vec_PtrPush( vInits, NULL );
    // grow storage for numbers of latches
    Vec_IntGrow( vNums, 2 * pBuffer->Id + 2 );
    for ( i = Vec_IntSize(vNums); i < 2 * (int)pBuffer->Id + 2; i++ )
        Vec_IntPush( vNums, 0 );
    // insert the new latch
    Seq_NodeInsertFirst( pBuffer, 0, InitNew );

    // redirect the fanouts
    Vec_PtrForEachEntry( vNodes, pFanout, i )
        Abc_ObjPatchFanin( pFanout, pNode, pBuffer );
}
/**Function*************************************************************

  Synopsis    [Retimes node backward by one latch.]

  Description [Constructs the problem for initial state computation.
  Returns 1 if the conflict is found.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Abc_ObjRetimeBackward( Abc_Obj_t * pObj, Abc_Ntk_t * pNtkNew, stmm_table * tTable, Vec_Int_t * vValues )  
{
    Abc_Obj_t * pFanout;
    Abc_InitType_t Init, Value;
    Seq_RetEdge_t RetEdge;
    Abc_Obj_t * pNodeNew, * pFanoutNew, * pBuffer;
    int i, Edge, fMet0, fMet1, fMetN;

    // make sure the node can be retimed
    assert( Seq_ObjFanoutLMin(pObj) > 0 );
    // get the fanout values
    fMet0 = fMet1 = fMetN = 0;
    Abc_ObjForEachFanout( pObj, pFanout, i )
    {
        if ( Abc_ObjFaninId0(pFanout) == pObj->Id )
        {
            Init = Seq_NodeGetInitLast( pFanout, 0 );
            if ( Init == ABC_INIT_ZERO )
                fMet0 = 1;
            else if ( Init == ABC_INIT_ONE )
                fMet1 = 1;
            else if ( Init == ABC_INIT_NONE )
                fMetN = 1;
        }
        if ( Abc_ObjFaninId1(pFanout) == pObj->Id )
        {
            Init = Seq_NodeGetInitLast( pFanout, 1 );
            if ( Init == ABC_INIT_ZERO )
                fMet0 = 1;
            else if ( Init == ABC_INIT_ONE )
                fMet1 = 1;
            else if ( Init == ABC_INIT_NONE )
                fMetN = 1;
        }
    }

    // consider the case when all fanout latches have don't-care values
    // the new values on the fanin edges will be don't-cares
    if ( !fMet0 && !fMet1 && !fMetN )
    {
        // make sure the label is clean
        Abc_ObjForEachFanout( pObj, pFanout, i )
            assert( pFanout->fMarkC == 0 );
        // update the fanout edges
        Abc_ObjForEachFanout( pObj, pFanout, i )
        {
            if ( pFanout->fMarkC )
                continue;
            pFanout->fMarkC = 1;
            if ( Abc_ObjFaninId0(pFanout) == pObj->Id )
                Seq_NodeDeleteLast( pFanout, 0 );
            if ( Abc_ObjFaninId1(pFanout) == pObj->Id )
                Seq_NodeDeleteLast( pFanout, 1 );
        }
        // clean the label
        Abc_ObjForEachFanout( pObj, pFanout, i )
            pFanout->fMarkC = 0;
        // update the fanin edges
        Abc_ObjRetimeBackwardUpdateEdge( pObj, 0, tTable );
        Abc_ObjRetimeBackwardUpdateEdge( pObj, 1, tTable );
        Seq_NodeInsertFirst( pObj, 0, ABC_INIT_DC );
        Seq_NodeInsertFirst( pObj, 1, ABC_INIT_DC );
        return 0;
    }