/**CFile****************************************************************

  FileName    [wlcAbs.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Verilog parser.]

  Synopsis    [Abstraction for word-level networks.]

  Author      [Yen-Sheng Ho, Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - August 22, 2014.]

  Revision    [$Id: wlcAbs.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]

***********************************************************************/

#include "wlc.h"
#include "proof/pdr/pdr.h"
#include "proof/pdr/pdrInt.h"
#include "proof/ssw/ssw.h"
#include "aig/gia/giaAig.h"
#include "sat/bmc/bmc.h"

ABC_NAMESPACE_IMPL_START

////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

extern Vec_Vec_t *   IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast );
extern int           IPdr_ManRestoreClauses( Pdr_Man_t * p, Vec_Vec_t * vClauses, Vec_Int_t * vMap );
extern int           IPdr_ManRebuildClauses( Pdr_Man_t * p, Vec_Vec_t * vClauses );
extern int           IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses );
extern int           IPdr_ManCheckCombUnsat( Pdr_Man_t * p );
extern int           IPdr_ManReduceClauses( Pdr_Man_t * p, Vec_Vec_t * vClauses );
extern void          IPdr_ManPrintClauses( Vec_Vec_t * vClauses, int kStart, int nRegs );
extern void          Wla_ManJoinThread( Wla_Man_t * pWla, int RunId );
extern void          Wla_ManConcurrentBmc3( Wla_Man_t * pWla, Aig_Man_t * pAig, Abc_Cex_t ** ppCex );
extern int           Wla_CallBackToStop( int RunId );
extern int           Wla_GetGlobalRunId();

typedef struct Int_Pair_t_       Int_Pair_t;
struct Int_Pair_t_
{
    int first;
    int second;
};

int IntPairPtrCompare ( Int_Pair_t ** a, Int_Pair_t ** b )
{
    return (*a)->second < (*b)->second; 
}

////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

void Wlc_NtkPrintNtk( Wlc_Ntk_t * p )
{
    int i;
    Wlc_Obj_t * pObj;

    Abc_Print( 1, "PIs:");
    Wlc_NtkForEachPi( p, pObj, i )
        Abc_Print( 1, " %s", Wlc_ObjName(p, Wlc_ObjId(p, pObj)) );
    Abc_Print( 1, "\n\n");

    Abc_Print( 1, "POs:");
    Wlc_NtkForEachPo( p, pObj, i )
        Abc_Print( 1, " %s", Wlc_ObjName(p, Wlc_ObjId(p, pObj)) );
    Abc_Print( 1, "\n\n");

    Abc_Print( 1, "FO(Fi)s:");
    Wlc_NtkForEachCi( p, pObj, i )
        if ( !Wlc_ObjIsPi( pObj ) )
            Abc_Print( 1, " %s(%s)", Wlc_ObjName(p, Wlc_ObjId(p, pObj)), Wlc_ObjName(p, Wlc_ObjId(p, Wlc_ObjFo2Fi(p, pObj))) );
    Abc_Print( 1, "\n\n");

    Abc_Print( 1, "Objs:\n");
    Wlc_NtkForEachObj( p, pObj, i )
    {
        if ( !Wlc_ObjIsCi(pObj) )
           Wlc_NtkPrintNode( p, pObj ) ;
    }
}

void Wlc_NtkAbsGetSupp_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vCiMarks, Vec_Int_t * vSuppRefs, Vec_Int_t * vSuppList )
{
    int i, iFanin, iObj;
    if ( pObj->Mark ) // visited
        return;
    pObj->Mark = 1;
    iObj = Wlc_ObjId( p, pObj );
    if ( Vec_BitEntry( vCiMarks, iObj ) )
    {
        if ( vSuppRefs )
            Vec_IntAddToEntry( vSuppRefs, iObj, 1 );
        if ( vSuppList )
            Vec_IntPush( vSuppList, iObj );
        return;
    }
    Wlc_ObjForEachFanin( pObj, iFanin, i )
        Wlc_NtkAbsGetSupp_rec( p, Wlc_NtkObj(p, iFanin), vCiMarks, vSuppRefs, vSuppList );
}

void Wlc_NtkAbsGetSupp( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vCiMarks, Vec_Int_t * vSuppRefs, Vec_Int_t * vSuppList)
{
    assert( vSuppRefs || vSuppList );
    Wlc_NtkCleanMarks( p );

    Wlc_NtkAbsGetSupp_rec( p, pObj, vCiMarks, vSuppRefs, vSuppList );
}

int Wlc_NtkNumPiBits( Wlc_Ntk_t * pNtk ) 
{
    int num = 0;
    int i;
    Wlc_Obj_t * pObj;
    Wlc_NtkForEachPi(pNtk, pObj, i) {
        num += Wlc_ObjRange(pObj);
    }
    return num;
}

void Wlc_NtkAbsAnalyzeRefine( Wlc_Ntk_t * p, Vec_Int_t * vBlacks, Vec_Bit_t * vUnmark, int * nDisj, int * nNDisj )
{
    Vec_Bit_t * vCurCis, * vCandCis;
    Vec_Int_t * vSuppList;
    Vec_Int_t * vDeltaB;
    Vec_Int_t * vSuppRefs;
    int i, Entry;
    Wlc_Obj_t * pObj;
    
    vCurCis    = Vec_BitStart( Wlc_NtkObjNumMax( p ) );
    vCandCis   = Vec_BitStart( Wlc_NtkObjNumMax( p ) );
    vDeltaB    = Vec_IntAlloc( Vec_IntSize(vBlacks) );
    vSuppList  = Vec_IntAlloc( Wlc_NtkCiNum(p) + Vec_IntSize(vBlacks) );
    vSuppRefs  = Vec_IntAlloc( Wlc_NtkObjNumMax( p ) );


    Vec_IntFill( vSuppRefs, Wlc_NtkObjNumMax( p ), 0 );

    Wlc_NtkForEachCi( p, pObj, i )
    {
        Vec_BitWriteEntry( vCurCis, Wlc_ObjId(p, pObj), 1 ) ;
        Vec_BitWriteEntry( vCandCis, Wlc_ObjId(p, pObj), 1 ) ;
    }

    Vec_IntForEachEntry( vBlacks, Entry, i )
    {
        Vec_BitWriteEntry( vCurCis, Entry, 1 );
        if ( !Vec_BitEntry( vUnmark, Entry ) )
            Vec_BitWriteEntry( vCandCis, Entry, 1 );
        else
            Vec_IntPush( vDeltaB, Entry );
    }
    assert( Vec_IntSize( vDeltaB ) );
    
    Wlc_NtkForEachCo( p, pObj, i )
        Wlc_NtkAbsGetSupp( p, pObj, vCurCis, vSuppRefs, NULL );
    
    /*
    Abc_Print( 1, "SuppCurrentAbs =" );
    Wlc_NtkForEachObj( p, pObj, i )
        if ( Vec_IntEntry(vSuppRefs, i) > 0 )
            Abc_Print( 1, " %d", i );
    Abc_Print( 1, "\n" );
    */

    Vec_IntForEachEntry( vDeltaB, Entry, i )
        Wlc_NtkAbsGetSupp( p, Wlc_NtkObj(p, Entry), vCandCis, vSuppRefs, NULL );

    Vec_IntForEachEntry( vDeltaB, Entry, i )
    {
        int iSupp, ii;
        int fDisjoint = 1;

        Vec_IntClear( vSuppList );
        Wlc_NtkAbsGetSupp( p, Wlc_NtkObj(p, Entry), vCandCis, NULL, vSuppList );

        //Abc_Print( 1, "SuppCandAbs =" );
        Vec_IntForEachEntry( vSuppList, iSupp, ii )
        {
            //Abc_Print( 1, " %d(%d)", iSupp, Vec_IntEntry( vSuppRefs, iSupp ) );
            if ( Vec_IntEntry( vSuppRefs, iSupp ) >= 2 )
            {
                fDisjoint = 0;
                break;
            }
        }
        //Abc_Print( 1, "\n" );
        
        if ( fDisjoint )
        {
            //Abc_Print( 1, "PPI[%d] is disjoint.\n", Entry );
            ++(*nDisj);
        }
        else 
        {
            //Abc_Print( 1, "PPI[%d] is non-disjoint.\n", Entry );
            ++(*nNDisj);
        }
    }

    Vec_BitFree( vCurCis );
    Vec_BitFree( vCandCis );
    Vec_IntFree( vDeltaB );
    Vec_IntFree( vSuppList );
    Vec_IntFree( vSuppRefs );
}

static Vec_Int_t * Wlc_NtkGetCoreSels( Gia_Man_t * pFrames, int nFrames, int first_sel_pi, int num_sel_pis, Vec_Bit_t * vMark, int nConfLimit, Wlc_Par_t * pPars, int fSetPO, int RunId ) 
{
    Vec_Int_t * vCores = NULL;
    Aig_Man_t * pAigFrames = Gia_ManToAigSimple( pFrames );
    Cnf_Dat_t * pCnf = Cnf_Derive(pAigFrames, Aig_ManCoNum(pAigFrames));
    sat_solver * pSat = sat_solver_new();
    int i;

    sat_solver_setnvars(pSat, pCnf->nVars);
    if ( RunId >= 0 )
    {
        sat_solver_set_runid( pSat, RunId );
        sat_solver_set_stop_func( pSat, Wla_CallBackToStop );
    }

    for (i = 0; i < pCnf->nClauses; i++) 
    {
        if (!sat_solver_addclause(pSat, pCnf->pClauses[i], pCnf->pClauses[i + 1]))
            assert(false);
    }
    // add PO clauses
    {
        Vec_Int_t* vLits = Vec_IntAlloc(100);
        Aig_Obj_t* pObj;
        int i, ret;
        Aig_ManForEachCo( pAigFrames, pObj, i )
        {
            assert(pCnf->pVarNums[pObj->Id] >= 0);
            Vec_IntPush(vLits, toLitCond(pCnf->pVarNums[pObj->Id], 0));
        }
        if ( !fSetPO )
        {
            ret = sat_solver_addclause(pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits));
            if (!ret) 
                Abc_Print( 1, "UNSAT after adding PO clauses.\n" );
        }
        else
        {
            int Lit;
            for ( i = 0; i < Vec_IntSize(vLits); ++i )
            {
                if ( i == Vec_IntSize(vLits) - 1 )
                    Lit = Vec_IntEntry( vLits, i );
                else
                    Lit = lit_neg(Vec_IntEntry( vLits, i ));
                ret = sat_solver_addclause(pSat, &Lit, &Lit + 1);
                if (!ret) 
                    Abc_Print( 1, "UNSAT after adding PO clauses.\n" );
            }
        }

        Vec_IntFree(vLits);
    }
    
    // main procedure
    {
        int status;
        Vec_Int_t* vLits = Vec_IntAlloc(100);
        Vec_Int_t* vMapVar2Sel = Vec_IntStart( pCnf->nVars );
        for ( i = 0; i < num_sel_pis; ++i ) 
        {
            int cur_pi = first_sel_pi + i;
            int var = pCnf->pVarNums[Aig_ManCi(pAigFrames, cur_pi)->Id];
            int Lit;
            assert(var >= 0);
            Vec_IntWriteEntry( vMapVar2Sel, var, i );
            Lit = toLitCond( var, 0 );
            if ( Vec_BitEntry( vMark, i ) )
                Vec_IntPush(vLits, Lit);
            else
                sat_solver_addclause( pSat, &Lit, &Lit+1 );
        }
        /*
            int i, Entry;
            Abc_Print( 1, "#vLits = %d; vLits = ", Vec_IntSize(vLits) );
            Vec_IntForEachEntry(vLits, Entry, i)
                Abc_Print( 1, "%d ", Entry);
            Abc_Print( 1, "\n");
        */
        status = sat_solver_solve(pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits), (ABC_INT64_T)(nConfLimit), (ABC_INT64_T)(0), (ABC_INT64_T)(0), (ABC_INT64_T)(0));
        if (status == l_False) {
            int nCoreLits, *pCoreLits;
            Abc_Print( 1, "UNSAT.\n" );
            nCoreLits = sat_solver_final(pSat, &pCoreLits);
            vCores = Vec_IntAlloc( nCoreLits );
            for (i = 0; i < nCoreLits; i++) 
            {
                Vec_IntPush( vCores, Vec_IntEntry( vMapVar2Sel, lit_var( pCoreLits[i] ) ) );
            }
        } else if (status == l_True) {
            Abc_Print( 1, "SAT.\n" );
        } else {
            Abc_Print( 1, "UNKNOWN.\n" );
        }

        Vec_IntFree(vLits);
        Vec_IntFree(vMapVar2Sel);
    }
    Cnf_ManFree();
    sat_solver_delete(pSat);
    Aig_ManStop(pAigFrames);

    return vCores;
}

static Gia_Man_t * Wlc_NtkUnrollWoCex(Wlc_Ntk_t * pChoice, int nFrames, int first_sel_pi, int num_sel_pis)
{
    Gia_Man_t * pGiaChoice = Wlc_NtkBitBlast( pChoice, NULL );
    Gia_Man_t * pFrames = NULL, * pGia;
    Gia_Obj_t * pObj, * pObjRi;
    int f, i;

    pFrames = Gia_ManStart( 10000 );
    pFrames->pName = Abc_UtilStrsav( pGiaChoice->pName );
    Gia_ManHashAlloc( pFrames );
    Gia_ManConst0(pGiaChoice)->Value = 0;
    Gia_ManForEachRi( pGiaChoice, pObj, i )
        pObj->Value = 0;

    for ( f = 0; f < nFrames; f++ ) 
    {
        for( i = 0; i < Gia_ManPiNum(pGiaChoice); i++ ) 
        {
            if ( i >= first_sel_pi && i < first_sel_pi + num_sel_pis ) 
            {
                if( f == 0 )
                    Gia_ManPi(pGiaChoice, i)->Value = Gia_ManAppendCi(pFrames);
            } 
            else
            {
                Gia_ManPi(pGiaChoice, i)->Value = Gia_ManAppendCi(pFrames);
            } 
        }
        Gia_ManForEachRiRo( pGiaChoice, pObjRi, pObj, i )
            pObj->Value = pObjRi->Value;
        Gia_ManForEachAnd( pGiaChoice, pObj, i )
            pObj->Value = Gia_ManHashAnd(pFrames, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj));
        Gia_ManForEachCo( pGiaChoice, pObj, i )
            pObj->Value = Gia_ObjFanin0Copy(pObj);
        Gia_ManForEachPo( pGiaChoice, pObj, i )
            Gia_ManAppendCo(pFrames, pObj->Value);
    }
    Gia_ManHashStop (pFrames);
    Gia_ManSetRegNum(pFrames, 0);
    pFrames = Gia_ManCleanup(pGia = pFrames);
    Gia_ManStop(pGia);
    Gia_ManStop(pGiaChoice);

    return pFrames;
}

static Gia_Man_t * Wlc_NtkUnrollWithCex(Wlc_Ntk_t * pChoice, Abc_Cex_t * pCex, int nbits_old_pis, int num_sel_pis, int * p_num_ppis, int sel_pi_first, int fUsePPI) 
{
    Gia_Man_t * pGiaChoice = Wlc_NtkBitBlast( pChoice, NULL );
    int nbits_new_pis = Wlc_NtkNumPiBits( pChoice );
    int num_ppis = nbits_new_pis - nbits_old_pis - num_sel_pis;
    int num_undc_pis = Gia_ManPiNum(pGiaChoice) - nbits_new_pis;
    Gia_Man_t * pFrames = NULL;
    Gia_Obj_t * pObj, * pObjRi;
    int f, i;
    int is_sel_pi;
    Gia_Man_t * pGia;
    *p_num_ppis = num_ppis;

    Abc_Print( 1, "#orig_pis = %d, #ppis = %d, #sel_pis = %d, #undc_pis = %d\n", nbits_old_pis, num_ppis, num_sel_pis, num_undc_pis );
    assert(Gia_ManPiNum(pGiaChoice)==nbits_old_pis+num_ppis+num_sel_pis+num_undc_pis);
    assert(Gia_ManPiNum(pGiaChoice)==pCex->nPis+num_sel_pis);

    pFrames = Gia_ManStart( 10000 );
    pFrames->pName = Abc_UtilStrsav( pGiaChoice->pName );
    Gia_ManHashAlloc( pFrames );
    Gia_ManConst0(pGiaChoice)->Value = 0;
    Gia_ManForEachRi( pGiaChoice, pObj, i )
        pObj->Value = 0;

    for ( f = 0; f <= pCex->iFrame; f++ ) 
    {
        for( i = 0; i < Gia_ManPiNum(pGiaChoice); i++ ) 
        {
            if ( i >= nbits_old_pis && i < nbits_old_pis + num_ppis + num_sel_pis ) 
            {
                is_sel_pi = sel_pi_first ? (i < nbits_old_pis + num_sel_pis) : (i >= nbits_old_pis + num_ppis);
                if( f == 0 && is_sel_pi )
                    Gia_ManPi(pGiaChoice, i)->Value = Gia_ManAppendCi(pFrames);
                if( !is_sel_pi )
                {
                    if ( !fUsePPI )
                        Gia_ManPi(pGiaChoice, i)->Value = Gia_ManAppendCi(pFrames);
                    else
                        Gia_ManPi(pGiaChoice, i)->Value = Abc_InfoHasBit(pCex->pData, pCex->nRegs+pCex->nPis*f + i + num_undc_pis);
                }
            } 
            else if (i < nbits_old_pis) 
            {
                Gia_ManPi(pGiaChoice, i)->Value = Abc_InfoHasBit(pCex->pData, pCex->nRegs+pCex->nPis*f + i);
            } 
            else if (i >= nbits_old_pis + num_ppis + num_sel_pis) 
            {
                Gia_ManPi(pGiaChoice, i)->Value = Abc_InfoHasBit(pCex->pData, pCex->nRegs+pCex->nPis*f + i - num_sel_pis - num_ppis);
            }
        }
        Gia_ManForEachRiRo( pGiaChoice, pObjRi, pObj, i )
            pObj->Value = pObjRi->Value;
        Gia_ManForEachAnd( pGiaChoice, pObj, i )
            pObj->Value = Gia_ManHashAnd(pFrames, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj));
        Gia_ManForEachCo( pGiaChoice, pObj, i )
            pObj->Value = Gia_ObjFanin0Copy(pObj);
        Gia_ManForEachPo( pGiaChoice, pObj, i )
            Gia_ManAppendCo(pFrames, pObj->Value);
    }
    Gia_ManHashStop (pFrames);
    Gia_ManSetRegNum(pFrames, 0);
    pFrames = Gia_ManCleanup(pGia = pFrames);
    Gia_ManStop(pGia);
    Gia_ManStop(pGiaChoice);

    return pFrames;
}

Wlc_Ntk_t * Wlc_NtkIntroduceChoices( Wlc_Ntk_t * pNtk, Vec_Int_t * vBlacks, Vec_Int_t * vPPIs )
{
    //if ( vBlacks== NULL ) return NULL;
    Vec_Int_t * vNodes = Vec_IntDup( vBlacks );
    Wlc_Ntk_t * pNew;
    Wlc_Obj_t * pObj;
    int i, k, iObj, iFanin;
    Vec_Int_t * vFanins = Vec_IntAlloc( 3 );
    Vec_Int_t * vMapNode2Pi = Vec_IntStart( Wlc_NtkObjNumMax(pNtk) );
    Vec_Int_t * vMapNode2Sel = Vec_IntStart( Wlc_NtkObjNumMax(pNtk) );
    int nOrigObjNum = Wlc_NtkObjNumMax( pNtk );
    Wlc_Ntk_t * p = Wlc_NtkDupDfsSimple( pNtk );
    Vec_Bit_t * vPPIMark = NULL;

    Wlc_NtkForEachObjVec( vNodes, pNtk, pObj, i ) 
    {
        // TODO : fix FOs here
        Vec_IntWriteEntry(vNodes, i, Wlc_ObjCopy(pNtk, Wlc_ObjId(pNtk, pObj)));
    }

    if ( vPPIs )
    {
        vPPIMark = Vec_BitStart( Wlc_NtkObjNumMax(pNtk) );
        Wlc_NtkForEachObjVec( vPPIs, pNtk, pObj, i ) 
        {
            Vec_IntWriteEntry(vPPIs, i, Wlc_ObjCopy(pNtk, Wlc_ObjId(pNtk, pObj)));
            Vec_BitWriteEntry( vPPIMark, Vec_IntEntry(vPPIs, i), 1 );
        }
    }

    // Vec_IntPrint(vNodes);
    Wlc_NtkCleanCopy( p );

    // mark nodes
    Wlc_NtkForEachObjVec( vNodes, p, pObj, i ) 
    {
        iObj = Wlc_ObjId(p, pObj);
        pObj->Mark = 1;
        // add fresh PI with the same number of bits
        Vec_IntWriteEntry( vMapNode2Pi, iObj, Wlc_ObjAlloc( p, WLC_OBJ_PI, Wlc_ObjIsSigned(pObj), Wlc_ObjRange(pObj) - 1, 0 ) );
    }

    if ( vPPIs )
    {
        Wlc_NtkForEachObjVec( vPPIs, p, pObj, i ) 
        {
            iObj = Wlc_ObjId(p, pObj);
            pObj->Mark = 1;
            // add fresh PI with the same number of bits
            Vec_IntWriteEntry( vMapNode2Pi, iObj, Wlc_ObjAlloc( p, WLC_OBJ_PI, Wlc_ObjIsSigned(pObj), Wlc_ObjRange(pObj) - 1, 0 ) );
        }
    }

    // add sel PI
    Wlc_NtkForEachObjVec( vNodes, p, pObj, i ) 
    {
        iObj = Wlc_ObjId( p, pObj );
        Vec_IntWriteEntry( vMapNode2Sel, iObj, Wlc_ObjAlloc( p, WLC_OBJ_PI, 0, 0, 0 ) );
    }

    // iterate through the nodes in the DFS order
    Wlc_NtkForEachObj( p, pObj, i )
    {
        int isSigned, range;
        if ( i == nOrigObjNum ) 
        {
            // cout << "break at " << i << endl;
            break;
        }

        // update fanins
        Wlc_ObjForEachFanin( pObj, iFanin, k )
            Wlc_ObjFanins(pObj)[k] = Wlc_ObjCopy(p, iFanin);
        // node to remain
        iObj = i;

        if ( pObj->Mark ) 
        {
            // clean
            pObj->Mark = 0;

            if ( vPPIMark && Vec_BitEntry(vPPIMark, i) )
                iObj = Vec_IntEntry( vMapNode2Pi, i );
            else
            {
                isSigned = Wlc_ObjIsSigned(pObj);
                range = Wlc_ObjRange(pObj);
                Vec_IntClear(vFanins);
                Vec_IntPush(vFanins, Vec_IntEntry( vMapNode2Sel, i) );
                Vec_IntPush(vFanins, Vec_IntEntry( vMapNode2Pi, i ) );
                Vec_IntPush(vFanins, i);
                iObj = Wlc_ObjCreate(p, WLC_OBJ_MUX, isSigned, range - 1, 0, vFanins);
            }
        }
        
        Wlc_ObjSetCopy( p, i, iObj );
    }

    Wlc_NtkForEachCo( p, pObj, i )
    {
        iObj = Wlc_ObjId(p, pObj);
        if (iObj != Wlc_ObjCopy(p, iObj)) 
        {
            if (pObj->fIsFi)
                Wlc_NtkObj(p, Wlc_ObjCopy(p, iObj))->fIsFi = 1;
            else
                Wlc_NtkObj(p, Wlc_ObjCopy(p, iObj))->fIsPo = 1;

            Vec_IntWriteEntry(&p->vCos, i, Wlc_ObjCopy(p, iObj));
        }
    }

    // DumpWlcNtk(p);
    pNew = Wlc_NtkDupDfsSimple( p );

    if ( vPPIMark )
        Vec_BitFree( vPPIMark );
    Vec_IntFree( vFanins );
    Vec_IntFree( vMapNode2Pi );
    Vec_IntFree( vMapNode2Sel );
    Vec_IntFree( vNodes );
    Wlc_NtkFree( p );

    return pNew;
}

static Abc_Cex_t * Wlc_NtkCexIsReal( Wlc_Ntk_t * pOrig, Abc_Cex_t * pCex ) 
{
    Gia_Man_t * pGiaOrig = Wlc_NtkBitBlast( pOrig, NULL );
    int f, i;
    Gia_Obj_t * pObj, * pObjRi;
    Abc_Cex_t * pCexReal = Abc_CexAlloc( Gia_ManRegNum(pGiaOrig), Gia_ManPiNum(pGiaOrig), pCex->iFrame + 1 );

    Gia_ManConst0(pGiaOrig)->Value = 0;
    Gia_ManForEachRi( pGiaOrig, pObj, i )
        pObj->Value = 0;
    for ( f = 0; f <= pCex->iFrame; f++ ) 
    {
        for( i = 0; i < Gia_ManPiNum( pGiaOrig ); i++ )
        { 
            Gia_ManPi(pGiaOrig, i)->Value = Abc_InfoHasBit(pCex->pData, pCex->nRegs+pCex->nPis*f + i);
            if ( Gia_ManPi(pGiaOrig, i)->Value )
                Abc_InfoSetBit(pCexReal->pData, pCexReal->nRegs + pCexReal->nPis*f + i);
        }
        Gia_ManForEachRiRo( pGiaOrig, pObjRi, pObj, i )
            pObj->Value = pObjRi->Value;
        Gia_ManForEachAnd( pGiaOrig, pObj, i )
            pObj->Value = Gia_ObjFanin0Copy(pObj) & Gia_ObjFanin1Copy(pObj);
        Gia_ManForEachCo( pGiaOrig, pObj, i )
            pObj->Value = Gia_ObjFanin0Copy(pObj);
        Gia_ManForEachPo( pGiaOrig, pObj, i ) 
        {
            if (pObj->Value==1) {
                Abc_Print( 1, "CEX is real on the original model.\n" );
                Gia_ManStop(pGiaOrig);
                pCexReal->iFrame = f;
                pCexReal->iPo = i;
                return pCexReal;
            }
        }
    }

    // Abc_Print( 1, "CEX is spurious.\n" );
    Gia_ManStop(pGiaOrig);
    Abc_CexFree(pCexReal);
    return NULL;
}

static Wlc_Ntk_t * Wlc_NtkAbs2( Wlc_Ntk_t * pNtk, Vec_Int_t * vBlacks, Vec_Int_t ** pvFlops )
{
    Vec_Int_t * vFlops  = Vec_IntAlloc( 100 );
    Vec_Int_t * vNodes  = Vec_IntDup( vBlacks );
    Wlc_Ntk_t * pNew;
    Wlc_Obj_t * pObj;
    int i, k, iObj, iFanin;
    Vec_Int_t * vMapNode2Pi = Vec_IntStart( Wlc_NtkObjNumMax(pNtk) );
    int nOrigObjNum = Wlc_NtkObjNumMax( pNtk );
    Wlc_Ntk_t * p = Wlc_NtkDupDfsSimple( pNtk );

    Wlc_NtkForEachCi( pNtk, pObj, i )
    {
        if ( !Wlc_ObjIsPi( pObj ) )
            Vec_IntPush( vFlops, Wlc_ObjId( pNtk, pObj ) ); 
    }

    Wlc_NtkForEachObjVec( vNodes, pNtk, pObj, i ) 
        Vec_IntWriteEntry(vNodes, i, Wlc_ObjCopy(pNtk, Wlc_ObjId(pNtk, pObj)));

    // mark nodes
    Wlc_NtkForEachObjVec( vNodes, p, pObj, i ) 
    {
        iObj = Wlc_ObjId(p, pObj);
        pObj->Mark = 1;
        // add fresh PI with the same number of bits
        Vec_IntWriteEntry( vMapNode2Pi, iObj, Wlc_ObjAlloc( p, WLC_OBJ_PI, Wlc_ObjIsSigned(pObj), Wlc_ObjRange(pObj) - 1, 0 ) );
    }

    Wlc_NtkCleanCopy( p );

    Wlc_NtkForEachObj( p, pObj, i )
    {
        if ( i == nOrigObjNum ) 
            break;

        if ( pObj->Mark ) {
            // clean
            pObj->Mark = 0;
            iObj = Vec_IntEntry( vMapNode2Pi, i );
        }
        else {
            // update fanins
            Wlc_ObjForEachFanin( pObj, iFanin, k )
                Wlc_ObjFanins(pObj)[k] = Wlc_ObjCopy(p, iFanin);
            // node to remain
            iObj = i;
        }
        Wlc_ObjSetCopy( p, i, iObj );
    }

    Wlc_NtkForEachCo( p, pObj, i )
    {
        iObj = Wlc_ObjId(p, pObj);
        if (iObj != Wlc_ObjCopy(p, iObj)) 
        {
            if (pObj->fIsFi)
                Wlc_NtkObj(p, Wlc_ObjCopy(p, iObj))->fIsFi = 1;
            else
                Wlc_NtkObj(p, Wlc_ObjCopy(p, iObj))->fIsPo = 1;


            Vec_IntWriteEntry(&p->vCos, i, Wlc_ObjCopy(p, iObj));
        }
    }

    pNew = Wlc_NtkDupDfsSimple( p );
    Vec_IntFree( vMapNode2Pi );
    Vec_IntFree( vNodes );
    Wlc_NtkFree( p );

    if ( pvFlops )
        *pvFlops = vFlops;
    else
        Vec_IntFree( vFlops );

    return pNew;
}

static Vec_Bit_t * Wlc_NtkProofReduce( Wlc_Ntk_t * p, Wlc_Par_t * pPars, int nFrames, Vec_Int_t * vWhites, Vec_Int_t * vBlacks, int RunId )
{
    Gia_Man_t * pGiaFrames;
    Wlc_Ntk_t * pNtkWithChoices = NULL; 
    Vec_Int_t * vCoreSels;
    Vec_Bit_t * vChoiceMark; 
    int first_sel_pi;
    int i, Entry;
    abctime clk = Abc_Clock();

    assert( vWhites && Vec_IntSize(vWhites) );
    pNtkWithChoices = Wlc_NtkIntroduceChoices( p, vWhites, vBlacks );

    first_sel_pi = Wlc_NtkNumPiBits( pNtkWithChoices ) - Vec_IntSize( vWhites );
    pGiaFrames = Wlc_NtkUnrollWoCex( pNtkWithChoices, nFrames, first_sel_pi, Vec_IntSize( vWhites ) );

    vChoiceMark = Vec_BitStartFull( Vec_IntSize( vWhites ) );      
    vCoreSels = Wlc_NtkGetCoreSels( pGiaFrames, nFrames, first_sel_pi, Vec_IntSize( vWhites ), vChoiceMark, 0, pPars, 0, RunId );

    Wlc_NtkFree( pNtkWithChoices );
    Gia_ManStop( pGiaFrames );

    if ( vCoreSels == NULL )
        return NULL;
 
    Vec_BitReset( vChoiceMark );
    Vec_IntForEachEntry( vCoreSels, Entry, i )
        Vec_BitWriteEntry( vChoiceMark, Entry, 1 );

    Abc_Print( 1, "ProofReduce: remove %d out of %d white boxes.", Vec_IntSize(vWhites) - Vec_BitCount(vChoiceMark), Vec_IntSize(vWhites) );
    Abc_PrintTime( 1, " Time", Abc_Clock() - clk );

    Vec_IntFree( vCoreSels );
    return vChoiceMark;
}

static int Wlc_NtkProofRefine( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Abc_Cex_t * pCex, Vec_Int_t * vBlacks, Vec_Int_t ** pvRefine )
{
    Gia_Man_t * pGiaFrames;
    Vec_Int_t * vRefine = NULL;
    Vec_Bit_t * vUnmark;
    Vec_Bit_t * vChoiceMark; 
    Wlc_Ntk_t * pNtkWithChoices = NULL; 
    Vec_Int_t * vCoreSels;
    int num_ppis = -1;
    int Entry, i;

    if ( *pvRefine == NULL )
        return 0;

    vUnmark = Vec_BitStart( Wlc_NtkObjNumMax( p ) );
    vChoiceMark = Vec_BitStart( Vec_IntSize( vBlacks ) );      

    Vec_IntForEachEntry( *pvRefine, Entry, i )
        Vec_BitWriteEntry( vUnmark, Entry, 1 );

    Vec_IntForEachEntry( vBlacks, Entry, i )
    {
        if ( Vec_BitEntry( vUnmark, Entry ) )
            Vec_BitWriteEntry( vChoiceMark, i, 1 );
    }

    pNtkWithChoices = vBlacks ? Wlc_NtkIntroduceChoices( p, vBlacks, NULL ) : NULL;
    pGiaFrames = Wlc_NtkUnrollWithCex( pNtkWithChoices, pCex, Wlc_NtkNumPiBits( p ), Vec_IntSize( vBlacks ), &num_ppis, 0, pPars->fProofUsePPI );

    if ( !pPars->fProofUsePPI )
        vCoreSels = Wlc_NtkGetCoreSels( pGiaFrames, pCex->iFrame+1, num_ppis, Vec_IntSize( vBlacks ), vChoiceMark, 0, pPars, 0, -1 );
    else
        vCoreSels = Wlc_NtkGetCoreSels( pGiaFrames, pCex->iFrame+1, 0, Vec_IntSize( vBlacks ), vChoiceMark, 0, pPars, 0, -1 );

    Wlc_NtkFree( pNtkWithChoices );
    Gia_ManStop( pGiaFrames );
    Vec_BitFree( vUnmark );
    Vec_BitFree( vChoiceMark );
 
    assert( Vec_IntSize( vCoreSels ) );

    vRefine = Vec_IntAlloc( 100 );
    Vec_IntForEachEntry( vCoreSels, Entry, i )
        Vec_IntPush( vRefine, Vec_IntEntry( vBlacks, Entry ) );

    Vec_IntFree( vCoreSels );

    if ( pPars->fVerbose )
        Abc_Print( 1, "Proof-based refinement reduces %d (out of %d) white boxes\n", Vec_IntSize( *pvRefine ) - Vec_IntSize( vRefine ), Vec_IntSize( *pvRefine ) );

    Vec_IntFree( *pvRefine );
    *pvRefine = vRefine;

    return 0;
}

static int Wlc_NtkUpdateBlacks( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Int_t ** pvBlacks, Vec_Bit_t * vUnmark, Vec_Int_t * vSignals )
{
    int Entry, i;
    Wlc_Obj_t * pObj; int Count[4] = {0};
    Vec_Int_t * vBlacks = Vec_IntAlloc( 100 );
    Vec_Int_t * vVec;

    assert( *pvBlacks );

    vVec = vSignals ? vSignals : *pvBlacks;

    Vec_IntForEachEntry( vVec, Entry, i )
    {
        if ( Vec_BitEntry( vUnmark, Entry) )
            continue;
        Vec_IntPush( vBlacks, Entry );

        pObj = Wlc_NtkObj( p, Entry );
        if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS )
            Count[0]++;
        else if ( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS )
            Count[1]++;
        else if ( pObj->Type == WLC_OBJ_MUX )
            Count[2]++;
        else if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) )
            Count[3]++;
    }
    
    Vec_IntFree( *pvBlacks );
    *pvBlacks = vBlacks;

    if ( pPars->fVerbose )
        printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Vec_IntSize( vBlacks ) - Count[0] - Count[1] - Count[2] );

    return 0;
}

static Vec_Bit_t * Wlc_NtkMarkLimit( Wlc_Ntk_t * p, Wlc_Par_t * pPars )
{
    Vec_Bit_t * vMarks = NULL;
    Vec_Ptr_t * vAdds  = Vec_PtrAlloc( 1000 );
    Vec_Ptr_t * vMuxes = Vec_PtrAlloc( 1000 );
    Vec_Ptr_t * vMults = Vec_PtrAlloc( 1000 );
    Vec_Ptr_t * vFlops = Vec_PtrAlloc( 1000 );
    Wlc_Obj_t * pObj; int i;
    Int_Pair_t * pPair;

    if ( pPars->nLimit == ABC_INFINITY )
        return NULL;

    vMarks = Vec_BitStart( Wlc_NtkObjNumMax( p ) );

    Wlc_NtkForEachObj( p, pObj, i )
    {
        if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS )
        {
            if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd )
            {
                pPair = ABC_ALLOC( Int_Pair_t, 1 );
                pPair->first = i;
                pPair->second = Wlc_ObjRange( pObj );
                Vec_PtrPush( vAdds, pPair );
            }
        }
        else if ( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS )
        {
            if ( Wlc_ObjRange(pObj) >= pPars->nBitsMul )
            {
                pPair = ABC_ALLOC( Int_Pair_t, 1 );
                pPair->first = i;
                pPair->second = Wlc_ObjRange( pObj );
                Vec_PtrPush( vMults, pPair );
            }
        }
        else if ( pObj->Type == WLC_OBJ_MUX ) 
        {
            if ( Wlc_ObjRange(pObj) >= pPars->nBitsMux )
            {
                pPair = ABC_ALLOC( Int_Pair_t, 1 );
                pPair->first = i;
                pPair->second = Wlc_ObjRange( pObj );
                Vec_PtrPush( vMuxes, pPair );
            }
        }
        else if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) )
        {
            if ( Wlc_ObjRange(pObj) >= pPars->nBitsFlop )
            {
                pPair = ABC_ALLOC( Int_Pair_t, 1 );
                pPair->first = i;
                pPair->second = Wlc_ObjRange( pObj );
                Vec_PtrPush( vFlops, pPair );
            }
        }
    }

    Vec_PtrSort( vAdds,  (int (*)(void))IntPairPtrCompare ) ;
    Vec_PtrSort( vMults, (int (*)(void))IntPairPtrCompare ) ;
    Vec_PtrSort( vMuxes, (int (*)(void))IntPairPtrCompare ) ;
    Vec_PtrSort( vFlops, (int (*)(void))IntPairPtrCompare ) ;

    Vec_PtrForEachEntry( Int_Pair_t *, vAdds, pPair, i )
    {
        if ( i >= pPars->nLimit ) break;
        Vec_BitWriteEntry( vMarks, pPair->first, 1 ); 
    }
    if ( i && pPars->fVerbose ) Abc_Print( 1, "%%PDRA: %d-th ADD has width = %d\n", i, pPair->second );

    Vec_PtrForEachEntry( Int_Pair_t *, vMults, pPair, i )
    {
        if ( i >= pPars->nLimit ) break;
        Vec_BitWriteEntry( vMarks, pPair->first, 1 ); 
    }
    if ( i && pPars->fVerbose ) Abc_Print( 1, "%%PDRA: %d-th MUL has width = %d\n", i, pPair->second );

    Vec_PtrForEachEntry( Int_Pair_t *, vMuxes, pPair, i )
    {
        if ( i >= pPars->nLimit ) break; 
        Vec_BitWriteEntry( vMarks, pPair->first, 1 ); 
    }
    if ( i && pPars->fVerbose ) Abc_Print( 1, "%%PDRA: %d-th MUX has width = %d\n", i, pPair->second );

    Vec_PtrForEachEntry( Int_Pair_t *, vFlops, pPair, i )
    {
        if ( i >= pPars->nLimit ) break;
        Vec_BitWriteEntry( vMarks, pPair->first, 1 ); 
    }
    if ( i && pPars->fVerbose ) Abc_Print( 1, "%%PDRA: %d-th FF has width = %d\n", i, pPair->second );


    Vec_PtrForEachEntry( Int_Pair_t *, vAdds,  pPair, i ) ABC_FREE( pPair );
    Vec_PtrForEachEntry( Int_Pair_t *, vMults, pPair, i ) ABC_FREE( pPair );
    Vec_PtrForEachEntry( Int_Pair_t *, vMuxes, pPair, i ) ABC_FREE( pPair );
    Vec_PtrForEachEntry( Int_Pair_t *, vFlops, pPair, i ) ABC_FREE( pPair );
    Vec_PtrFree( vAdds );
    Vec_PtrFree( vMults );
    Vec_PtrFree( vMuxes );
    Vec_PtrFree( vFlops );

    return vMarks;
}

static void Wlc_NtkSetUnmark( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark )
{
    int Entry, i;
    Vec_Bit_t * vMarks = Wlc_NtkMarkLimit( p, pPars );

    Vec_BitForEachEntry( vMarks, Entry, i )
        Vec_BitWriteEntry( vUnmark, i, Entry^1 );

    Vec_BitFree( vMarks );
}

static Vec_Int_t * Wlc_NtkGetBlacks( Wlc_Ntk_t * p, Wlc_Par_t * pPars )
{
    Vec_Int_t * vBlacks = Vec_IntAlloc( 100 ) ;
    Wlc_Obj_t * pObj; int i, Count[4] = {0};
    Vec_Bit_t * vMarks = NULL;
    int nTotal = 0;

    vMarks = Wlc_NtkMarkLimit( p, pPars ) ; 

    Wlc_NtkForEachObj( p, pObj, i )
    {
        if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS )
        {
            if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd )
            {
                ++nTotal;
                if ( vMarks == NULL )
                    Vec_IntPushUniqueOrder( vBlacks, Wlc_ObjId(p, pObj) ), Count[0]++;
                else if ( Vec_BitEntry( vMarks, i ) )
                    Vec_IntPushUniqueOrder( vBlacks, Wlc_ObjId(p, pObj) ), Count[0]++;
            }
            continue;
        }
        if ( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS )
        {
            if ( Wlc_ObjRange(pObj) >= pPars->nBitsMul )
            {
                ++nTotal;
                if ( vMarks == NULL )
                    Vec_IntPushUniqueOrder( vBlacks, Wlc_ObjId(p, pObj) ), Count[1]++;
                else if ( Vec_BitEntry( vMarks, i ) )
                    Vec_IntPushUniqueOrder( vBlacks, Wlc_ObjId(p, pObj) ), Count[1]++;
            }
            continue;
        }
        if ( pObj->Type == WLC_OBJ_MUX )
        {
            if ( Wlc_ObjRange(pObj) >= pPars->nBitsMux )
            {
                ++nTotal;
                if ( vMarks == NULL )
                    Vec_IntPushUniqueOrder( vBlacks, Wlc_ObjId(p, pObj) ), Count[2]++;
                else if ( Vec_BitEntry( vMarks, i ) )
                    Vec_IntPushUniqueOrder( vBlacks, Wlc_ObjId(p, pObj) ), Count[2]++;
            }
            continue;
        }
        if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) )
        {
            if ( Wlc_ObjRange(pObj) >= pPars->nBitsFlop )
            {
                ++nTotal;
                if ( vMarks == NULL )
                    Vec_IntPushUniqueOrder( vBlacks, Wlc_ObjId( p, Wlc_ObjFo2Fi( p, pObj ) ) ), Count[3]++;
                else if ( Vec_BitEntry( vMarks, i ) )
                    Vec_IntPushUniqueOrder( vBlacks, Wlc_ObjId( p, Wlc_ObjFo2Fi( p, pObj ) ) ), Count[3]++;
            }
            continue;
        }
    }
    if ( vMarks )
        Vec_BitFree( vMarks );
    if ( pPars->fVerbose )
        printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away (out of %d signals).\n", Count[0], Count[1], Count[2], Count[3], nTotal );
    return vBlacks;
}

/**Function*************************************************************

  Synopsis    [Mark operators that meet the abstraction criteria.]

  Description [This procedure returns the array of objects (vLeaves) that 
  should be abstracted because of their high bit-width. It uses input array (vUnmark)
  to not abstract those objects that have been refined in the previous rounds.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/

static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose )
{
    Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) );
    Wlc_Obj_t * pObj; int i, Count[4] = {0};
    Wlc_NtkForEachObj( p, pObj, i )
    {
        if ( vUnmark && Vec_BitEntry(vUnmark, i) ) // not allow this object to be abstracted away
            continue;
        if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS )
        {
            if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd )
                Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[0]++;
            continue;
        }
        if ( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS )
        {
            if ( Wlc_ObjRange(pObj) >= pPars->nBitsMul )
                Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[1]++;
            continue;
        }
        if ( pObj->Type == WLC_OBJ_MUX )
        {
            if ( Wlc_ObjRange(pObj) >= pPars->nBitsMux )
                Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[2]++;
            continue;
        }
        if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) )
        {
            if ( Wlc_ObjRange(pObj) >= pPars->nBitsFlop )
                Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[3]++;
            continue;
        }
    }
    if ( fVerbose )
        printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Count[3] );
    return vLeaves;
}

/**Function*************************************************************

  Synopsis    [Marks nodes to be included in the abstracted network.]

  Description [Marks all objects that will be included in the abstracted model.  
  Stops at the objects (vLeaves) that are abstracted away. Returns three arrays:
  a subset of original PIs (vPisOld), a subset of pseudo-PIs (vPisNew) and the
  set of flops present as flops in the abstracted network.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
static void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
{
    int i, iFanin;
    if ( pObj->Mark )
        return;
    pObj->Mark = 1;
    if ( Vec_BitEntry(vLeaves, Wlc_ObjId(p, pObj)) )
    {
        assert( !Wlc_ObjIsPi(pObj) );
        Vec_IntPush( vPisNew, Wlc_ObjId(p, pObj) );
        return;
    }
    if ( Wlc_ObjIsCi(pObj) )
    {
        if ( Wlc_ObjIsPi(pObj) )
            Vec_IntPush( vPisOld, Wlc_ObjId(p, pObj) );
        else
            Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) );
        return;
    }
    Wlc_ObjForEachFanin( pObj, iFanin, i )
        Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vPisOld, vPisNew, vFlops );
}
static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
{
    Wlc_Obj_t * pObj;
    int i, Count = 0;
    Wlc_NtkCleanMarks( p );
    Wlc_NtkForEachCo( p, pObj, i )
        Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops );
    
/*    
    Vec_IntClear(vFlops);
    Wlc_NtkForEachCi( p, pObj, i ) {
        if ( !Wlc_ObjIsPi(pObj) ) {
            Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) );
            pObj->Mark = 1;
        }
    }
*/    

    Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
        Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops );
    Wlc_NtkForEachObj( p, pObj, i )
        Count += pObj->Mark;
//    printf( "Collected %d old PIs, %d new PIs, %d flops, and %d other objects.\n", 
//        Vec_IntSize(vPisOld), Vec_IntSize(vPisNew), Vec_IntSize(vFlops), 
//        Count - Vec_IntSize(vPisOld) - Vec_IntSize(vPisNew) - Vec_IntSize(vFlops) );
    Vec_IntSort( vPisOld, 0 );
    Vec_IntSort( vPisNew, 0 );
    Vec_IntSort( vFlops, 0 );
    Wlc_NtkCleanMarks( p );
}

/**Function*************************************************************

  Synopsis    [Derive word-level abstracted model based on the parameter values.]

  Description [Retuns the word-level abstracted network and the set of pseudo-PIs 
  (vPisNew), which were created during abstraction. If the abstraction is
  satisfiable, some of the pseudo-PIs will be un-abstracted. These pseudo-PIs
  and their MFFC cones will be listed in the array (vUnmark), which will
  force the abstraction to not stop at these pseudo-PIs in the future.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, Vec_Int_t ** pvFlops, int fVerbose )
{
    Wlc_Ntk_t * pNtkNew = NULL;
    Vec_Int_t * vPisOld = Vec_IntAlloc( 100 );
    Vec_Int_t * vPisNew = Vec_IntAlloc( 100 );
    Vec_Int_t * vFlops  = Vec_IntAlloc( 100 );
    Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars, vUnmark, fVerbose );
    Wlc_NtkAbsMarkNodes( p, vLeaves, vPisOld, vPisNew, vFlops );
    Vec_BitFree( vLeaves );
    pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops );
    Vec_IntFree( vPisOld );
    if ( pvFlops )
        *pvFlops = vFlops;
    else
        Vec_IntFree( vFlops );
    if ( pvPisNew )
        *pvPisNew = vPisNew;
    else
        Vec_IntFree( vPisNew );
    return pNtkNew;
}

/**Function*************************************************************

  Synopsis    [Find what objects need to be un-abstracted.]

  Description [Returns a subset of pseudo-PIs (vPisNew), which will be 
  prevented from being abstracted in the future rounds of abstraction.
  The AIG manager (pGia) is a bit-level view of the abstracted model.
  The counter-example (pCex) is used to find waht PPIs to refine.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
static Vec_Int_t * Wlc_NtkAbsRefinement( Wlc_Ntk_t * p, Gia_Man_t * pGia, Abc_Cex_t * pCex, Vec_Int_t * vPisNew )
{
    Vec_Int_t * vRefine = Vec_IntAlloc( 100 );
    Abc_Cex_t * pCexCare;
    Wlc_Obj_t * pObj; 
    // count the number of bit-level PPIs and map them into word-level objects they were derived from
    int f, i, b, nRealPis, nPpiBits = 0;
    Vec_Int_t * vMap = Vec_IntStartFull( pCex->nPis );
    Wlc_NtkForEachObjVec( vPisNew, p, pObj, i )
        for ( b = 0; b < Wlc_ObjRange(pObj); b++ )
            Vec_IntWriteEntry( vMap, nPpiBits++, Wlc_ObjId(p, pObj) );
    // since PPIs are ordered last, the previous bits are real PIs
    nRealPis = pCex->nPis - nPpiBits;
    // find the care-set
    pCexCare = Bmc_CexCareMinimizeAig( pGia, nRealPis, pCex, 1, 0, 0 );
    assert( pCexCare->nPis == pCex->nPis );
    // detect care PPIs
    for ( f = 0; f <= pCexCare->iFrame; f++ )
        for ( i = nRealPis; i < pCexCare->nPis; i++ )
            if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) )
                Vec_IntPushUniqueOrder( vRefine, Vec_IntEntry(vMap, i-nRealPis) );
    Abc_CexFree( pCexCare );
    Vec_IntFree( vMap );
    if ( Vec_IntSize(vRefine) == 0 )// real CEX
        Vec_IntFreeP( &vRefine );
    return vRefine;
}

/**Function*************************************************************

  Synopsis    [Mark MFFC cones of the un-abstracted objects.]

  Description [The MFFC cones of the objects in vRefine are traversed
  and all their nodes are marked in vUnmark.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
static int Wlc_NtkNodeDeref_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark )
{
    int i, Fanin, Counter = 1;
    if ( Wlc_ObjIsCi(pNode) )
        return 0;
    Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 );
    Wlc_ObjForEachFanin( pNode, Fanin, i )
    {
        Vec_IntAddToEntry( &p->vRefs, Fanin, -1 );
        if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 )
            Counter += Wlc_NtkNodeDeref_rec( p, Wlc_NtkObj(p, Fanin), vUnmark );
    }
    return Counter;
}
static int Wlc_NtkNodeRef_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode )
{
    int i, Fanin, Counter = 1;
    if ( Wlc_ObjIsCi(pNode) )
        return 0;
    Wlc_ObjForEachFanin( pNode, Fanin, i )
    {
        if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 )
            Counter += Wlc_NtkNodeRef_rec( p, Wlc_NtkObj(p, Fanin) );
        Vec_IntAddToEntry( &p->vRefs, Fanin, 1 );
    }
    return Counter;
}
static int Wlc_NtkMarkMffc( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark )
{
    int Count1, Count2;
    // if this is a flop output, compute MFFC of the corresponding flop input
    while ( Wlc_ObjIsCi(pNode) )
    {
        Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 );
        pNode = Wlc_ObjFo2Fi(p, pNode);
    }
    assert( !Wlc_ObjIsCi(pNode) );
    // dereference the node (and set the bits in vUnmark)
    Count1 = Wlc_NtkNodeDeref_rec( p, pNode, vUnmark );
    // reference it back
    Count2 = Wlc_NtkNodeRef_rec( p, pNode );
    assert( Count1 == Count2 );
    return Count1;
}
static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec_Bit_t * vUnmark )
{
    Wlc_Obj_t * pObj; int i, nNodes = 0;
    if ( Vec_IntSize(&p->vRefs) == 0 )
        Wlc_NtkSetRefs( p );
    Wlc_NtkForEachObjVec( vRefine, p, pObj, i )
        nNodes += Wlc_NtkMarkMffc( p, pObj, vUnmark );
    return nNodes;
}

static int Wlc_NtkUnmarkRefinement( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec_Bit_t * vUnmark )
{
    Wlc_Obj_t * pObj; int i, nNodes = 0;
    Wlc_NtkForEachObjVec( vRefine, p, pObj, i )
    {
        Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pObj), 1 );
        ++nNodes;
    }
    return nNodes;
}

/**Function*************************************************************

  Synopsis    [Computes the map for remapping flop IDs used in the clauses.]

  Description [Takes the original network (Wlc_Ntk_t) and the array of word-level 
  flops used in the old abstraction (vFfOld) and those used in the new abstraction
  (vFfNew). Returns the integer map, which remaps every binary flop found
  in the old abstraction into a binary flop found in the new abstraction.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Vec_Int_t * Wlc_NtkFlopsRemap( Wlc_Ntk_t * p, Vec_Int_t * vFfOld, Vec_Int_t * vFfNew )
{
    Vec_Int_t * vMap = Vec_IntAlloc( 1000 );             // the resulting map
    Vec_Int_t * vMapFfNew2Bit1 = Vec_IntAlloc( 1000 );   // first binary bit of each new word-level flop
    int i, b, iFfOld, iFfNew, iBit1New, nBits = 0;
    // map object IDs of old flops into their flop indexes
    Vec_Int_t * vMapFfObj2FfId = Vec_IntStartFull( Wlc_NtkObjNumMax(p) );
    Vec_IntForEachEntry( vFfNew, iFfNew, i )
        Vec_IntWriteEntry( vMapFfObj2FfId, iFfNew, i );
    // map each new flop index into its first bit
    Vec_IntForEachEntry( vFfNew, iFfNew, i )
    {
        Wlc_Obj_t * pObj = Wlc_NtkObj( p, iFfNew );
        int nRange = Wlc_ObjRange( pObj );
        Vec_IntPush( vMapFfNew2Bit1, nBits );
        nBits += nRange;
    }
    assert( Vec_IntSize(vMapFfNew2Bit1) == Vec_IntSize(vFfNew) );
    // remap old binary flops into new binary flops
    Vec_IntForEachEntry( vFfOld, iFfOld, i )
    {
        Wlc_Obj_t * pObj = Wlc_NtkObj( p, iFfOld );
        int nRange = Wlc_ObjRange( pObj );
        iFfNew = Vec_IntEntry( vMapFfObj2FfId, iFfOld );
        assert( iFfNew >= 0 ); // every old flop should be present in the new abstraction
        // find the first bit of this new flop
        iBit1New = Vec_IntEntry( vMapFfNew2Bit1, iFfNew );
        for ( b = 0; b < nRange; b++ )
            Vec_IntPush( vMap, iBit1New + b );
    }
    Vec_IntFree( vMapFfNew2Bit1 );
    Vec_IntFree( vMapFfObj2FfId );
    return vMap;
}

/**Function*************************************************************

  Synopsis    [Performs PDR with word-level abstraction.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Vec_Int_t * Wla_ManCollectNodes( Wla_Man_t * pWla, int fBlack )
{
    Vec_Int_t * vNodes = NULL;
    int i, Entry;

    assert( pWla->vSignals );

    vNodes = Vec_IntAlloc( 100 );
    Vec_IntForEachEntry( pWla->vSignals, Entry, i )
    {
        if ( !fBlack && Vec_BitEntry(pWla->vUnmark, Entry) )
            Vec_IntPush( vNodes, Entry );
        
        if ( fBlack && !Vec_BitEntry(pWla->vUnmark, Entry) )
            Vec_IntPush( vNodes, Entry );
    }

    return vNodes;
}

int Wla_ManShrinkAbs( Wla_Man_t * pWla, int nFrames, int RunId )
{
    int i, Entry;
    int RetValue = 0;

    Vec_Int_t * vWhites = Wla_ManCollectNodes( pWla, 0 );
    Vec_Int_t * vBlacks = Wla_ManCollectNodes( pWla, 1 );
    Vec_Bit_t * vCoreMarks = Wlc_NtkProofReduce( pWla->p, pWla->pPars, nFrames, vWhites, vBlacks, RunId );

    if ( vCoreMarks == NULL )
    {
        Vec_IntFree( vWhites );
        Vec_IntFree( vBlacks );
        return -1;
    }

    RetValue = Vec_IntSize( vWhites ) != Vec_BitCount( vCoreMarks );

    Vec_IntForEachEntry( vWhites, Entry, i )
        if ( !Vec_BitEntry( vCoreMarks, i ) )
            Vec_BitWriteEntry( pWla->vUnmark, Entry, 0 );

    Vec_IntFree( vWhites );
    Vec_IntFree( vBlacks );
    Vec_BitFree( vCoreMarks );

    return RetValue;
}

Wlc_Ntk_t * Wla_ManCreateAbs( Wla_Man_t * pWla )
{
    Wlc_Ntk_t * pAbs;

    // get abstracted GIA and the set of pseudo-PIs (vBlacks)
    if ( pWla->vBlacks == NULL )
    {
        pWla->vBlacks = Wlc_NtkGetBlacks( pWla->p, pWla->pPars );
        pWla->vSignals = Vec_IntDup( pWla->vBlacks );
    }
    else
    {
        Wlc_NtkUpdateBlacks( pWla->p, pWla->pPars, &pWla->vBlacks, pWla->vUnmark, pWla->vSignals );
    }
    pAbs = Wlc_NtkAbs2( pWla->p, pWla->vBlacks, NULL );

    return pAbs;
}

Aig_Man_t * Wla_ManBitBlast( Wla_Man_t * pWla, Wlc_Ntk_t * pAbs )
{
    int nDcFlops;
    Gia_Man_t * pTemp;
    Aig_Man_t * pAig;

    pWla->pGia = Wlc_NtkBitBlast( pAbs, NULL );

    // if the abstraction has flops with DC-init state,
    // new PIs were introduced by bit-blasting at the end of the PI list
    // here we move these variables to be *before* PPIs, because
    // PPIs are supposed to be at the end of the PI list for refinement
    nDcFlops = Wlc_NtkDcFlopNum(pAbs);
    if ( nDcFlops > 0 ) // DC-init flops are present
    {
        pWla->pGia = Gia_ManPermuteInputs( pTemp = pWla->pGia, Wlc_NtkCountObjBits(pWla->p, pWla->vBlacks), nDcFlops );
        Gia_ManStop( pTemp );
    }
    // if the word-level outputs have to be XORs, this is a place to do it
    if ( pWla->pPars->fXorOutput )
    {
        pWla->pGia = Gia_ManTransformMiter2( pTemp = pWla->pGia );
        Gia_ManStop( pTemp );
    }
    if ( pWla->pPars->fVerbose )
    {
        printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(pWla->vBlacks) ); 
        Gia_ManPrintStats( pWla->pGia, NULL );
    }

    // try to prove abstracted GIA by converting it to AIG and calling PDR
    pAig = Gia_ManToAigSimple( pWla->pGia );

    return pAig;
}

int Wla_ManCheckCombUnsat( Wla_Man_t * pWla, Aig_Man_t * pAig )
{
    Pdr_Man_t * pPdr;
    Pdr_Par_t * pPdrPars = (Pdr_Par_t *)pWla->pPdrPars;
    abctime clk;
    int RetValue = -1;

    if ( Aig_ManAndNum( pAig ) <= 20000 )
    { 
        Aig_Man_t * pAigScorr;
        Ssw_Pars_t ScorrPars, * pScorrPars = &ScorrPars;
        int nAnds;

        clk = Abc_Clock();

        Ssw_ManSetDefaultParams( pScorrPars );
        pScorrPars->fStopWhenGone = 1;
        pScorrPars->nFramesK = 1;
        pAigScorr = Ssw_SignalCorrespondence( pAig, pScorrPars );
        assert ( pAigScorr );
        nAnds = Aig_ManAndNum( pAigScorr); 
        Aig_ManStop( pAigScorr );

        if ( nAnds == 0 )
        {
            if ( pWla->pPars->fVerbose )
                Abc_PrintTime( 1, "SCORR proved UNSAT. Time", Abc_Clock() - clk );
            return 1;
        }
        else if ( pWla->pPars->fVerbose )
        {
            Abc_Print( 1, "SCORR failed with %d ANDs. ", nAnds);
            Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
        }
    }

    clk = Abc_Clock();

    pPdrPars->fVerbose = 0;
    pPdr = Pdr_ManStart( pAig, pPdrPars, NULL );
    RetValue = IPdr_ManCheckCombUnsat( pPdr );
    Pdr_ManStop( pPdr );
    pPdrPars->fVerbose = pWla->pPars->fPdrVerbose;

    pWla->tPdr += Abc_Clock() - clk;

    return RetValue;
}

int Wla_ManSolveInt( Wla_Man_t * pWla, Aig_Man_t * pAig )
{
    abctime clk;
    Pdr_Man_t * pPdr;
    Pdr_Par_t * pPdrPars = (Pdr_Par_t *)pWla->pPdrPars;
    Abc_Cex_t * pBmcCex = NULL;
    Abc_Cex_t * pCexReal = NULL;
    int RetValue = -1;
    int RunId = Wla_GetGlobalRunId();

    if ( pWla->vClauses && pWla->pPars->fCheckCombUnsat )
    {
        clk = Abc_Clock();

        RetValue = Wla_ManCheckCombUnsat( pWla, pAig );
        if ( RetValue == 1 )
        {
            if ( pWla->pPars->fVerbose )
                Abc_PrintTime( 1,  "ABS becomes combinationally UNSAT. Time", Abc_Clock() - clk );
            return 1;
        }

        if ( pWla->pPars->fVerbose )
            Abc_PrintTime( 1, "Check comb. unsat failed. Time", Abc_Clock() - clk );
    }

    if ( pWla->pPars->fUseBmc3 )
    {
        pPdrPars->RunId = RunId;
        pPdrPars->pFuncStop = Wla_CallBackToStop;

        Wla_ManConcurrentBmc3( pWla, Aig_ManDupSimple(pAig), &pBmcCex );
    }

    clk = Abc_Clock();
    pPdr = Pdr_ManStart( pAig, pPdrPars, NULL );
    if ( pWla->vClauses ) {
        assert( Vec_VecSize( pWla->vClauses) >= 2 ); 
        
        if ( pWla->fNewAbs )
            IPdr_ManRebuildClauses( pPdr, pWla->pPars->fShrinkScratch ? NULL : pWla->vClauses );
        else
            IPdr_ManRestoreClauses( pPdr, pWla->vClauses, NULL );

        pWla->fNewAbs = 0;
    }

    RetValue = IPdr_ManSolveInt( pPdr, pWla->pPars->fCheckClauses, pWla->pPars->fPushClauses );
    pPdr->tTotal += Abc_Clock() - clk;
    pWla->tPdr += pPdr->tTotal;
    if ( pWla->pPars->fLoadTrace)
        pWla->vClauses = IPdr_ManSaveClauses( pPdr, 0 );
    Pdr_ManStop( pPdr );


    if ( pWla->pPars->fUseBmc3 )
        Wla_ManJoinThread( pWla, RunId );

    if ( pBmcCex )
    {
        pWla->pCex = pBmcCex ;
    }
    else
    {
        pWla->pCex = pAig->pSeqModel;
        pAig->pSeqModel = NULL;
    }

    // consider outcomes
    if ( pWla->pCex == NULL ) 
    {
        assert( RetValue ); // proved or undecided
        return RetValue;
    }

    // verify CEX
    pCexReal = Wlc_NtkCexIsReal( pWla->p, pWla->pCex );
    if ( pCexReal )
    {
        Abc_CexFree( pWla->pCex );
        pWla->pCex = pCexReal; 
        return 0;
    }

    return -1;
}

void Wla_ManRefine( Wla_Man_t * pWla )
{
    abctime clk;
    int nNodes;
    Vec_Int_t * vRefine = NULL;

    if ( pWla->fNewAbs )
    {
        if ( pWla->pCex )
            Abc_CexFree( pWla->pCex );
        pWla->pCex = NULL;
        Gia_ManStop( pWla->pGia ); pWla->pGia = NULL;
        return;
    }

    // perform refinement
    if ( pWla->pPars->fHybrid || !pWla->pPars->fProofRefine )
    {
        clk = Abc_Clock();
        vRefine = Wlc_NtkAbsRefinement( pWla->p, pWla->pGia, pWla->pCex, pWla->vBlacks );
        pWla->tCbr += Abc_Clock() - clk;
    }
    else // proof-based only
    {
        vRefine = Vec_IntDup( pWla->vBlacks );
    }
    if ( pWla->pPars->fProofRefine ) 
    {
        clk = Abc_Clock();
        Wlc_NtkProofRefine( pWla->p, pWla->pPars, pWla->pCex, pWla->vBlacks, &vRefine );
        pWla->tPbr += Abc_Clock() - clk;
    }

    if ( pWla->vClauses && pWla->pPars->fVerbose )
    {
        int i;
        Vec_Ptr_t * vVec; 
        Vec_VecForEachLevel( pWla->vClauses, vVec, i )
            pWla->nTotalCla += Vec_PtrSize( vVec ); 
    }

    // update the set of objects to be un-abstracted
    clk = Abc_Clock();
    if ( pWla->pPars->fMFFC )
    {
        nNodes = Wlc_NtkRemoveFromAbstraction( pWla->p, vRefine, pWla->vUnmark );
        if ( pWla->pPars->fVerbose )
            printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pWla->pCex->iFrame, Vec_IntSize(vRefine), nNodes );
    }
    else
    {
        nNodes = Wlc_NtkUnmarkRefinement( pWla->p, vRefine, pWla->vUnmark );
        if ( pWla->pPars->fVerbose )
            printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs.\n", pWla->pCex->iFrame, Vec_IntSize(vRefine) );

    }
    /*
    if ( pWla->pPars->fVerbose ) 
    {
        Wlc_NtkAbsAnalyzeRefine( pWla->p, pWla->vBlacks, pWla->vUnmark, &pWla->nDisj, &pWla->nNDisj );
        Abc_Print( 1, "Refine analysis (total): %d disjoint PPIs and %d non-disjoint PPIs\n", pWla->nDisj, pWla->nNDisj );
    }
    */
    pWla->tCbr += Abc_Clock() - clk;
    
    // Experimental
    /*
    if ( pWla->pCex->iFrame > 0 )
    {
        Vec_Int_t * vWhites = Wla_ManCollectWhites( pWla );
        Vec_Bit_t * vCore = Wlc_NtkProofReduce( pWla->p, pWla->pPars, pWla->pCex->iFrame, vWhites );
        Vec_IntFree( vWhites );
        Vec_BitFree( vCore );
    }
    */

    pWla->iCexFrame = pWla->pCex->iFrame;

    Vec_IntFree( vRefine );
    Gia_ManStop( pWla->pGia ); pWla->pGia = NULL;
    Abc_CexFree( pWla->pCex ); pWla->pCex = NULL;
}

Wla_Man_t * Wla_ManStart( Wlc_Ntk_t * pNtk, Wlc_Par_t * pPars )
{
    Wla_Man_t * p = ABC_CALLOC( Wla_Man_t, 1 );
    Pdr_Par_t * pPdrPars;
    p->p = pNtk;
    p->pPars = pPars;
    p->vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(pNtk) );

    pPdrPars = ABC_CALLOC( Pdr_Par_t, 1 );
    Pdr_ManSetDefaultParams( pPdrPars );
    pPdrPars->fVerbose   = pPars->fPdrVerbose;
    pPdrPars->fVeryVerbose = 0;
    pPdrPars->pFuncStop  = pPars->pFuncStop;
    pPdrPars->RunId      = pPars->RunId;
    if ( pPars->fPdra )
    {
        pPdrPars->fUseAbs    = 1;   // use 'pdr -t'  (on-the-fly abstraction)
        pPdrPars->fCtgs      = 1;   // use 'pdr -nc' (improved generalization)
        pPdrPars->fSkipDown  = 0;   // use 'pdr -nc' (improved generalization)
        pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this
    } 
    p->pPdrPars = (void *)pPdrPars;

    p->iCexFrame = 0;
    p->fNewAbs   = 0;

    p->nIters    = 1;
    p->nTotalCla = 0;
    p->nDisj     = 0;
    p->nNDisj    = 0;

    return p;
}

void Wla_ManStop( Wla_Man_t * p )
{
    if ( p->vBlacks )   Vec_IntFree( p->vBlacks );
    if ( p->vSignals )  Vec_IntFree( p->vSignals );
    if ( p->pGia )      Gia_ManStop( p->pGia );
    if ( p->pCex )      Abc_CexFree( p->pCex );
    Vec_BitFree( p->vUnmark );
    ABC_FREE( p->pPdrPars );
    ABC_FREE( p );
}

int Wla_ManSolve( Wla_Man_t * pWla, Wlc_Par_t * pPars )
{
    abctime clk = Abc_Clock();
    abctime tTotal;
    Wlc_Ntk_t * pAbs = NULL;
    Aig_Man_t * pAig = NULL;

    int RetValue = -1;

    // perform refinement iterations
    for ( pWla->nIters = 1; pWla->nIters < pPars->nIterMax; ++pWla->nIters )
    {
        if ( pPars->fVerbose )
            printf( "\nIteration %d:\n", pWla->nIters );

        pAbs = Wla_ManCreateAbs( pWla );

        pAig = Wla_ManBitBlast( pWla, pAbs );
        Wlc_NtkFree( pAbs );

        RetValue = Wla_ManSolveInt( pWla, pAig );
        Aig_ManStop( pAig );

        if ( RetValue != -1 || (pPars->pFuncStop && pPars->pFuncStop( pPars->RunId)) )
            break;

        Wla_ManRefine( pWla );
    }

    // report the result
    if ( pPars->fVerbose )
        printf( "\n" );
    printf( "Abstraction " );
    if ( RetValue == 0 )
        printf( "resulted in a real CEX" );
    else if ( RetValue == 1 )
        printf( "is successfully proved" );
    else 
        printf( "timed out" );
    printf( " after %d iterations. ", pWla->nIters );
    tTotal = Abc_Clock() - clk;
    Abc_PrintTime( 1, "Time", tTotal );

    if ( pPars->fVerbose )
        Abc_Print( 1, "PDRA reused %d clauses.\n", pWla->nTotalCla );
    if ( pPars->fVerbose )
    {
        ABC_PRTP( "PDR          ", pWla->tPdr,                          tTotal );
        ABC_PRTP( "CEX Refine   ", pWla->tCbr,                          tTotal );
        ABC_PRTP( "Proof Refine ", pWla->tPbr,                          tTotal );
        ABC_PRTP( "Misc.        ", tTotal - pWla->tPdr - pWla->tCbr - pWla->tPbr,   tTotal );
        ABC_PRTP( "Total        ", tTotal,                              tTotal );
    }

    return RetValue;
} 

int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars )
{
    Wla_Man_t * pWla = NULL;
    
    int RetValue = -1;

    pWla = Wla_ManStart( p, pPars );

    RetValue = Wla_ManSolve( pWla, pPars );

    Wla_ManStop( pWla );
    
    return RetValue;
}

/**Function*************************************************************

  Synopsis    [Performs abstraction.]

  Description [Derives initial abstraction based on user-specified
  parameter values, which tell what is the smallest bit-width of a
  primitive that is being abstracted away.  Currently only add/sub,
  mul/div, mux, and flop are supported with individual parameters.
  The second step is to refine the initial abstraction until the
  point when the property is proved.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars )
{
    abctime clk = Abc_Clock();
    Vec_Int_t * vBlacks = NULL;
    int nIters, nNodes, nDcFlops, RetValue = -1;
    // start the bitmap to mark objects that cannot be abstracted because of refinement
    // currently, this bitmap is empty because abstraction begins without refinement
    Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) );
    // set up parameters to run PDR
    Pdr_Par_t PdrPars, * pPdrPars = &PdrPars;
    Pdr_ManSetDefaultParams( pPdrPars );
    //pPdrPars->fUseAbs    = 1;   // use 'pdr -t'  (on-the-fly abstraction)
    //pPdrPars->fCtgs      = 1;   // use 'pdr -nc' (improved generalization)
    //pPdrPars->fSkipDown  = 0;   // use 'pdr -nc' (improved generalization)
    //pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this
    pPdrPars->fVerbose   = pPars->fPdrVerbose;
    pPdrPars->fVeryVerbose = 0;
    // perform refinement iterations
    for ( nIters = 1; nIters < pPars->nIterMax; nIters++ )
    {
        Aig_Man_t * pAig;
        Abc_Cex_t * pCex;
        Vec_Int_t * vPisNew, * vRefine;  
        Gia_Man_t * pGia, * pTemp;
        Wlc_Ntk_t * pAbs;

        if ( pPars->fVerbose )
            printf( "\nIteration %d:\n", nIters );

        // get abstracted GIA and the set of pseudo-PIs (vPisNew)
        if ( pPars->fAbs2 )
        {
            if ( vBlacks == NULL )
                vBlacks = Wlc_NtkGetBlacks( p, pPars );
            else
                Wlc_NtkUpdateBlacks( p, pPars, &vBlacks, vUnmark, NULL );
            pAbs = Wlc_NtkAbs2( p, vBlacks, NULL );
            vPisNew = Vec_IntDup( vBlacks );
        }
        else
        {
            if ( nIters == 1 && pPars->nLimit < ABC_INFINITY )
                Wlc_NtkSetUnmark( p, pPars, vUnmark );

            pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, NULL, pPars->fVerbose );
        }
        pGia = Wlc_NtkBitBlast( pAbs, NULL );

        // if the abstraction has flops with DC-init state,
        // new PIs were introduced by bit-blasting at the end of the PI list
        // here we move these variables to be *before* PPIs, because
        // PPIs are supposed to be at the end of the PI list for refinement
        nDcFlops = Wlc_NtkDcFlopNum(pAbs);
        if ( nDcFlops > 0 ) // DC-init flops are present
        {
            pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops );
            Gia_ManStop( pTemp );
        }
        // if the word-level outputs have to be XORs, this is a place to do it
        if ( pPars->fXorOutput )
        {
            pGia = Gia_ManTransformMiter2( pTemp = pGia );
            Gia_ManStop( pTemp );
        }
        if ( pPars->fVerbose )
        {
            printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) ); 
            Gia_ManPrintStats( pGia, NULL );
        }
        Wlc_NtkFree( pAbs );

        // try to prove abstracted GIA by converting it to AIG and calling PDR
        pAig = Gia_ManToAigSimple( pGia );
        RetValue = Pdr_ManSolve( pAig, pPdrPars );
        pCex = pAig->pSeqModel; pAig->pSeqModel = NULL;
        Aig_ManStop( pAig );

        // consider outcomes
        if ( pCex == NULL ) 
        {
            assert( RetValue ); // proved or undecided
            Gia_ManStop( pGia );
            Vec_IntFree( vPisNew );
            break;
        }

        // perform refinement
        vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew );
        Gia_ManStop( pGia );
        Vec_IntFree( vPisNew );
        if ( vRefine == NULL ) // real CEX
        {
            Abc_CexFree( pCex ); // return CEX in the future
            break;
        }

        // update the set of objects to be un-abstracted
        nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark );
        if ( pPars->fVerbose )
            printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes );
        Vec_IntFree( vRefine );
        Abc_CexFree( pCex );
    }
    Vec_IntFree( vBlacks );
    Vec_BitFree( vUnmark );
    // report the result
    if ( pPars->fVerbose )
        printf( "\n" );
    printf( "Abstraction " );
    if ( RetValue == 0 )
        printf( "resulted in a real CEX" );
    else if ( RetValue == 1 )
        printf( "is successfully proved" );
    else 
        printf( "timed out" );
    printf( " after %d iterations. ", nIters );
    Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
    return RetValue;
}

////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


ABC_NAMESPACE_IMPL_END

